From 5d5119631bbc5997ef828a7908af9f1b7c603d43 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 27 May 2008 07:22:27 +0200 Subject: [PATCH 01/12] first outline regarding the wiring of nodes within the builder --- src/proc/engine/nodefactory.cpp | 41 ++++++++++++ src/proc/engine/nodefactory.hpp | 70 +++++++++++++++++++++ src/proc/engine/procnode.cpp | 8 ++- src/proc/engine/procnode.hpp | 35 +++++++++-- src/proc/engine/trafo.hpp | 16 ++++- src/proc/mobject/builder/mould.hpp | 22 ++++--- src/proc/mobject/builder/operationpoint.hpp | 23 ++++++- src/proc/mobject/builder/toolfactory.hpp | 1 + src/proc/mobject/session/mobjectfactory.hpp | 17 +++-- wiki/renderengine.html | 35 ++++++++--- 10 files changed, 230 insertions(+), 38 deletions(-) create mode 100644 src/proc/engine/nodefactory.cpp create mode 100644 src/proc/engine/nodefactory.hpp diff --git a/src/proc/engine/nodefactory.cpp b/src/proc/engine/nodefactory.cpp new file mode 100644 index 000000000..d439232f3 --- /dev/null +++ b/src/proc/engine/nodefactory.cpp @@ -0,0 +1,41 @@ +/* + NodeFactory - Interface for creating processing nodes of variouos kinds + + Copyright (C) Lumiera.org + 2008, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + + +#include "proc/engine/nodefactory.hpp" +#include "proc/mobject/session/effect.hpp" + +namespace engine { + + using mobject::Placement; + using mobject::session::Effect; + + + /** create a processing node able to render an effect */ + PTrafo + NodeFactory::operator() (Placement const&) + { + UNIMPLEMENTED ("create proc node for Effect/Plugin"); + } + + +} // namespace engine diff --git a/src/proc/engine/nodefactory.hpp b/src/proc/engine/nodefactory.hpp new file mode 100644 index 000000000..8dbcc5f0c --- /dev/null +++ b/src/proc/engine/nodefactory.hpp @@ -0,0 +1,70 @@ +/* + NODEFACTORY.hpp - Interface for creating processing nodes of variouos kinds + + Copyright (C) Lumiera.org + 2008, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +#ifndef ENGINE_NODEFACTORY_H +#define ENGINE_NODEFACTORY_H + +#include "proc/engine/procnode.hpp" +#include "proc/mobject/placement.hpp" + + + +namespace mobject { + namespace session { + + class Clip; + class Effect; + typedef Placement PEffect; + // TODO: class Transition; + + } // namespace mobject::session + +} // namespace mobject + + +namespace engine { + + using std::vector; + + class Trafo; + typedef Trafo* PTrafo; ///< @todo handle ProcNode by pointer or by shared-ptr?? + + + /** + * Create processing nodes based on given objects of the high-level model. + */ + class NodeFactory + { + /** custom deleter func allowing a smart-ptr + * to take ownership of processing nodes + */ + static void deleterFunc (ProcNode* pno) { delete pno; } + + public: + + PTrafo operator() (mobject::session::PEffect const&); + + }; + +} // namespace engine +#endif diff --git a/src/proc/engine/procnode.cpp b/src/proc/engine/procnode.cpp index 48e33c498..984c4dece 100644 --- a/src/proc/engine/procnode.cpp +++ b/src/proc/engine/procnode.cpp @@ -22,12 +22,14 @@ #include "proc/engine/procnode.hpp" +#include "proc/engine/nodefactory.hpp" -namespace engine - { +namespace engine { - /** */ + /** Storage for the (single, static) ProcNode factory object. + */ + NodeFactory ProcNode::create; } // namespace engine diff --git a/src/proc/engine/procnode.hpp b/src/proc/engine/procnode.hpp index ae210f96b..e2a4c89b9 100644 --- a/src/proc/engine/procnode.hpp +++ b/src/proc/engine/procnode.hpp @@ -29,12 +29,16 @@ #include "proc/mobject/parameter.hpp" -using std::vector; +namespace engine { -namespace engine - { + using std::vector; + + class ProcNode; + class NodeFactory; + + typedef ProcNode* PNode; ///< @todo handle ProcNode by pointer or by shared-ptr?? /** @@ -42,16 +46,37 @@ namespace engine */ class ProcNode { - protected: typedef mobject::Parameter Param; /** The predecessor in a processing pipeline. * I.e. a source to get data to be processed */ - ProcNode * datasrc; + PNode datasrc; vector params; + protected: + ProcNode(); + virtual ~ProcNode() {}; + + friend class NodeFactory; + + + /** do the actual calculations. + * @internal dispatch to implementation. + * Client code should use #render() + * @todo obviously we need a parameter!!! + */ + virtual void process() = 0; + + public: + static NodeFactory create; + + /** render and pull output from this node. + * @todo define the parameter!!! + */ + void render() { this->process(); } + }; } // namespace engine diff --git a/src/proc/engine/trafo.hpp b/src/proc/engine/trafo.hpp index 8d2155661..d1b6ba3cb 100644 --- a/src/proc/engine/trafo.hpp +++ b/src/proc/engine/trafo.hpp @@ -42,9 +42,23 @@ namespace engine */ class Trafo : public ProcNode { - /////////// + protected: + Trafo() : ProcNode() { }; + + friend class NodeFactory; + + + + /** do the actual calculations. + * @internal dispatch to implementation. + * Client code should use #render() + * @todo obviously we need a parameter!!! + */ + virtual void process() = 0; }; + typedef Trafo* PTrafo; ///< @todo handle ProcNode by pointer or by shared-ptr?? + } // namespace engine diff --git a/src/proc/mobject/builder/mould.hpp b/src/proc/mobject/builder/mould.hpp index 6c714157a..be29f2b21 100644 --- a/src/proc/mobject/builder/mould.hpp +++ b/src/proc/mobject/builder/mould.hpp @@ -39,19 +39,21 @@ namespace mobject { /** - * Interface: a holder tool used by the builder to - * wire up a specific building situation and then to - * apply/execute a single building step. Mould is the - * passive part, while usually the ProcPatt is the active - * counterpart. By means of the Mould interface, the specifics - * of a build situation are abstracted away, thus allowing the - * processing pattern to be defined as working on symbolic - * locations. The most common location is "current", denoting - * the render node just being built. + * Interface: a workbench-like tool used by the builder + * for wiring up a specific building situation, followed by + * the application/execution of a single building step. Mould is + * conceived as the passive part, while usually the ProcPatt plays + * the role of the active counterpart. By means of the Mould interface, + * the specifics of a build situation are abstracted away, thus allowing + * the processing pattern to be defined as working on symbolic locations. + * Most commonly this is "current", denoting the render node just being built. *
  • PipeMould supports attaching an effect to a pipe
  • *
  • combining pipes via a transition is done by a CombiningMould
  • *
  • a SourceChainMould allows to start out from a source reader and build a clip
  • - *
  • wiring general connections is supported by the WiringMould
  • + *
  • wiring general connections is supported by the WiringMould
  • + *
+ * @see ToolFactory + * @see NodeCreatorTool */ class Mould { diff --git a/src/proc/mobject/builder/operationpoint.hpp b/src/proc/mobject/builder/operationpoint.hpp index d48e9ecf6..daa0f18d6 100644 --- a/src/proc/mobject/builder/operationpoint.hpp +++ b/src/proc/mobject/builder/operationpoint.hpp @@ -24,12 +24,18 @@ #ifndef MOBJECT_BUILDER_OPERATIONPOINT_H #define MOBJECT_BUILDER_OPERATIONPOINT_H +#include "proc/engine/procnode.hpp" +#include "common/query.hpp" +#include +#include namespace mobject { namespace builder { + using std::vector; + using std::string; /** * A point in the render node network under construction. @@ -40,8 +46,23 @@ namespace mobject { */ class OperationPoint { - public: + typedef engine::PNode PNode; + vector refPoint_; + const string streamID_; + + public: + /** create node(s) corresponding to the given Processor-Asset + * and wire them as a successor to this OperationPoint; then + * move this point to point at the resulting new exit node(s) + */ + void attach (asset::PProc const&); + + /** connect the output this OperationPoint referes such as to + * connect or combine with the input of the already existing + * nodes accessible via the target OperationPoint. + */ + void join (OperationPoint& target); }; diff --git a/src/proc/mobject/builder/toolfactory.hpp b/src/proc/mobject/builder/toolfactory.hpp index 5d30c9eea..ecb9f7949 100644 --- a/src/proc/mobject/builder/toolfactory.hpp +++ b/src/proc/mobject/builder/toolfactory.hpp @@ -25,6 +25,7 @@ #define MOBJECT_BUILDER_TOOLFACTORY_H #include "proc/mobject/builder/buildertool.hpp" +#include "proc/mobject/builder/mould.hpp" #include "proc/asset/pipe.hpp" #include "proc/mobject/session/clip.hpp" #include "proc/mobject/builder/wiringrequest.hpp" diff --git a/src/proc/mobject/session/mobjectfactory.hpp b/src/proc/mobject/session/mobjectfactory.hpp index 427385194..e1a7a5695 100644 --- a/src/proc/mobject/session/mobjectfactory.hpp +++ b/src/proc/mobject/session/mobjectfactory.hpp @@ -28,8 +28,8 @@ -namespace asset - { +namespace asset { + class Clip; class Media; class Track; @@ -37,10 +37,9 @@ namespace asset } -namespace mobject - { - namespace session - { +namespace mobject { + namespace session { + class Clip; class Track; class Effect; @@ -57,10 +56,10 @@ namespace mobject public: - Placement operator() (const asset::Clip&, const asset::Media&); - Placement operator() (const asset::Clip&, vector); + Placement operator() (asset::Clip const&, asset::Media const&); + Placement operator() (asset::Clip const&, vector); Placement operator() (PTrackAsset&); - Placement operator() (const asset::Effect&); + Placement operator() (asset::Effect const&); }; diff --git a/wiki/renderengine.html b/wiki/renderengine.html index c55d698a2..44b635e79 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -773,13 +773,14 @@ As the builder has to create a render node network implementing most of the feat !!pattern of operation The working pattern of this builder mechanics can be described as triggering, enqueuing, priorizing, recursing and exhausting. Without the priorizing part, it would be a depth-first call graph without any context state, forcing us to have all cross reference information available at every node or element to be treated. We prefer to avoid this overhead by ordering the operations into several phases and within these phases into correlated entities with the help of a ''weighting function'' and scheduling with a ''priority queue'' -
+
The [[Builder]] uses different kinds of tools for creating a network of render nodes from a given high-level model. When breaking down this (necessarily complex) process into small manageable chunks, we arrive at [[elementary building situations|BuilderPrimitives]]. For each of these there is a specialized tool. We denote these tools as "moulds" because they are a rather passive holder for the objects to be attached and wired up. They are shaped according to the basic form the connections have to follow for each of these basic situations:
 * attaching an effect to a pipe
 * combining pipes via a transition
 * starting out a pipe from a source reader
 * general connections from the exit node of a pipe to the port of another pipe
-In all those cases, the active part is provided by [[processing patterns|ProcPatt]] &mdash; sort of micro programs executed within the context of a given mould: the processing pattern defines the steps to take (in the standard/basic case this is just "attach"), while the mould holds and provides the location where these steps will operate.
+In all those cases, the active part is provided by [[processing patterns|ProcPatt]] &mdash; sort of micro programs executed within the context of a given mould: the processing pattern defines the steps to take (in the standard/basic case this is just "attach"), while the mould holds and provides the location where these steps will operate. Actually, this location is represented as a OperationPoint, provided by the mould and abstracting the details of making multi-channel connections. +
While assembling and building up the render engines node network, a small number of primitive building situations is encountered repeatedly. The BuilderToolKit provides a "[[mould|BuilderMould]]" for each of these situations, typically involving parametrisation and the application of a [[processing pattern|ProcPatt]].
@@ -852,13 +853,9 @@ While building, the application of such a visiting tool (especially the [[NodeCr
 
 
-
+
Besides the primary working tool within the builder (namely the [[Node Creator Tool|PlanningNodeCreatorTool]]), on a lower level, we encounter several [[elementary building situations|BuilderPrimitives]] &mdash; and for each of these elementary situations we can retrieve a suitable "fitting tool" or [[mould|BuilderMould]]. The palette of these moulds is called the ''tool kit'' of the builder. It is subject to configuration by rules.
 
-!! {{red{open questions}}}
-* how to address these moulds
-* how to type them
-* how to parametrize them
 
 !!addressing a mould
 All mould instances are owned and managed by the [[tool factory|BuilderToolFactory]], and can be referred to by their type ({{{PipeMould}}}, {{{CombiningMould}}}, {{{SourceChainMould}}}, {{{WiringMould}}}) and a concrete object instance (of suitable type). The returned mould (instance) acts as a handle to stick together the given object instance (from the high-level model) with the corresponding point in the low-level node network under construction. As consequence of this approach, the tool factory instance holds a snapshot of the current building state, including all the active spots in the build process. As the latter is driven by objects from the high-level model appearing (in a sensible order &rarr; see BuilderMechanics) within the NodeCreatorTool, new moulds will be created and fitted as necessary, and existing moulds will be exhausted when finished, until the render node network is complete.
@@ -869,7 +866,10 @@ As each mould kind is different, it has a {{{prepare(...)}}} function with suita
 !!sequence of operations
 When {{{operate()}}} doesn't throw, the result is a list of //successor moulds// &mdash; you shouldn't use the original mould after triggering its operation, because it may have been retracted as a result and reused for another purpose by the tool factory. It is not necessary to store these resulting moulds either (as they can be retrieved as described above), but they can be used right away for the next building step if applicable. In the state they are returned from a successful building step (mould operation = execution of a contained [[processing pattern|ProcPatt]]), they are usually already holding a reference to the part of the network just created and need to be configured only with the next high-level object (effect, placement, pipe, processing pattern or similar, depending on the concrete situation) in order to carry out the next step.
 
-&rarr;see also: BuilderPrimitives for the elementary working situations corresponding to these fitting tools
+!!single connection step
+at the lowest level within the builder there is the step of building a //connection.// This step is executed by the processing pattern with the help of the mould. Actually, making such a connection is more complicated, because in the standard case it will connect N media streams simultaneously (N=2 for stereo sound or 3D video, N=6 for 5.1 Surround, N=9 for 2nd order Ambisonics). These details are encapsulated within the OperationPoint, which is provides by the mould and exhibits a common interface for the processing pattern to express the connecting operation.
+
+&rarr;see also: BuilderPrimitives for the elementary working situations corresponding to each of these [[builder moulds|BuilderMould]]
 
@@ -1831,6 +1831,14 @@ But because I know the opinions on this topc are varying (users tend to be delig My proposed aproach is to treat OpenGL as a separate video raw data type, requiring separete and specialized [[Processing Nodes|ProcNode]] for all calculations. Thus the Builder could connect OpenGL nodes if it is possible to cover the whole render path for preview and fall back to the normal ~ProcNodes for all relevant renders
+
+
A low-level abstraction within the [[Builder]] &mdash; it serves to encapsulate the details of making multi-channel connections between the render nodes: In some cases, a node can handle N channels internally, while in other cases we need to replicate the node N times and wire each channel individually.
+
+The operation point is provided by the current BuilderMould and used by the [[processing pattern|ProcPatt]] executing within this mould and conducting the current build step. The operation point's interface allows //to abstract//&nbsp; these details, as well as to //gain additional control//&nbsp; if necessary (e.g. addressing only one of the channels). The most prominent build instruction used within the processing patterns (which is the instruction {{{"attach"}}}) relies on the aforementioned //approach of abstracted handling,// letting the operation point determine automatically how to make the connection.
+
+This is possible because the operation point has been provided (by the mould) with informations about the media stream type to be wired, while at the same time relying on the [[render node interface|ProcNode]] for finding out whats possible and making the desired connections.
+
+
The Lumiera Processing Layer is comprised of various subsystems and can be separated into a low-level and a high-level part. At the low-level end is the [[Render Engine|OverviewRenderEngine]] which basically is a network of render nodes cooperating closely with the Backend Layer in order to carry out the actual playback and media transforming calculations. Whereas on the high-level side we find several different [[Media Objects|MObjects]] that can be placed into the [[EDL]], edited and manipulated. This is complemented by the [[Asset Management|Asset]], which is the "bookkeeping view" of all the different "things" within each [[Session|SessionOverview]].
 
@@ -2657,8 +2665,17 @@ The system is ''open'' inasmuch every part mirrors the structure of correspondin
 &rarr; [[Implementation Details|ImplementationDetails]] {{red{WIP}}}
 
-
+
A data processing node within the Render Engine. Its key feature is the possibility to pull from it one (freely addressable) [[Frame]] of calculated data. Further, each ~ProcNode has the ability to be wired with other nodes and [[Parameter Providers|ParamProvider]]
+
+!! {{red{open questions}}}
+* how to address a node
+* how to type them
+* how to discover the number and type of the ports
+* how to discover the possible parameter ports
+* how to define and query for additional capabilities
+
+&rarr; see also the [[open design process draft|http://www.pipapo.org/pipawiki/Lumiera/DesignProcess/DesignRenderNodesInterface]]
 
From 8daec32733cdb4bd25e99f982354268c09c5a2ce Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 30 May 2008 06:23:13 +0200 Subject: [PATCH 02/12] first draft plans for the render process, as far as needed for defining the builder --- src/proc/mobject/builder/toolfactory.hpp | 6 ++ wiki/renderengine.html | 75 ++++++++++++++++++------ 2 files changed, 64 insertions(+), 17 deletions(-) diff --git a/src/proc/mobject/builder/toolfactory.hpp b/src/proc/mobject/builder/toolfactory.hpp index ecb9f7949..1f6cbd7aa 100644 --- a/src/proc/mobject/builder/toolfactory.hpp +++ b/src/proc/mobject/builder/toolfactory.hpp @@ -40,6 +40,12 @@ namespace mobject { using asset::PPipe; using session::PClipMO; + /** + * provides the builder with the necessary, preconfigured tools. + * Dedicated to a single build process, it holds the internal state + * of this process and thus serves to coordinate and link together all + * the individual parts fabricated by using the various tools. + */ class ToolFactory { public: diff --git a/wiki/renderengine.html b/wiki/renderengine.html index 44b635e79..8b1883bbe 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -578,6 +578,9 @@ The first step towards an solution is to isolate the problem; obviously we //nee [img[how to implement Automation|uml/fig129669.png]]
+
+
While generally automation is treated as a function over time, defining and providing such a function requires some //Automation Data.// The actual layout and meaning of this data is deemed an implementation detail of the [[parameter provider|ParamProvider]] used, but nevertheless an automation data set has object characteristics within the [[EDL (high-level-model)|EDL]], allowing it to be attached, moved and [[placed|Placement]] by the user.
+
Starting out from the concepts of Objects, Placement to Tracks, render Pipes and connection properties (&rarr; see [[here|TrackPipeEDL]]) within the EDL, we can identify the elementary operations occuring within the Builder. Overall, the Builder is organized as application of //visiting tools// to a collection of objects, so finally we have to consider some object kind appearing in the working function of the given builder tool, which holds at this moment some //context//. The job now is to organize this context such as to create a predictable build process from this //event driven// approach.
 &rarr;see also: BuilderPrimitives for the elementary situations used to cary out the building operations
@@ -729,11 +732,11 @@ config.macros.timeline.handler = function(place,macroName,params,wikifier,paramS
 }
 //}}}
-
+
All decisions on //how // the RenderProcess has to be carried out are concentrated in this rather complicated Builder Subsystem. The benefit of this approach is, besides decoupling of subsystems, to keep the actual performance-intensive video processing code as simple and transparent as possible. The price, in terms of increased complexity &mdash; to pay in the Builder &mdash; can be handled by making the Build Process generic to a large degree. Using a Design By Contract approach we can decompose the various decisions into small decision modules without having to trace the actual workings of the Build Process as a whole.
 
 [>img[Outline of the Build Process|uml/fig129413.png]]
-The building itself will be broken down into several small tool application steps. Each of these steps has to be mapped to the MObjects found on the [[Timeline]]. Remember: the idea is that the so called "[[Fixture]]" contains only [[ExplicitPlacement]]s which in turn link to MObjects like Clips, Effects and Automation. So it is sufficient to traverse this list and map the build tools to the elements. Each of these build tools has its own state, which serves to build up the resulting Render Engine. So far I see two steps to be necessary:
+The building itself will be broken down into several small tool application steps. Each of these steps has to be mapped to the MObjects found on the [[Timeline]]. Remember: the idea is that the so called "[[Fixture]]" contains only [[ExplicitPlacement]]s which in turn link to MObjects like Clips, Effects and [[Automation]]. So it is sufficient to traverse this list and map the build tools to the elements. Each of these build tools has its own state, which serves to build up the resulting Render Engine. So far I see two steps to be necessary:
 * find the "Segments", i.e. the locations where the overall configuration changes
 * for each segment: generate a ProcNode for each found MObject and wire them accordingly
 Note, //we still have to work out how exactly building, rendering and playback work// together with the backend-design. The build process as such doesn't overly depend on these decisions. It is easy to reconfigure this process. For example, it would be possible as well to build for each frame separately (as Cinelerra2 does), or to build one segment covering the whole timeline (and handle everything via [[Automation]]
@@ -749,7 +752,30 @@ Note, //we still have to work out how exactly building, rendering and playback w
 [img[Colaborations in the Build Process|uml/fig128517.png]]
 
-
+
+
Actually setting up and wiring a [[processing node|ProcNode]] involves several issues and is carried out at the lowest level of the build process. 
+
+!!!object creation
+The Nodes are small polymorphic objects, carrying configuration data, but no state. They are [[specially allocated|ManagementRenderNodes]], and the object creation is accessible solely by the NodeFactory. They //must not be deallocated manually.// The decision of what concrete node type to create depends on the actual build situation and is worked out by the combination of [[mould|BuilderMould]] and [[processing pattern|ProcPatt]] at the current OperationPoint, issuing a call to one of NodeFactory's {{{operator()}}}
+
+!!!node, plugin and processing function
+Its a good idea to distinguish clearly between those concepts. A plugin is a piece of (possibly external) code we use to carry out operations. We have to //discover its properties and capabilities.// We don't have to discover anything regarding nodes, because we (Lumiera builder and renderengine) are creating, configuring and wiring them to fit the specific purpose. Both are to be distinguished from processing functions, which do the actual calculations on the media data. Every node typically encompasses at least one processing function, which may be an internal function in the node object, a library function from Lumiera or GAVL, or external code loaded from a plugin.
+
+!!!node interfaces
+As a consequence of this distinctions, in conjunction with a processing node, we have to deal with three different interfaces
+* the __build interface__ is used by the builder to set up and wire the nodes. It can be full blown C++ (including templates)
+* the __operation interface__ is used to run the calculations, which happens in cooperation of Proc-Layer and Backend. So a function-style interface is preferable.
+* the __inward interface__ is accessed by the processing function in the course of the calculations to get at the necessary context, including in/out buffers and param values.
+
+!!!wiring data connections
+A node //knows its predecessors, but not its successors.// When being //pulled//&nbsp; in operation, it can expect to get a frame provider for accessing the in/out buffer locations (some processing functions may be "in-place capable", but that's only a special case of the former). At this point, the ''pull principle'' comes into play: the node may request input frames from the frame provider, passing its predecessors as a ''continuation''.
+With regard to the build process, the wiring of data connections translates into providing the node with its predecessors and preconfiguring the possible continuations. While in the common case, a node has just one input/output and pulls from its predecessor a frame for the same timeline position, the general case can be more contrived. A node may process N buffers in parallel and may require several different time positions for it's input, even at a differing framerate. So the actual source specification is (predNode,time,frameType). The objective of the wiring done in the build process is to factor out the parts known in advance, while in the render process only the variable part need to be filled in. Or to put it differently: wiring builds a higher order function (time)->(continuation), where continuation can be invoked to get the desired input frame.
+
+!!!wiring control conections
+In many cases, the parameter values provided by these connections aren't frame based data, rather, the processing function needs a call interface to get the current value (value for a given time), which is provided by the parameter object. Here, the wiring needs to link to the suitable parameter instance, which is located within the high-level model (!). As an additional complication, calculating the actual parameter value may require a context data frame (typically for caching purposes to speed up the interpolation). While these parameter context data frames are completely opaque for the render node, they have to be passed in and out similar to the state needed by the node itself, and the wiring has to prepare for accessing these frames too.
+
+
+
The Builder takes some MObject/[[Placement]] information (called Timeline) and generates out of this a Render Engine configuration able to render this Objects. It does all decisions and retrieves the current configuration of all objects and plugins, so the Render Engine can just process them stright forward.
 
 The Builder is the central part of the [[Builder Pattern|http://en.wikipedia.org/wiki/Builder_pattern]]
@@ -761,7 +787,7 @@ As the builder has to create a render node network implementing most of the feat
 * //operating the Builder// can be viewed at from two different angles, either emphasizing the [[basic building operations|BasicBuildingOperations]] employed to assemble the render node network, or focussing rather at the [[mechanics|BuilderMechanics]] of cooperating parts while processing.
 * besides, we can identify a small set of elementary situations we call [[builder primitives|BuilderPrimitives]], to be covered by the mentioned BuilderToolKit; by virtue of [[processing patterns|ProcPatt]] they form an [[interface to the rule based configuration|BuilderRulesInterface]].
 * the actual building (i.e. the application of tools to the timeline) is done by the [[Assembler|BuilderAssembler]], which is basically a collection of functions (but has a small amount of global configuration state)
-* any non-trivial wiring of render nodes, tracks, pipes and automation is done by the services of the [[connection manager|ConManager]]
+* any non-trivial wiring of render nodes, tracks, pipes and [[automation|Automation]] is done by the services of the [[connection manager|ConManager]]
 
@@ -1010,7 +1036,7 @@ As we don't have a Prolog interpreter on board yet, we utilize a mock store with {{{default(Obj)}}} is a predicate expressing that the object {{{Obj}}} can be considered the default setup under the given conditions. Using the //default// can be considered as a shortcut for actually finding a exact and unique solution. The latter would require to specify all sorts of detailed properties up to the point where only one single object can satisfy all conditions. On the other hand, leaving some properties unspecified would yield a set of solutions (and the user code issuing the query had to provide means for selecting one soltution from this set). Just falling back on the //default// means that the user code actually doesn't care for any additional properties (as long as the properties he //does// care for are satisfied). Nothing is said specifically on //how//&nbsp; this default gets configured; actually there can be rules //somewhere,// and, additionally, anything encountered once while asking for a default can be re-used as default under similar circumstances. &rarr; [[implementing defaults|DefaultsImplementation]]
-
+
Along the way of working out various [[implementation details|ImplementationDetails]], decisions need to be made on how to understand the different facilities and entities and how to tackle some of the problems. This page is mainly a collection of keywords, summaries and links to further the discussion. And the various decisions should allways be read as proposals to solve some problem at hand...
 
 ''Everything is an object'' &mdash; of course, that's a //no-brainer // todays. Rather, important is what is not "an object", meaning it can't be arranged arbitrarily
@@ -1023,10 +1049,10 @@ We ''separate'' processing (rendering) and configuration (building). We have a [
 ''Objects are [[placed|Placement]] rather'' than assembled, connected, wired, attached. This is more of a rule-based approach and gives us one central metaphor and abstraction, allowing us to treat everything in an uniform manner. You can place it as you like, and the builder tries to make sense out of it, silently disabling what doesn't make sense.
 An [[EDL]] is just a collection of configured and placed objects (and has no additional, fixed structure). [[Tracks|Track]] form a mere organisational grid, they are grouping devices not first-class entities (a track doesn't "have" a pipe or "is" a video track and the like; it can be configured to behave in such manner by using placements though). [[Pipes|Pipe]] are hooks for making connections and are the only facility to build processing chains. We have global pipes, and each clip is built around a lokal [[source port|ClipSourcePort]] &mdash; and that's all. No special "media viewer" and "arranger", no special role for media sources, no commitment to some fixed media stream types (video and audio). All of this is sort of pushed down to be configuration, represented as asset of some kind. For example, we have [[processing pattern|ProcPatt]] assets to represent the way of building the source network for reading from some media file (including codecs treated like effect plugin nodes)
 
-''State'' is rigorously ''externalized'' and operations are to be ''scheduled'', to simplify locking and error handling. State is either treated similar to media stream data (as addressable and cacheable data frame), or is represented as "parameter" to be served by some [[parameter provider|ParamProvider]]. Automation is just another kind of parameter, i.e. a function, and how this function is calculated is an encapsulated implementation detail (we don't have "bezier automation", and then maybe a "linear automation", a "mask automation" and yet another way to handle transitions)
+''State'' is rigorously ''externalized'' and operations are to be ''scheduled'', to simplify locking and error handling. State is either treated similar to media stream data (as addressable and cacheable data frame), or is represented as "parameter" to be served by some [[parameter provider|ParamProvider]]. Consequently, [[Automation]] is just another kind of parameter, i.e. a function &mdash; how this function is calculated is an encapsulated implementation detail (we don't have "bezier automation", and then maybe a "linear automation", a "mask automation" and yet another way to handle transitions)
 
-
+
This __proc-Layer__ and ~Render-Engine implementation started out as a design-draft by [[Ichthyo|mailto:Ichthyostega@web.de]] in summer 2007. The key idea of this design-draft is to use the [[Builder Pattern|http://en.wikipedia.org/wiki/Builder_pattern]] for the Render Engine, thus separating completely the //building// of the Render Pipeline from //running,// i.e. doing the actual Render. The Nodes in this Pipeline should process Video/Audio and do nothing else. No more decisions, tests and conditional operations when running the Pipeline. Move all of this out into the configuration of the pipeline, which is done by the Builder.
 
 !Why doesn't the current Cinelerra-2 Design succeed?
@@ -1045,7 +1071,7 @@ As always, the main goal is //to cut down complexity// by the usual approach to
 
 To achieve this, here we try to separate ''Configuration'' from ''Processing''. Further, in Configuration we try to separate the ''high level view'' (users view when editing) from the ''low level view'' (the actual configuration effective for the calculations). Finally, we try to factor out and encapsulate ''State'' in order to make State explicit.
 
-The main tool used to implement this separation is the [[Builder Pattern|http://en.wikipedia.org/wiki/Builder_pattern]]. Here especially we move all decisions and parametrization into the BuildProcess. The Nodes in the render pipeline should process Video/Audio and do nothing else. No more decisions, tests and conditional operations when running the Pipeline. Move all of this out into the configuration of the pipeline, which is done by the Builder. Make the actual processing nodes Template classes, parametrized by the color model and number of components. Make all Nodes of equal footing with each other, able to be connected freely within the limitations of the necessary input and output. Make the OpenGL rendering into alternate implementation of some operations together with an alternate signal flow (usable only if the whole Pipeline can be built up to support this changed signal flow), thus factoring out all the complexities of managing the data flow between core and hardware accelerated rendering out of the implementation of the actual processing. Introduce separate control data connections for the automation data, separating the case of true multi-channel-effects from the case where one node just gets remote controlled by another node (or two nodes using the same automation data).
+The main tool used to implement this separation is the [[Builder Pattern|http://en.wikipedia.org/wiki/Builder_pattern]]. Here especially we move all decisions and parametrization into the BuildProcess. The Nodes in the render pipeline should process Video/Audio and do nothing else. No more decisions, tests and conditional operations when running the Pipeline. Move all of this out into the configuration of the pipeline, which is done by the Builder. Make the actual processing nodes Template classes, parametrized by the color model and number of components. Make all Nodes of equal footing with each other, able to be connected freely within the limitations of the necessary input and output. Make the OpenGL rendering into alternate implementation of some operations together with an alternate signal flow (usable only if the whole Pipeline can be built up to support this changed signal flow), thus factoring out all the complexities of managing the data flow between core and hardware accelerated rendering out of the implementation of the actual processing. Introduce separate control data connections for the [[automation data|Automation]], separating the case of true multi-channel-effects from the case where one node just gets remote controlled by another node (or two nodes are utilizing the same automation data).
 
 Another pertinent theme is to make the basic building blocks simpler, while on the other hand gaining much more flexibility for combining these building blocks. For example we try to unfold any "internal-multi" effects into separate instances (e.g. the possibility of having an arbitrary number of single masks at any point of the pipeline instead of having one special masking facility encompassing multiple sub-masks. Similarly, we treat the Objects in the EDL in a more uniform manner and gain the possibility to [[place|Placement]] them in various ways.
 
@@ -1722,6 +1748,12 @@ This Design strives to achieve a StrongSeparation between the low-level Structur {{red{let's see if this approach works...}}}
+
+
Contrary to the &rarr;[[Assets and MObjects|ManagementAssetRelation]], the usage pattern for [[render nodes|ProcNode]] is quite simple: All nodes are created together every time a new segment of the network is being build and are all needed together until this segment is re-built, at which point they can be thrown away altogether. While it would be easy to handle the nodes automatically by smart-ptr (the creation is accessible only by use of the {{{NodeFactory}}} anyways), it //seems advisable to care for a bulk allocation/deallocation here.// The reason being not so much the amount of memory (which is expected to be moderate), but the fact, that the build process can be triggered repeatedly several times a second when tweaking the EDL, which could lead to fragmentation and memory pressure.
+
+__5/2008__: the allocation mechanism can surely be improved later, but for now I am going for a simple implementation based on keeping all nodes of one kind together in a vector. The list of possible node kinds is hard wired, allowing to generate the object holding a chunk of nodes for one segment, mostly relying on the runtime system for the management.
+
+
<!--{{{-->
 <link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml'/>
@@ -1887,8 +1919,8 @@ see also: RenderEntities, [[two Examples (Object diagrams)|Examples]]
 <!--}}}-->
 
-
-
A ParamProvider is the counterpart for (one or many) Parameter instances. It implements the value access function made available by the Parameter object to its clients.
+
+
A ParamProvider is the counterpart for (one or many) [[Parameter]] instances. It implements the value access function made available by the Parameter object to its clients.
 
 To give a concrete example: 
 * a Fade Plugin needs the actual fade value for Frame t=xxx
@@ -1900,8 +1932,8 @@ To give a concrete example:
 &rarr; see the class diagram for [[Automation]]
 
-
-
Parameters are all probably variable control values used within the Render Engine. Contrast this with configuration values, which are considered to be fixed and need an internal reset of the application state to take effect.
+
+
Parameters are all possibly variable control values used within the Render Engine. Contrast this with configuration values, which are considered to be fixed and need an internal reset of the application (or session) state to take effect.
 
 A ''Parameter Object'' provides a descriptor of the kind of parameter, together with a function used to pull the //actual value// of this parameter. Here, //actual// has a two-fold meaning:
 * if called without a time specification, it is either a global (but variable) system or session parameter or a default value for automated Parameters. (the intention is to treat this cases uniformly)
@@ -2665,7 +2697,7 @@ The system is ''open'' inasmuch every part mirrors the structure of correspondin
 &rarr; [[Implementation Details|ImplementationDetails]] {{red{WIP}}}
 
-
+
A data processing node within the Render Engine. Its key feature is the possibility to pull from it one (freely addressable) [[Frame]] of calculated data. Further, each ~ProcNode has the ability to be wired with other nodes and [[Parameter Providers|ParamProvider]]
 
 !! {{red{open questions}}}
@@ -2676,6 +2708,7 @@ The system is ''open'' inasmuch every part mirrors the structure of correspondin
 * how to define and query for additional capabilities
 
 &rarr; see also the [[open design process draft|http://www.pipapo.org/pipawiki/Lumiera/DesignProcess/DesignRenderNodesInterface]]
+&rarr; see RenderProcess
 
@@ -4347,12 +4380,12 @@ Placements are __resolved__ resulting in an ExplicitPlacement. In most cases thi &rarr; [[Definition|Pipe]] and [[handling of Pipes|PipeHandling]]
-
+
Transitions combine the data from at least two processing chains and do this combining in a time varying fashion. So, any transition has
 * N input connections
 * either one or N output connections
 * temporal coordinates (time, length)
-* some control data connection to a ParamProvider, because in the most general case the controling curves are treated like automation
+* some control data connection to a ParamProvider, because in the most general case the controling curves are treated similar to  [[automation data|AutomationData]]
 
 !!!how much output ports?
 The standard case of a transition is sort of mixing together two input streams, like e.g. a simple dissolve. For this to be of any use, this input streams need to be connected to the same ouput destination before and after the transition (with regards to the timeline), i.e. the inputs and the transition share placement to the same output pipe. In this case, when the transition starts, the direct connections can be suspended and the transition will switch in seamlessly.
@@ -4416,7 +4449,7 @@ generally speaking, visitors are preferable when the underlying element type hie
 To see an simple example of our "visiting tool", have a look at {{{tests/components/common/visitingtooltest.cpp}}}
 
-
+
The Intention of this text is to help you understanding the design and to show some notable details.
 
 !!!!Starting Point
@@ -4437,7 +4470,7 @@ This design strives to build each level and subsystem around some central concep
 * albeit being a special form of a Placement, the ExplicitPlacement is treated as a separate concept. With respect to edit operations within the EDL, it can stand for any sort of Placement. On the other hand the Builder takes a list of ~ExplicitPlacements as input for building up the Render Engine(s). This corresponds to the fact that the render process needs to organize the things to be done on a simple two dimensional grid of (output channel / time). The (extended) contract of an ~ExplicitPlacement provides us with this (output,time).
 * on the lower end of the builder, everything is organized around the Concept of a ProcNode, which enables us to //pull// one (freely addressable) Frame of calculated data. Further, the ProcNode has the ability to be wired with other nodes and [[Parameter Providers|ParamProvider]]
 * the various types of data to be processed are abstracted away under the notion of a [[Frame]]. Basically, a Frame is an Buffer containing an Array of raw data and it can be located by some generic scheme, including (at least) the absolute starting time (and probably some type or channel id).
-* All sorts of (target domain) [[Parameters]] are treated uniformly. There is a distinction between Parameters (which //could// be variable) and Configuration (which is considered to be fixed). In this context, Automation just appears as a special kind of ParamProvider.
+* All sorts of (target domain) [[parameters|Parameter]] are treated uniformly. There is a distinction between Parameters (which //could// be variable) and Configuration (which is considered to be fixed). In this context, [[Automation]] just appears as a special kind of ParamProvider.
 * and finally, the calculation //process// together with its current state is represented by a StateProxy. I call this a "proxy", because it should encapsulate and hide all tedious details of communication, be it even asynchronous communication with some Controller or Dispatcher running in another Thread. In order to maintain a view on the current state of the render process, it could eventually be necessary to register as an observer somewhere or to send notifications to other parts of the system.
 
 !!!!Handling Diversity
@@ -4450,6 +4483,14 @@ In case it's not already clear: we don't have "the" Render Engine, rat
 The &raquo;current setup&laquo; of the objects in the EDL is sort of a global state. Same holds true for the Controller, as the Engine can be at playback, it can run a background render or scrub single frames. But the whole complicated subsystem of the Builder and one given Render Engine configuration can be made ''stateless''. As a benefit of this we can run this subsystems multi-threaded without the need of any precautions (locking, synchronizing). Because all state information is just passed in as function parameters and lives in local variables on the stack, or is contained in the StateProxy which represents the given render //process// and is passed down as function parameter as well. (note: I use the term "stateless" in the usual, slightly relaxed manner; of course there are some configuration values contained in instance variables of the objects carrying out the calculations, but this values are considered to be constant over the course of the object usage).
 
+
+
The purpose of automation is to vary a parameter of some data processing instance in the course of time while rendering. Thus, automation encompasses all the variability within the render network //which is not a structural change.//
+
+
+!Parameters and Automation
+
+[[Automation]] is treated as a function over time. Everything beyond this definition is considered an implementation detail of the [[parameter provider|ParamProvider]] used to yield the value. Thus automation is closely tied to the concept of a [[Parameter]], which also plays an important role in the communication with the GUI and while [[setting up and wiring the render nodes|BuildRenderNode]] in the course of the build process (&rarr; see [[tag:Builder|Builder]])
+
From 6ad61b0108239805c891c7bbe6b74ca7e16d67ef Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 1 Jun 2008 06:05:39 +0200 Subject: [PATCH 03/12] further draftings, esp. how the render nodes are operated --- wiki/renderengine.html | 45 ++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/wiki/renderengine.html b/wiki/renderengine.html index 8b1883bbe..be449639b 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -752,8 +752,9 @@ Note, //we still have to work out how exactly building, rendering and playback w [img[Colaborations in the Build Process|uml/fig128517.png]]
-
-
Actually setting up and wiring a [[processing node|ProcNode]] involves several issues and is carried out at the lowest level of the build process. 
+
+
Actually setting up and wiring a [[processing node|ProcNode]] involves several issues and is carried out at the lowest level of the build process.
+It is closely related to &rarr; [[the way nodes are operated|NodeOperationProtocol]]
 
 !!!object creation
 The Nodes are small polymorphic objects, carrying configuration data, but no state. They are [[specially allocated|ManagementRenderNodes]], and the object creation is accessible solely by the NodeFactory. They //must not be deallocated manually.// The decision of what concrete node type to create depends on the actual build situation and is worked out by the combination of [[mould|BuilderMould]] and [[processing pattern|ProcPatt]] at the current OperationPoint, issuing a call to one of NodeFactory's {{{operator()}}}
@@ -1823,6 +1824,21 @@ So, when creating a clip out of such a compound media asset, the clip has to be
 
NodeCreaterTool is a [[visiting tool|VisitorUse]] used as second step in the [[Builder]]. Starting out from a [[Fixture]], the builder first [[divides the Timeline into segments|SegmentationTool]] and then processes each segment with the NodeCreaterTool to build a render nodes network (Render Engine) for this part of the timeline. While visiting individual Objects and Placements, the NodeCreaterTool creates and wires the necessary [[nodes|ProcNode]]
+
+
The [[nodes|ProcNode]] are wired to form a "Directed Acyclic Graph"; each node knows its predecessor(s), but not its successor(s).  The RenderProcess is organized according to the ''pull principle'', thus we find an operation {{{pull()}}} at the core of this process. There is no such thing as an "engine object" calling nodes iteratively or table driven, rather, the nodes themselves issue recursive calls to their predecessor(s). For this to work, we need the nodes to adhere to a specific protocol:
+# Node is pulled, providing a StateProxy object (encapsulating the access to the frames or buffers)
+# Node may now access current parameter values, using the state accessible via the StateProxy
+# Node calles back into the StateProxy, providing the //input descriptor//
+# StateProxy tries to get the input frames from the Cache in the Backend. If this fails, it forwards the call using the information in the input descriptor
+# after this call returns, the Node is allowed to dereference the frame pointers and do its calculations
+# finally, when the {{{pull()}}} call returns, the StateProxy may push down the result frames to the cache
+some points to note:
+* the input descriptor is {{{const}}} and precalculated while building (remember another thread may call in parallel)
+* when a node is "inplace-capable", input and output buffer may actually point to the same location
+* but there is no guarantee for this to happen, because the cache may be involved (and we can't overwrite the contents of a cache frame)
+* generally, a node may have N inputs and M output frames, which are expected to be processed in a single call
+
+
We have to consider carefully how to handle the Creation of new class instances. Because, when done naively, it can defeat all efforts of separating subsystems, or &mdash; the other extreme &mdash; lead to a //switch-on-typeID//  programming style. We strive at a solution somewhere in the middle by utilizing __Abstract Factories__ on Interface or key abstraction classes, but providing specialized overloads for the different use cases. So in each use case we have to decide if we want to create a instance of some general concept (Interface), or if we have a direct collaboration and thus need the Factory to provide a more specific sub-Interface or even a concrete type.
 
@@ -1881,7 +1897,7 @@ There is rather strong separation between these two levels, and &mdash; <
 [img[Block Diagram|uml/fig128005.png]]
 
-
+
Render Engine, [[Builder]] and [[Controller]] are closely related Subsystems. Actually, the [[Builder]] //creates// a newly configured Render Engine //for every// RenderProcess. Before doing so, it queries from the Session (or, to be more precise, from the [[Fixture]] within the current Session) all necessary Media Object Placement information. The [[Builder]] then derives from this information the actual assembly of [[Processing Nodes|ProcNode]] comprising the Render Engine. Thus:
  * the source of the build process is a sequence of absolute (explicit) [[Placements|Placement]] called the [[Playlist]]
  * the [[build process|BuildProcess]] is driven, configured and controlled by the [[Controller]] subsystem component. It encompasses the actual playback configuration and State of the System.
@@ -2997,18 +3013,26 @@ At first sight the link between asset and clip-MO is a simple logical relation b
 &rarr; OverviewRenderEngine
 
-
-
The Render Engine only carries out the low-level and performance critical tasks. All configuration and decision concerns are to be handled by [[Builder]] and [[Controller]]. While the actual connection of the Render Nodes can be highly complex, basically each Segment of the Timeline with uniform characteristics is handled by one Processor, which is a graph of [[Processing Nodes|ProcNode]] discharging into a ExitNode. The Render Engine Components as such are //stateless// themselves; for the actual calculations they are combined with a StateProxy object generated by and connected internally to the [[Controller]], while at the same time holding the Data Buffers (Frames) for the actual calculations.
+
+
The [[Render Engine|Rendering]] only carries out the low-level and performance critical tasks. All configuration and decision concerns are to be handled by [[Builder]] and [[Controller]]. While the actual connection of the Render Nodes can be highly complex, basically each Segment of the Timeline with uniform characteristics is handled by one Processor, which is a graph of [[Processing Nodes|ProcNode]] discharging into a ExitNode. The Render Engine Components as such are //stateless// themselves; for the actual calculations they are combined with a StateProxy object generated by and connected internally to the [[Controller]], while at the same time holding the Data Buffers (Frames) for the actual calculations.
 
 [img[Entities comprising the Render Engine|uml/fig128389.png]]
 
-
-
{{red{TODO: describe the Render Process.}}}
-
- * see also the [[Entities involved in Rendering|RenderEntities]]
+
+
For each segment (of the effective timeline), there is a Processor holding the exit node(s) of a processing network, which is a "Directed Acyclic Graph" of small, preconfigured, stateless [[processing nodes|ProcNode]]. This network is operated according to the ''pull principle'', meaning that the rendering is just initiated by "pulling" output from the exit node, causing a cascade of recursive downcalls. Each node knows its predecessor(s) an can pull the necessary input from there. Consequently, there is no centralized "engine object" which may invoke nodes iteratively or table driven &mdash; rather, the rendering can be seen as a passive service provided for the backend, which may pull from the exit nodes at any time, in any order (?), and possibly multithreaded.
+All State necessary for a given calculation process is encapsulated and accessible by a StateProxy object, which can be seen as the representation of "the process". At the same time, this proxy acts as a gateway to the backend to handle the communication with the Cache.
+{{red{TODO: fill in more details of the Render Process.}}}
+* see also
+&rarr; the [[Entities involved in Rendering|RenderEntities]]
+&rarr; the protocol [[how to operate the nodes|NodeOperationProtocol]]
 
+
+
The rendering of input sources to the desired output ports happens within the &raquo;''Render Engine''&laquo;, which can be seen as a collaboration of Proc-Layer, Backend together with external/library code for the actual data manipulation. In preparation of the RenderProcess, the [[Builder]] as wired up a network of [[processing nodes|ProcNode]] called the ''low-level model'' (in contrast to the high-level model of objects placed within the EDL/Session). Generally, this network is a "Directed Acyclic Graph" starting at the //exit nodes// (output ports) and pointing down to the //source readers.// In Lumiera, rendering is organized according to the ''pull principle'': when a specific frame of rendered data is requested from an exit node, a recursive calldown happens, as each node asks his predecessor(s) for the necessary input frame(s). This may include pulling frames from various input sources and for several time points, thus pull rendering is more powerful (but also more difficult to understand) than push rendering, where the process would start out with a given source frame.
+
+Rendering can be seen as a passive service available to the Backend, which remains in charge what to render and when. Render processes may be running in parallel without any limitations. All of the storage and data management falls into the realm of the Backend. The render nodes themselves are ''completely stateless'' &mdash; if some state is necessary for carrying out the calculations, the backend will provide a //state frame// in addition to the data frames.
+
The Session contains all informations, state and objects to be edited by the User. From a users view, the Session is synonymous to the //current Project//. It can be saved and loaded. The individual Objects within the Session, i.e. Clips, Media, Effects, are contained in one (or several) collections within the Session, which we call [[EDL (Edit Decision List)|EDL]]. &rarr; [[Session design overview|SessionOverview]]
 
@@ -3109,11 +3133,12 @@ if (oldText.indexOf("SplashScreen")==-1)
 }
 //}}}
-
+
An Object representing a //Render Process// and containing associated state information.
 * it is created in the Controller subsystem while initiating the BuildProcess
 * it is passed on to the generated Render Engine, which in turn passes it down to the individual Processors
 * moreover, it contains methods to communicate with other state relevant parts of the system, thereby shielding the rendering code from any complexities of Thread communication if necessary. (thus the name Proxy)
+* in a future version, it may also encapsulate the communication in a distributed render farm
 
From 3c2a6f0598225044c0eecd464b3746c8676c638b Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 3 Jun 2008 06:22:41 +0200 Subject: [PATCH 04/12] planing more details of the render mechanics --- doc/devel/uml/class130949.html | 2 +- doc/devel/uml/class131589.html | 1 + doc/devel/uml/class131717.html | 5 +- doc/devel/uml/class131845.html | 1 + doc/devel/uml/class131973.html | 1 + doc/devel/uml/class132101.html | 1 + doc/devel/uml/class132229.html | 1 + doc/devel/uml/class132357.html | 1 + doc/devel/uml/class132485.html | 1 + doc/devel/uml/class132613.html | 1 + doc/devel/uml/class132741.html | 8 +- doc/devel/uml/class132869.html | 2 +- doc/devel/uml/class132997.html | 2 +- doc/devel/uml/class133125.html | 2 +- doc/devel/uml/class133765.html | 1 + doc/devel/uml/class135045.html | 1 + doc/devel/uml/class142085.html | 22 ++++++ doc/devel/uml/class142213.html | 27 +++++++ doc/devel/uml/class142341.html | 20 +++++ doc/devel/uml/class142469.html | 20 +++++ doc/devel/uml/class142597.html | 20 +++++ doc/devel/uml/classdiagrams.html | 1 + doc/devel/uml/classes.html | 8 +- doc/devel/uml/classes_list.html | 8 +- doc/devel/uml/collaborationdiagrams.html | 1 + doc/devel/uml/fig128389.png | Bin 30399 -> 31223 bytes doc/devel/uml/fig131973.png | Bin 0 -> 16309 bytes doc/devel/uml/fig132101.png | Bin 0 -> 18071 bytes doc/devel/uml/index.html | 37 +++++++-- doc/devel/uml/index_60.html | 4 +- doc/devel/uml/index_65.html | 4 +- doc/devel/uml/index_66.html | 3 +- doc/devel/uml/index_67.html | 44 ++++++----- doc/devel/uml/index_68.html | 2 +- doc/devel/uml/index_69.html | 5 +- doc/devel/uml/index_70.html | 2 +- doc/devel/uml/index_73.html | 3 +- doc/devel/uml/index_77.html | 2 +- doc/devel/uml/index_78.html | 3 + doc/devel/uml/index_79.html | 4 +- doc/devel/uml/index_80.html | 5 ++ doc/devel/uml/index_82.html | 4 +- doc/devel/uml/index_83.html | 7 +- doc/devel/uml/index_84.html | 6 +- doc/devel/uml/index_86.html | 20 ++--- doc/devel/uml/public_operations.html | 3 + uml/lumiera/128389.diagram | 28 +++---- uml/lumiera/129285 | 2 +- uml/lumiera/131973.diagram | 67 +++++++++++++++++ uml/lumiera/132101.diagram | 91 +++++++++++++++++++++++ uml/lumiera/5.session | 14 +++- uml/lumiera/lumiera.prj | 2 +- wiki/renderengine.html | 86 ++++++++++++++------- 53 files changed, 492 insertions(+), 114 deletions(-) create mode 100644 doc/devel/uml/class142085.html create mode 100644 doc/devel/uml/class142213.html create mode 100644 doc/devel/uml/class142341.html create mode 100644 doc/devel/uml/class142469.html create mode 100644 doc/devel/uml/class142597.html create mode 100644 doc/devel/uml/fig131973.png create mode 100644 doc/devel/uml/fig132101.png create mode 100644 uml/lumiera/131973.diagram create mode 100644 uml/lumiera/132101.diagram diff --git a/doc/devel/uml/class130949.html b/doc/devel/uml/class130949.html index 774585ac5..05f451c34 100644 --- a/doc/devel/uml/class130949.html +++ b/doc/devel/uml/class130949.html @@ -18,7 +18,7 @@

Declaration :

  • C++ : class RenderState

Encapsulates the logic used to get a "current render process" in accordance to the currentyl applicable controller settings. The provided StateProxy serves to hold any mutalbe state used in the render process, so the rest of the render engine can be stateless.

Artifact : renderstate

-
Operation getStateProxy

Declaration :

+
Operation getStateProxy

Declaration :

  • Uml : + getStateProxy() : State
  • C++ : public: State getStateProxy ()

All public operations : getStateProxy

diff --git a/doc/devel/uml/class131589.html b/doc/devel/uml/class131589.html index c65bef7fb..beefcf13d 100644 --- a/doc/devel/uml/class131589.html +++ b/doc/devel/uml/class131589.html @@ -18,5 +18,6 @@

Declaration :

The output of the render pipeline. Pulling from such exit nodes actually ivokes the render process

Artifact : exitnode

+

All public operations : pull

diff --git a/doc/devel/uml/class131717.html b/doc/devel/uml/class131717.html index d03898369..8952f6f05 100644 --- a/doc/devel/uml/class131717.html +++ b/doc/devel/uml/class131717.html @@ -20,6 +20,9 @@

Key abstraction of the Render Engine: A Data processing Node

Artifact : procnode

Relation datasrc (<unidirectional association>)

Declaration :

The predecessor in a processing pipeline, i.e. a source to get data to be processed

-
Relation params (<directional aggregation by value>)

Declaration :

+
Relation params (<directional aggregation by value>)

Declaration :

+
Operation pull

Declaration :

  • Uml : + pull(inout renderProcess : State) : void
  • C++ : public: void pull ()

trigger data processing by "pulling" results from the node's output

+
Relation predecessors (<directional aggregation by value>)

Declaration :

preconfigured table of all predecessor nodes, qualified
with the output port on these nodes and time offset of the data
we need for doing our calculations

+

All public operations : pull

diff --git a/doc/devel/uml/class131845.html b/doc/devel/uml/class131845.html index 278d1cdb1..c59787b25 100644 --- a/doc/devel/uml/class131845.html +++ b/doc/devel/uml/class131845.html @@ -19,5 +19,6 @@

Declaration :

Directly inherited by : CodecAdapter Mask PluginAdapter Projector

Artifact : trafo

+

All public operations : pull

diff --git a/doc/devel/uml/class131973.html b/doc/devel/uml/class131973.html index 68e7e24de..82d637b48 100644 --- a/doc/devel/uml/class131973.html +++ b/doc/devel/uml/class131973.html @@ -19,5 +19,6 @@

Declaration :

Directly inherited by : GLPipe

Artifact : link

+

All public operations : pull

diff --git a/doc/devel/uml/class132101.html b/doc/devel/uml/class132101.html index ca7d5ac7e..50eae3f1b 100644 --- a/doc/devel/uml/class132101.html +++ b/doc/devel/uml/class132101.html @@ -18,5 +18,6 @@

Declaration :

Artifact : hub

+

All public operations : pull

diff --git a/doc/devel/uml/class132229.html b/doc/devel/uml/class132229.html index f0ba8e9d7..28f198354 100644 --- a/doc/devel/uml/class132229.html +++ b/doc/devel/uml/class132229.html @@ -18,5 +18,6 @@

Declaration :

  • C++ : class Projector : public Trafo

Special video processing node used to scale and translate image data.

Artifact : projector

+

All public operations : pull

diff --git a/doc/devel/uml/class132357.html b/doc/devel/uml/class132357.html index 0d94f52bc..9dab6ff1f 100644 --- a/doc/devel/uml/class132357.html +++ b/doc/devel/uml/class132357.html @@ -18,5 +18,6 @@

Declaration :

  • C++ : class Mask : public Trafo

Artifact : mask

+

All public operations : pull

diff --git a/doc/devel/uml/class132485.html b/doc/devel/uml/class132485.html index b6389bd12..2ccb92506 100644 --- a/doc/devel/uml/class132485.html +++ b/doc/devel/uml/class132485.html @@ -18,5 +18,6 @@

Declaration :

  • C++ : class PluginAdapter : public Trafo

Adapter used to integrage an effects processor in the render pipeline

Artifact : pluginadapter

+

All public operations : pull

diff --git a/doc/devel/uml/class132613.html b/doc/devel/uml/class132613.html index 0134205d1..763de044c 100644 --- a/doc/devel/uml/class132613.html +++ b/doc/devel/uml/class132613.html @@ -18,5 +18,6 @@

Declaration :

  • C++ : class GLPipe : public Link

specialized connection node used to handle the transfer of OpenGL data from a image bitmap into texture form

Artifact : glpipe

+

All public operations : pull

diff --git a/doc/devel/uml/class132741.html b/doc/devel/uml/class132741.html index f0a749926..f543def13 100644 --- a/doc/devel/uml/class132741.html +++ b/doc/devel/uml/class132741.html @@ -4,21 +4,21 @@ -Class StateProxy +Class State -
Class StateProxy
+
Class State

-

Declaration :

  • C++ : class StateProxy
  • Java : public interface StateProxy

Directly inherited by : ARender GLRender VRender

+

Declaration :

  • C++ : class State
  • Java : public interface State

Directly inherited by : ARender GLRender StateAdapter StateProxy VRender

Artifact : stateproxy, Component(s) : Builder

-
Relation currFrame (<unidirectional association>)

Declaration :

  • Uml : # currFrame : Frame
  • C++ : protected: Frame * currFrame
+
Relation currFrame (<unidirectional association>)

Declaration :

  • Uml : # currFrame : Frame, multiplicity : 1..*
  • C++ : protected: vector<Frame *> currFrame
diff --git a/doc/devel/uml/class132869.html b/doc/devel/uml/class132869.html index 743378103..2d6833c2a 100644 --- a/doc/devel/uml/class132869.html +++ b/doc/devel/uml/class132869.html @@ -16,7 +16,7 @@ -

Declaration :

Representation of a Audio render process

Artifact : arender

+

Declaration :

  • C++ : class ARender : public State

Representation of a Audio render process

Artifact : arender

diff --git a/doc/devel/uml/class132997.html b/doc/devel/uml/class132997.html index 7680639be..a45d3c828 100644 --- a/doc/devel/uml/class132997.html +++ b/doc/devel/uml/class132997.html @@ -16,7 +16,7 @@ -

Declaration :

Representation of a Video render process. (Encapsulates the video buffers for the actual calculations)

Artifact : vrender

+

Declaration :

  • C++ : class VRender : public State

Representation of a Video render process. (Encapsulates the video buffers for the actual calculations)

Artifact : vrender

diff --git a/doc/devel/uml/class133125.html b/doc/devel/uml/class133125.html index 140cc4b67..d1cf4b2b6 100644 --- a/doc/devel/uml/class133125.html +++ b/doc/devel/uml/class133125.html @@ -16,7 +16,7 @@ -

Declaration :

Representation of a OpenGL accelerated Video render process

Artifact : glrender

+

Declaration :

  • C++ : class GLRender : public State

Representation of a OpenGL accelerated Video render process

Artifact : glrender

diff --git a/doc/devel/uml/class133765.html b/doc/devel/uml/class133765.html index af0e6bfb1..384101f0a 100644 --- a/doc/devel/uml/class133765.html +++ b/doc/devel/uml/class133765.html @@ -18,5 +18,6 @@

Declaration :

Source Node: represents a media source to pull data from.

Artifact : source

+

All public operations : pull

diff --git a/doc/devel/uml/class135045.html b/doc/devel/uml/class135045.html index 16259137b..a651d86b1 100644 --- a/doc/devel/uml/class135045.html +++ b/doc/devel/uml/class135045.html @@ -18,5 +18,6 @@

Declaration :

  • C++ : class CodecAdapter : public Trafo

Artifact : codecadapter

+

All public operations : pull

diff --git a/doc/devel/uml/class142085.html b/doc/devel/uml/class142085.html new file mode 100644 index 000000000..70fbc4c7b --- /dev/null +++ b/doc/devel/uml/class142085.html @@ -0,0 +1,22 @@ + + + + + + +Class StateProxy + + + + + +
Class StateProxy
+

+ + + + +

Declaration :

  • C++ : class StateProxy : public State
+
+ + diff --git a/doc/devel/uml/class142213.html b/doc/devel/uml/class142213.html new file mode 100644 index 000000000..a43acb9ac --- /dev/null +++ b/doc/devel/uml/class142213.html @@ -0,0 +1,27 @@ + + + + + + +Class StateAdapter + + + + + +
Class StateAdapter
+

+ + + + +

Declaration :

  • C++ : class StateAdapter : public State

lightweight value class used to manage the buffer associations for a single pull() call on a processing node

+ +
Operation pull

Declaration :

  • Uml : + pull(inout renderProcess : State) : void
  • C++ : public: void pull ()

trigger data processing by "pulling" results from the node's output

+
Operation retrieveBuffers

Declaration :

  • Uml : + retrieveBuffers(in requiredSource : vector<InputDescriptor> const) : void
  • C++ : public: void retrieveBuffers (const vector<InputDescriptor> const& requiredSource)

invoked from within the pull() - call of a node to set up the data buffers.
@param requiredSource descriptor denoting the predecessors and the frames required from them

+
Relation <unidirectional association>

Declaration :

+
Relation state (<unidirectional association>)

Declaration :

+

All public operations : pull , retrieveBuffers

+ + diff --git a/doc/devel/uml/class142341.html b/doc/devel/uml/class142341.html new file mode 100644 index 000000000..e9ac0ff67 --- /dev/null +++ b/doc/devel/uml/class142341.html @@ -0,0 +1,20 @@ + + + + + + +Class InputDescriptor + + + + + +
Class InputDescriptor
+

+ + + + +

Declaration :

  • C++ : class InputDescriptor

Artifact : procnode

+ diff --git a/doc/devel/uml/class142469.html b/doc/devel/uml/class142469.html new file mode 100644 index 000000000..9b6ed01a1 --- /dev/null +++ b/doc/devel/uml/class142469.html @@ -0,0 +1,20 @@ + + + + + + +Class caller + + + + + +
Class caller
+

+ + + + +

Declaration :

  • C++ : class caller
+ diff --git a/doc/devel/uml/class142597.html b/doc/devel/uml/class142597.html new file mode 100644 index 000000000..6465a8cd5 --- /dev/null +++ b/doc/devel/uml/class142597.html @@ -0,0 +1,20 @@ + + + + + + +Class Backend_Cache + + + + + +
Class Backend_Cache
+

+ + + + +

Declaration :

  • C++ : class Backend_Cache
+ diff --git a/doc/devel/uml/classdiagrams.html b/doc/devel/uml/classdiagrams.html index 4cf5416cc..c08c6d8a8 100644 --- a/doc/devel/uml/classdiagrams.html +++ b/doc/devel/uml/classdiagrams.html @@ -20,6 +20,7 @@ Automation Entities Builder Entities Controller Entities +Engine Details File MappingShows whats used to access Frames HierarchyLumiera Exception hierarchy In Memory Database diff --git a/doc/devel/uml/classes.html b/doc/devel/uml/classes.html index 23162b8f6..e1343f56e 100644 --- a/doc/devel/uml/classes.html +++ b/doc/devel/uml/classes.html @@ -26,10 +26,12 @@ AssetinterfaceSuperinterface describing especially the bookeeping properties of Assets AssetManagerboundaryFacade for the Asset subsystem AutoAutomation data for some parameter (i.e. a time varying function) +Backend_Cache Buildableinterface BuilderFacadeboundaryProvides unified access to the builder functionality. While individual components of the builder subsystem may be called if necessary or suitable, it is usually better to do all extern invocations via the high level methods of this Facade BuilderToolinterfaceUsed according to the visitor pattern: each Tool contains the concrete implementation for one task to be done to the various MObject classes BuildInstruct(Interface) building instructions to be executed by the Builder on the render node network under construction. +caller Categorytree like classification of Assets Clipbookkeeping (asset) view of a media clip. Clip @@ -74,6 +76,7 @@ GLPipespecialized connection node used to handle the transfer of OpenGL data from a image bitmap into texture form GLRenderRepresentation of a OpenGL accelerated Video render process Hub +InputDescriptor InterpolatorProvides the implementation for getting the acutal value of a time varying or automated effect/plugin parameter Invalid Label @@ -101,6 +104,7 @@ Prefetch Previewalternative version of the media data, probably with lower resolution Prockey abstraction: data processing asset +ProcDispatcher Processor ProcNodeinterfaceKey abstraction of the Render Engine: A Data processing Node ProcPattspecial type of structural Asset representing information how to build some part of the render engine's processing nodes network. @@ -122,8 +126,10 @@ SimpleClipElementary clip consisting of only one media stream SmartPointerauxiliary SourceSource Node: represents a media source to pull data from. +Stateinterface State -StateProxyinterface +StateAdapterlightweight value class used to manage the buffer associations for a single pull() call on a processing node +StateProxyimplementation std::exceptionauxiliary Structkey abstraction: structural asset ThreadWe can basically reuse the Thread class design from Cinelerra2, Thread becomes a baseclass for all Threads diff --git a/doc/devel/uml/classes_list.html b/doc/devel/uml/classes_list.html index 6f3005da9..153e47670 100644 --- a/doc/devel/uml/classes_list.html +++ b/doc/devel/uml/classes_list.html @@ -27,10 +27,12 @@ Asset
AssetManager
Auto
+Backend_Cache
Buildable
BuilderFacade
BuilderTool
BuildInstruct
+caller
Category
Clip
Clip
@@ -75,6 +77,7 @@ GLPipe
GLRender
Hub
+InputDescriptor
Interpolator
Invalid
Label
@@ -102,6 +105,7 @@ Prefetch
Preview
Proc
+ProcDispatcher
Processor
ProcNode
ProcPatt
@@ -123,8 +127,10 @@ SimpleClip
SmartPointer
Source
+State
State
-StateProxy
+StateAdapter
+StateProxy
std::exception
Struct
Thread
diff --git a/doc/devel/uml/collaborationdiagrams.html b/doc/devel/uml/collaborationdiagrams.html index 2d8ab627d..9090762bc 100644 --- a/doc/devel/uml/collaborationdiagrams.html +++ b/doc/devel/uml/collaborationdiagrams.html @@ -18,6 +18,7 @@ +
"default" object
build processThis figure shows the process of building and starting a RenderEngine
pull call
diff --git a/doc/devel/uml/fig128389.png b/doc/devel/uml/fig128389.png index c6a57b8573f2a2faab08cafe49d0c14ed5d6d60b..adc3952e4ac393a8b720975eb6ea80813e91c328 100644 GIT binary patch literal 31223 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 literal 0 HcmV?d00001 diff --git a/doc/devel/uml/index.html b/doc/devel/uml/index.html index bbecbcbc0..a054cc161 100644 --- a/doc/devel/uml/index.html +++ b/doc/devel/uml/index.html @@ -32,7 +32,7 @@ Documentation

provided classes : Error, Time

Component Builder
-

provided classes : StateProxy

+

provided classes : State

required classes : Fixture, SessionImpl

Component Session
@@ -54,9 +54,10 @@ Documentation
Component AssetManagement
Component Dispatcher
+

provided classes : ProcDispatcher

Component Engine
-

Depends on Frame (Stream) Provider

required classes : StateProxy

+

Depends on Frame (Stream) Provider

required classes : State

Component ProcNode
@@ -78,6 +79,9 @@ Documentation

required classes : MediaAccessFacade

Component AssetDB
+ +
Component client code
+

required classes : ProcDispatcher

1.2 Component View interfaces

@@ -112,7 +116,7 @@ Documentation
Artifact Lumiera

Depends on common

Depends on gui

Depends on proc

Depends on backend

the main executable to be built

-

executable associated with : aframe, assembler, trafo, explicitplacement, auto, glrender, link, parameter, renderengine, allocation, vframe, toolfactory, arender, renderstate, label, glbuf, procnode, stateproxy, hub, buildable, abstractmo, nodecreatertool, projector, interpolator, edl, fixture, glpipe, vrender, exitnode, pathmanager, track, paramprovider, mask, main, conmanager, clip, meta, fixedlocation, relativelocation, mobject, source, frame, placement, sessionimpl, builderfacade, controllerfacade, processor, pluginadapter, effect, buildertool, segmentationtool

+

executable associated with : placement, sessionimpl, builderfacade, controllerfacade, processor, pluginadapter, effect, buildertool, segmentationtool, aframe, assembler, trafo, explicitplacement, auto, glrender, link, parameter, renderengine, allocation, vframe, toolfactory, arender, renderstate, label, glbuf, procnode, stateproxy, hub, buildable, abstractmo, nodecreatertool, projector, interpolator, edl, fixture, glpipe, vrender, exitnode, pathmanager, track, paramprovider, mask, main, conmanager, clip, meta, fixedlocation, relativelocation, mobject, source, frame

Artifact main

Artifact source

@@ -192,7 +196,7 @@ Documentation
Artifact stateproxy

Key Interface representing a render process and encapsulating state

-

Artifact source associated with : StateProxy

+

Artifact source associated with : State

Artifact controllerfacade

Facade and service access point for the Proc Layer Controller

@@ -505,7 +509,7 @@ Documentation
Artifact procnode

Key abstraction of the Render Engine: a Processing Node

-

Artifact source associated with : ProcNode

+

Artifact source associated with : ProcNode, InputDescriptor

Artifact trafo

transforming processing Node

@@ -670,6 +674,7 @@ Documentation
+

2.2.2 Package Builder

@@ -759,7 +764,6 @@ Documentation
Class Assembler
-
Class Buildable
@@ -892,6 +896,27 @@ reuse exiting Engine

Selection :

    Transformation
    Class VFrame
    Class GLBuf
    Class Source
    + +

    +

    Engine Details



    +
    Class State
    +
    +
    +
    +
    + +

    2.3.3 Use Case View render process

    +
    + +

    +

    pull call



    + +
    Class instance

    type :StateAdapter

    +
    Class instance node1

    type :ProcNode

    +
    Class instance node2

    type :ProcNode

    +
    Class instance next_adapter

    type :StateAdapter

    +
    Class instance current_state

    type :StateProxy

    Class caller
    +
    diff --git a/doc/devel/uml/index_60.html b/doc/devel/uml/index_60.html index 4909e634c..8712d7074 100644 --- a/doc/devel/uml/index_60.html +++ b/doc/devel/uml/index_60.html @@ -17,8 +17,8 @@ - + @@ -28,8 +28,8 @@ - + diff --git a/doc/devel/uml/index_65.html b/doc/devel/uml/index_65.html index 3fce72879..c1c05066a 100644 --- a/doc/devel/uml/index_65.html +++ b/doc/devel/uml/index_65.html @@ -55,9 +55,9 @@ - - + + diff --git a/doc/devel/uml/index_66.html b/doc/devel/uml/index_66.html index 2d9540c91..592c6f15d 100644 --- a/doc/devel/uml/index_66.html +++ b/doc/devel/uml/index_66.html @@ -21,6 +21,7 @@ + @@ -34,8 +35,8 @@ - + diff --git a/doc/devel/uml/index_67.html b/doc/devel/uml/index_67.html index 08c04b765..996ed7eb6 100644 --- a/doc/devel/uml/index_67.html +++ b/doc/devel/uml/index_67.html @@ -19,6 +19,7 @@ + @@ -27,38 +28,40 @@ - - - - - - + + + + + + - - - - - - - + - - - - - + + - + + + + + + + + + + + + - + @@ -105,6 +108,7 @@ +
    NameKindDescription
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    <flow>transition
    aud_Aclass instance
    aud_aclass instance
    audioclass instance
    audio1class instance
    audio1class instance
    audio1class instance
    audio1class instance
    audio1class instance
    autoartifactMedia Object holding automation data
    AutoclassAutomation data for some parameter (i.e. a time varying function)
    Automation Entitiesclass diagram
    Backend Componentsclass view
    backend use casesuse case diagram
    backend-componentscomponent diagram
    Backend_Cacheclass
    BackendLayerpackage
    buildoperation
    build flowactivity diagram
    buildableartifactmarker interface denoting any MObject able to be treated by Tools
    buildEngineoperationMain Operation of the Builder: create a render engine for a given part of the timeline
    Buildercomponent
    Builderpackage
    builderpackagesourcecode package

    The Builder creating the Render Engine,
    located within the MObject Subsystem
    Builderpackage
    Builder Entitiesclass diagram
    Builder Workingsclass view
    BuilderFacadeclassProvides unified access to the builder functionality. While individual components of the builder subsystem may be called if necessary or suitable, it is usually better to do all extern invocations via the high level methods of this Facade
    NameKindDescription
    Cachecomponent
    Cachecomponent view
    callerclass
    categoryrelationprimary tree like classification of the asset
    Categoryclasstree like classification of Assets
    categoryartifacttree like classification of Assets
    chainoperationcreate and add another Placement for this media object, thus increasingly constraining the (possible) position of this object.
    checked_inrelationchecked_in objects are subject of cache aging and must be not in use
    checked_outrelationthis list keeps all mappings which are in use, and thus prevents them from Cache aging
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    class instanceclass instance
    clearoperationclear current session contents
    without resetting overall session config.
    Afterwards, the session will contain only one
    empty EDL, while all Assets are retained.
    client codecomponent
    Clipclassbookkeeping (asset) view of a media clip.
    clipartifactbookkeeping (asset) view of a media clip.
    clipartifacta Media Clip
    clipartifactbookkeeping (asset) view of a media clip.
    Clipclass
    clipsrelation
    Codecclassdescription of some media data decoder or encoder facility
    createClipoperationcreate a (possibly compound) Clip refering to this media, ready to be added to the EDL.
    currEDLoperationThe EDL currently in focus. In most cases, Session and EDL are almost the same, just EDL emphasizes the collection aspect. But generally (for larger editing projects) one Session can contain several EDLs, which may even be nested. At any given time, only one of these EDLs has focus and recieves the editing commands.
    currentrelationStandard access path to get at the current session via the Session Manager, which acts as a "PImpl" smart pointer
    current_stateclass instance
    currFramerelation
    diff --git a/doc/devel/uml/index_68.html b/doc/devel/uml/index_68.html index 90bc7ba4d..e9e768a1e 100644 --- a/doc/devel/uml/index_68.html +++ b/doc/devel/uml/index_68.html @@ -32,8 +32,8 @@ designpackage designpackageAll things concering the big picture.
    Not a real code package, rather a container for design drafts, specifications, decisions. detect Channelsuse case -determine Render Paramsexpansion region determine Render Paramsopaque activity action +determine Render Paramsexpansion region devnullclass instance Dispatchercomponent dispatchOpoperation diff --git a/doc/devel/uml/index_69.html b/doc/devel/uml/index_69.html index 6c17d406d..c9eb2c76d 100644 --- a/doc/devel/uml/index_69.html +++ b/doc/devel/uml/index_69.html @@ -18,20 +18,21 @@ - + - + + diff --git a/doc/devel/uml/index_70.html b/doc/devel/uml/index_70.html index 78b986b1b..f328ad207 100644 --- a/doc/devel/uml/index_70.html +++ b/doc/devel/uml/index_70.html @@ -34,8 +34,8 @@ - + diff --git a/doc/devel/uml/index_73.html b/doc/devel/uml/index_73.html index 798945020..fa68d81e1 100644 --- a/doc/devel/uml/index_73.html +++ b/doc/devel/uml/index_73.html @@ -20,9 +20,10 @@ - + + diff --git a/doc/devel/uml/index_77.html b/doc/devel/uml/index_77.html index e6d8e8031..1428ef6eb 100644 --- a/doc/devel/uml/index_77.html +++ b/doc/devel/uml/index_77.html @@ -33,8 +33,8 @@ - + diff --git a/doc/devel/uml/index_78.html b/doc/devel/uml/index_78.html index 1cf51971d..8afac3d9f 100644 --- a/doc/devel/uml/index_78.html +++ b/doc/devel/uml/index_78.html @@ -20,6 +20,9 @@ + + + diff --git a/doc/devel/uml/index_79.html b/doc/devel/uml/index_79.html index 4ac4c3b33..f63687c5b 100644 --- a/doc/devel/uml/index_79.html +++ b/doc/devel/uml/index_79.html @@ -19,9 +19,9 @@ - - + + diff --git a/doc/devel/uml/index_80.html b/doc/devel/uml/index_80.html index ba34ae763..83ab6f76d 100644 --- a/doc/devel/uml/index_80.html +++ b/doc/devel/uml/index_80.html @@ -40,6 +40,7 @@ + @@ -51,6 +52,7 @@ + @@ -62,6 +64,9 @@ + + +
    NameKindDescription
    edlartifactthe (high level) Edit Decision List within the current Session
    EDLclass
    EDLcomponent
    EDLclass
    EDL Example1object diagramA simple example showing how the actual objects are placed in the Fixture (=definitive playlist). It shows a Video and Audio clip placed on two tracks
    EDL Example2object diagramMore complex example showing the Object graph in the EDL and how it is linked into the Fixture to yield the actual locations. In this example, an HUE Effect is applied on a part of the Clip
    edlsrelation
    EffectclassEffect or media processing component
    effectartifactEDL representation of a pluggable and automatable effect.
    effectartifactEffect or media processing component
    effectartifactEDL representation of a pluggable and automatable effect.
    Effectclass
    elementsrelationrelevant MObjects comprising this segment. TODO: actually necessary??
    enableoperationchange the enabled status of this asset. Note the corresponding #isActive predicate may depend on the enablement status of parent assets as well
    endattributeend of the timerange (excl)
    Enginecomponent
    enginepackagesourcecode package

    The Core Render Engine
    Engine Detailsclass diagram
    Engine Example1object diagramExample1 (from EDL) continued: here the RenderEngine to be created by the Builder from the Input shown in Example1
    Engine Example2object diagramExample2 (from EDL) continued: notably in this RenderEngine the Effect has been partitioned into 2 segments with constant configuration.
    Engine Partsdeployment view
    FixedLocationclass
    Fixtureactivity object
    fixtureartifactthe (low level) representation of the EDL with concrete placement data
    Fixturecomponent
    Fixtureclass
    Fixturecomponent
    fork activity nodefork activity node
    FrameclassFrames are just a low level lump of continous memory, most parts are opaque. Frames are memory sensitive, they will be small constant sized structures which can be efficently managed in a pool.
    Framenode
    idattributeAsset primary key.
    In Memory Databaseclass diagram
    inFixtureactivity action pin
    inputclass instance
    inputclass instance
    inputclass instance
    inputclass instance
    InputDescriptorclass
    instanceoperation
    instructionsrelation
    Interfaceclass view
    MediaFactoryclassspecialized Asset Factory for configuring (new) media asset instances based on existing media files on disk; can create placeholder assets as well
    merge activity nodemerge activity node
    Metaclasskey abstraction: metadata and organisational asset
    metaartifactkey abstraction: metadata and organisational asset
    metaartifactabstract base class of all MObjects representing meta data or processing instructions
    metaartifactkey abstraction: metadata and organisational asset
    Metaclass
    mobjectartifactKey Abstraction: A Media Object in the Session
    mobjectpackagesourcecode package

    MObject Subsystem
    including the Session (EDL), Builder and Processing Controller
    nameattributeelement ID, comprehensible but sanitized. The tuple (category, name, org) is unique.
    need sub objectuse case
    nextrelationnext additional LocatingPin, if any
    next_adapterclass instance
    node1class instance
    node2class instance
    nodecreatertoolartifactcentral Tool implementing the Renderengine building
    NodeCreatorToolclassThis Tool implementation plays the central role in the buld process: given a MObject from Session, it is able to attach ProcNodes to the render engine under construction such as to reflect the properties of the MObject in the actual render.
    nodesrelation
    NameKindDescription
    offsetattributeOffset the actual position by this (time) value relative to the anchor point. TODO: Representation?
    orgattributeorigin or authorship id. Can be a project abbreviation, a package id or just the authors nickname or UID. This allows for the compnent name to be more generic (e.g. "blur"). Default for all assets provided by the core Lumiera codebase is "lumi".
    ouputclass instance
    ouputclass instance
    ouputclass instance
    ouputclass instance
    ouputclass instance
    outPortrelationthe Port this MObject wants to be conected to
    outputrelation
    Overviewcomponent diagramThis drawing shows the top level compoents and relations
    pnodenode
    pointattributeidentifying the point where the nodes should be attached
    Posix Threads Abstractionclass viewC++ wrapers for pthreads
    predecessorsrelationpreconfigured table of all predecessor nodes, qualified
    with the output port on these nodes and time offset of the data
    we need for doing our calculations
    predicate implclass instance
    Prefetchclass
    Previewclassalternative version of the media data, probably with lower resolution
    procattributeholds the Processor (Render Engine Element) to be built by the current build step
    Proc-Asset Relationsclass diagram
    proc-componentscomponent diagram
    ProcDispatcherclass
    ProcessingLayerpackage
    Processorclass
    processorartifacta single render pipeline for one segment of the timeline
    ProjectorclassSpecial video processing node used to scale and translate image data.
    projectorartifactvideo ProcNode for scaling and translating image data
    providerrelation
    pulloperationtrigger data processing by "pulling" results from the node's output
    pulloperationtrigger data processing by "pulling" results from the node's output
    pull callcollaboration diagram
    diff --git a/doc/devel/uml/index_82.html b/doc/devel/uml/index_82.html index 1bade53e8..c807e8ca4 100644 --- a/doc/devel/uml/index_82.html +++ b/doc/devel/uml/index_82.html @@ -22,10 +22,11 @@ registryrelation@internal Table or DB holding all registered asset instances. relativelocationartifactPlacement implemnetaion providing various ways of attaching a MObject to another one RelativeLocationclass -RelTypeclassthe possible kinds of RelativePlacements relTypeattributethe kind of relation denoted by this Placement +RelTypeclassthe possible kinds of RelativePlacements removeoperationremove the given asset <i>together with all its dependants</i> from the internal DB Render Entitiesclass diagram +render processuse case view Render Requestactivity parameter RenderEngineclass renderengineartifacta complete network of processing nodes usable for rendering @@ -42,6 +43,7 @@ resolveoperation Resolvercomponent ResolverBaseclass +retrieveBuffersoperationinvoked from within the pull() - call of a node to set up the data buffers.
    @param requiredSource descriptor denoting the predecessors and the frames required from them rootCauseoperationIf this exception was caused by a chain of further exceptions,
    return the first one registered in this throw sequence.
    This works only, if every exceptions thrown as a consequence
    of another exception is propperly constructed by passing
    the original exception to the constructor Rule Basecomponent Rules accessclass diagram diff --git a/doc/devel/uml/index_83.html b/doc/devel/uml/index_83.html index e2f2fcea3..2edde4200 100644 --- a/doc/devel/uml/index_83.html +++ b/doc/devel/uml/index_83.html @@ -32,8 +32,8 @@ Service Componentsclass view Sessioncomponent sessionartifactInterface: the session edited by the user -Sessionclass view sessionpackagesourcecode package

    Everything concerning the EDL and Session, within the MObject Subsystem +Sessionclass view SessionclassPrimary Interface for all editing tasks.
    The session contains defaults, all the assets being edited, and a set of EDL with the individual MObjects to be manipulated and rendered. Session structureclass diagram sessionimplartifactholds the complete session data to be edited by the user @@ -56,8 +56,11 @@ startattributebegin of the timerange covered by this processor startattribute Statenode +Stateclass Stateclass -StateProxyclass +staterelation +StateAdapterclasslightweight value class used to manage the buffer associations for a single pull() call on a processing node +StateProxyclass stateproxyartifactKey Interface representing a render process and encapsulating state std::exceptionclass Structclasskey abstraction: structural asset diff --git a/doc/devel/uml/index_84.html b/doc/devel/uml/index_84.html index 14d928057..bfcae496d 100644 --- a/doc/devel/uml/index_84.html +++ b/doc/devel/uml/index_84.html @@ -34,20 +34,20 @@ trackrelation trackattribute trackrelation -trackartifactA grouping device within the EDL. The corresponding Placement
    by which this Track object is refered defines fallback placing
    properties to be used by all objects placed on this track in
    case they don't specify more concrete placements.
    Typically, tracks are used do make default Port connections,
    define a layer or pan for sound and for for disabling groups
    of clips. Note tracks are grouped in a tree like fashion.
    trackartifactstructural asset holding the configuration of a track in the EDL +trackartifactA grouping device within the EDL. The corresponding Placement
    by which this Track object is refered defines fallback placing
    properties to be used by all objects placed on this track in
    case they don't specify more concrete placements.
    Typically, tracks are used do make default Port connections,
    define a layer or pan for sound and for for disabling groups
    of clips. Note tracks are grouped in a tree like fashion.
    Trackclass tracksrelationelementary media assets comprising this compound Trafoclass trafoartifacttransforming processing Node treatoperation treatoperationThis operation is to be overloaded for the specific MObject subclasses to be treated. -treatoperation treatoperation treatoperation treatoperation -treatoperation +treatoperation treatoperation +treatoperation treatoperation TypeHandlerclass TypeHandler<Pipe>class diff --git a/doc/devel/uml/index_86.html b/doc/devel/uml/index_86.html index e3c5f01a9..364ff0811 100644 --- a/doc/devel/uml/index_86.html +++ b/doc/devel/uml/index_86.html @@ -20,23 +20,23 @@ versionattributeversion number of the thing or concept represented by this asset. Of each unique tuple (name, category, org) there will be only one version in the whole system. Version 0 is reserved for internal purposes. Versions are considered to be ordered, and any higher version is supposed to be fully backwards compatible to all previous versions. VFrameclass vframeartifacta buffer and render process holding a Video frame -vid1class instance vid1class instance -vid_Aclass instance -vid_Aclass instance +vid1class instance vid_aclass instance -vid_aclass instance +vid_Aclass instance vid_Aclass instance -videoclass instance +vid_aclass instance +vid_Aclass instance videoclass instance -videoclass instance videoclass instance -video1class instance -video1class instance -video1class instance -video1class instance +videoclass instance +videoclass instance video1class instance +video1class instance +video1class instance video1class instance +video1class instance +video1class instance Visitableclass visitorpackagesub-namespace for visitor library implementation visitorartifactAcyclic Visitor library diff --git a/doc/devel/uml/public_operations.html b/doc/devel/uml/public_operations.html index 697d67b52..03a780210 100644 --- a/doc/devel/uml/public_operations.html +++ b/doc/devel/uml/public_operations.html @@ -51,11 +51,14 @@ loadSessManagerreplace the current session by a new
    session loaded from serialized state. makeTypeHandler playRenderEngineTODO: will probably be handled differently (see Cehteh) +pullProcNodetrigger data processing by "pulling" results from the node's output +pullStateAdaptertrigger data processing by "pulling" results from the node's output removeAssetManagerremove the given asset <i>together with all its dependants</i> from the internal DB resetSessManagerreset all session config and
    start with a pristine default session. resolvePlacementcreate an actual (explicit) placement while trying to satisfy the network of adjacent objects and placements. resolveQueryHandler resolveQueryHandlerImpl +retrieveBuffersStateAdapterinvoked from within the pull() - call of a node to set up the data buffers.
    @param requiredSource descriptor denoting the predecessors and the frames required from them rootCauseErrorIf this exception was caused by a chain of further exceptions,
    return the first one registered in this throw sequence.
    This works only, if every exceptions thrown as a consequence
    of another exception is propperly constructed by passing
    the original exception to the constructor saveSessManagercreate a complete, serialized representation
    of the current session config and contents.
    @todo how to serialize, prameters, return value? treatApplicable diff --git a/uml/lumiera/128389.diagram b/uml/lumiera/128389.diagram index 5a6ad5049..741cf9ff5 100644 --- a/uml/lumiera/128389.diagram +++ b/uml/lumiera/128389.diagram @@ -14,7 +14,7 @@ classcanvas 128389 class_ref 131589 // ExitNode end classcanvas 128517 class_ref 131717 // ProcNode draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 462 264 2000 + xyz 462 257 2000 end classcanvas 129029 class_ref 131845 // Trafo draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default @@ -44,7 +44,7 @@ classcanvas 129797 class_ref 132613 // GLPipe draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default xyz 699 531 2000 end -classcanvas 132229 class_ref 132741 // StateProxy +classcanvas 132229 class_ref 132741 // State draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default xyz 36 374 2000 end @@ -97,29 +97,29 @@ relationcanvas 128901 relation_ref 131973 // multiplicity_a_pos 414 419 3000 no_multiplicity_b relationcanvas 129925 relation_ref 132101 // geometry VHV - from ref 128389 z 1999 to point 445 384 - line 130693 z 1999 to point 499 384 + from ref 128389 z 1999 to point 445 387 + line 130693 z 1999 to point 499 387 line 130821 z 1999 to ref 128517 no_role_a no_role_b no_multiplicity_a no_multiplicity_b relationcanvas 130053 relation_ref 132229 // geometry VHV - from ref 129029 z 1999 to point 516 383 - line 130949 z 1999 to point 499 383 + from ref 129029 z 1999 to point 516 387 + line 130949 z 1999 to point 499 387 line 131077 z 1999 to ref 128517 no_role_a no_role_b no_multiplicity_a no_multiplicity_b relationcanvas 130181 relation_ref 132357 // geometry VHV - from ref 129285 z 1999 to point 613 384 - line 131205 z 1999 to point 499 384 + from ref 129285 z 1999 to point 613 387 + line 131205 z 1999 to point 499 387 line 131333 z 1999 to ref 128517 no_role_a no_role_b no_multiplicity_a no_multiplicity_b relationcanvas 130309 relation_ref 132485 // geometry VHV - from ref 129157 z 1999 to point 668 384 - line 131461 z 1999 to point 499 384 + from ref 129157 z 1999 to point 668 387 + line 131461 z 1999 to point 499 387 line 131589 z 1999 to ref 128517 no_role_a no_role_b no_multiplicity_a no_multiplicity_b @@ -179,14 +179,14 @@ relationcanvas 135429 relation_ref 134149 // no_role_a no_role_b no_multiplicity_a no_multiplicity_b relationcanvas 136965 relation_ref 134533 // - from ref 132229 z 1999 to point 306 465 + from ref 132229 z 1999 stereotype "<>" xyz 279 441 3000 to point 306 465 line 137093 z 1999 to ref 133765 role_a_pos 318 587 3000 no_role_b - no_multiplicity_a multiplicity_b_pos 124 427 3000 + multiplicity_a_pos 282 587 3000 multiplicity_b_pos 124 427 3000 relationcanvas 137349 relation_ref 134661 // geometry VHV - from ref 137221 z 1999 to point 763 384 - line 137477 z 1999 to point 499 384 + from ref 137221 z 1999 to point 763 387 + line 137477 z 1999 to point 499 387 line 137605 z 1999 to ref 128517 no_role_a no_role_b no_multiplicity_a no_multiplicity_b diff --git a/uml/lumiera/129285 b/uml/lumiera/129285 index 28f619bb6..7883c598c 100644 --- a/uml/lumiera/129285 +++ b/uml/lumiera/129285 @@ -1,6 +1,6 @@ format 40 "ProcessingLayer" // ProcessingLayer - revision 14 + revision 15 modified_by 5 "hiv" // class settings //class diagram settings diff --git a/uml/lumiera/131973.diagram b/uml/lumiera/131973.diagram new file mode 100644 index 000000000..9d11f2c5a --- /dev/null +++ b/uml/lumiera/131973.diagram @@ -0,0 +1,67 @@ +format 40 + +classcanvas 128005 class_ref 131717 // ProcNode + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 106 330 2004 + end +classcanvas 128517 class_ref 132741 // State + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 83 21 2000 + end +classcanvas 128645 class_ref 142085 // StateProxy + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 127 135 2000 + end +classcanvas 128773 class_ref 142213 // StateAdapter + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 36 216 2000 + end +classcanvas 129157 class_ref 142341 // InputDescriptor + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 183 446 2000 + end +classcanvas 129669 class_ref 133253 // Frame + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 267 221 3005 + end +relationcanvas 128901 relation_ref 148229 // + geometry VHV unfixed + from ref 128645 z 1999 to point 179 108 + line 131589 z 1999 to point 120 108 + line 131717 z 1999 to ref 128517 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 129029 relation_ref 148357 // + geometry VHV unfixed + from ref 128773 z 1999 to point 80 108 + line 131333 z 1999 to point 120 108 + line 131461 z 1999 to ref 128517 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 129285 relation_ref 148485 // + geometry HV + from ref 128005 z 1999 to point 228 367 + line 129541 z 1999 to ref 129157 + role_a_pos 240 421 3000 no_role_b + multiplicity_a_pos 216 421 3000 no_multiplicity_b +relationcanvas 129797 relation_ref 134533 // + from ref 128517 z 1999 to point 303 129 + line 130053 z 1999 stereotype "<>" xyz 248 128 3000 to ref 129669 + role_a_pos 312 194 3000 no_role_b + multiplicity_a_pos 281 158 3000 multiplicity_b_pos 171 82 3000 +relationcanvas 129925 relation_ref 148613 // + from ref 128773 z 1999 to ref 129669 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 130181 relation_ref 148741 // + from ref 128773 z 1999 to point 179 226 + line 130309 z 1999 to ref 128645 + role_a_pos 149 210 3000 no_role_b + no_multiplicity_a no_multiplicity_b +line 130437 -_-_ + from ref 128773 z 1999 to point 136 328 + line 130693 z 1999 to ref 128005 +line 130565 -_-_ + from ref 128773 z 1999 to ref 128005 +preferred_whz 414 544 1 +end diff --git a/uml/lumiera/132101.diagram b/uml/lumiera/132101.diagram new file mode 100644 index 000000000..39dd25211 --- /dev/null +++ b/uml/lumiera/132101.diagram @@ -0,0 +1,91 @@ +format 40 + +classinstancecanvas 128005 classinstance_ref 136069 // + xyz 144 217 2000 + end +classinstancecanvas 128133 classinstance_ref 136197 // node1 + xyz 169 309 2000 + end +classinstancecanvas 128261 classinstance_ref 136325 // node2 + xyz 485 277 2000 + end +classinstancecanvas 128389 classinstance_ref 136453 // next_adapter + xyz 388 216 2005 + end +classinstancecanvas 128901 classinstance_ref 136581 // current_state + xyz 114 20 2000 + end +classinstance 129285 class_ref 142469 // caller + name "" xyz 29 106 2000 +classinstance 129541 class_ref 142597 // Backend_Cache + name "" xyz 412 39 2000 +textcanvas 130565 "node1 using node2 as predecessor" + xyzwh 267 343 2000 133 24 +textcanvas 130693 "try to get frame from Cache first" + xyzwh 468 121 2000 89 43 +note 130821 "Triggered by pulling" + xyzwh 5 176 2005 118 38 +note 130949 "Buffers" + xyzwh 255 20 2005 61 35 +linkcanvas 128517 + from ref 128005 z 1999 to ref 128133 +dirscanvas 128645 z 1000 linkcanvas_ref 128517 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "2 pull()" xyz 217 255 3000 + backward_label "3 retrieveBuffers()" xyz 95 282 3000 +linkcanvas 128773 + from ref 128005 z 1999 to ref 128389 +dirscanvas 130053 z 1000 linkcanvas_ref 128773 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "4 create" xyz 281 192 3000 +linkcanvas 129029 + from ref 128005 z 1999 to ref 128901 +linkcanvas 129157 + from ref 128389 z 1999 to ref 128261 +dirscanvas 130309 z 1000 linkcanvas_ref 129157 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "6 pull()" xyz 515 246 3000 +linkcanvas 129413 + from ref 129285 z 1999 to ref 128005 +dirscanvas 129925 z 1000 linkcanvas_ref 129413 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "1 pull()" xyz 124 140 3000 +linkcanvas 129669 + from ref 128389 z 1999 to ref 129541 +dirscanvas 130181 z 1000 linkcanvas_ref 129669 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "5 try_fetch" xyz 386 132 3000 +linkcanvas 129797 + from ref 128005 z 1999 to ref 129541 +dirscanvas 130437 z 1000 linkcanvas_ref 129797 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "7 store" xyz 280 108 3000 +msgs + msg operation_ref 135685 // "pull(inout renderProcess : State) : void" + forward ranks 1 "1" dirscanvas_ref 129925 + msgs + msg operation_ref 135557 // "pull(inout renderProcess : State) : void" + forward ranks 2 "1.1" dirscanvas_ref 128645 + msgs + msg operation_ref 135813 // "retrieveBuffers(in requiredSource : vector const) : void" + backward ranks 3 "1.1.1" dirscanvas_ref 128645 + msgs + explicitmsg "create" + forward ranks 4 "1.1.1.1" dirscanvas_ref 130053 + msgs + explicitmsg "try_fetch" + forward ranks 5 "1.1.1.1.1" dirscanvas_ref 130181 + no_msg + msg operation_ref 135557 // "pull(inout renderProcess : State) : void" + forward ranks 6 "1.1.1.1.2" dirscanvas_ref 130309 + no_msg + msgsend + explicitmsg "store" + forward ranks 7 "1.1.1.2" dirscanvas_ref 130437 + no_msg + msgsend + msgsend + msgsend +msgsend +preferred_whz 599 408 1 +end diff --git a/uml/lumiera/5.session b/uml/lumiera/5.session index fc9677d8c..5f7a09a5a 100644 --- a/uml/lumiera/5.session +++ b/uml/lumiera/5.session @@ -1,14 +1,20 @@ window_sizes 1140 830 270 860 680 71 diagrams - active componentdiagram_ref 128005 // Overview - 702 640 80 4 2 0 + active collaborationdiagram_ref 132101 // pull call + 599 408 100 4 0 0 + classdiagram_ref 131973 // Engine Details + 414 544 100 4 0 0 + classdiagram_ref 128389 // Render Entities + 829 656 100 4 162 0 end show_stereotypes selected package_ref 129 // lumiera open - componentview_ref 128133 // interfaces - classview_ref 128005 // Session + + package_ref 128261 // MObject + classview_ref 128133 // Engine Workings + usecaseview_ref 128517 // render process class_ref 140677 // QueryHandler class_ref 140805 // TypeHandler class_ref 140933 // ResolverBase diff --git a/uml/lumiera/lumiera.prj b/uml/lumiera/lumiera.prj index dcdd63301..93cb8fa6f 100644 --- a/uml/lumiera/lumiera.prj +++ b/uml/lumiera/lumiera.prj @@ -1,6 +1,6 @@ format 40 "lumiera" - revision 44 + revision 45 modified_by 5 "hiv" cpp_root_dir "../../src/" diff --git a/wiki/renderengine.html b/wiki/renderengine.html index be449639b..09256ec75 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -556,10 +556,11 @@ is how to implement the relationship between [[MObject]]s and Assets. Do we use
    -
    +
    Assets are created by a Factories returning smart pointers; the Asset creation is bound to specific use cases and //only available// for these specific situations. There is no generic Asset Factory.
     
    -For every Asset we generate a __Ident tuple__ and a long ID (hash) derived from this Ident tuple. The constructor of the abstract base class {{{Asset}}} takes care of this step and automatically registeres the new Asset object with the AssetManager. Typically, the factory methods for concrete Asset classes provide some shortcuts providing sensible default values for some of the Ident tuple data fields. They may take additional parameters &mdash; for example the factory method for creating {{{asset::Media}}} takes a filename (and may at some point in the future aply "magic" based on examination of the file)
    +For every Asset we generate a __Ident tuple__ and a long ID (hash) derived from this Ident tuple. The constructor of the abstract base class {{{Asset}}} takes care of this step and automatically registeres the new Asset object with the AssetManager. Typically, the factory methods for concrete Asset classes provide some shortcuts providing sensible default values for some of the Ident tuple data fields. They may take additional parameters &mdash; for example the factory method for creating {{{asset::Media}}} takes a filename (and may at some point in the future aply "magic" based on examination of the file &rarr; LoadingMedia) +
    The Asset Manager provides an Interface to some internal Database holding all Assets in the current Session and System state. It may be a real Database at some point (and for the moment it's a Hashtable). Each [[Asset]] is registered automatically with the Asset Manager; it can be queried either by it's //identification tuple// or by it's unique ID.
    @@ -752,12 +753,12 @@ Note, //we still have to work out how exactly building, rendering and playback w [img[Colaborations in the Build Process|uml/fig128517.png]]
    -
    +
    Actually setting up and wiring a [[processing node|ProcNode]] involves several issues and is carried out at the lowest level of the build process.
    -It is closely related to &rarr; [[the way nodes are operated|NodeOperationProtocol]]
    +It is closely related to &rarr; [[the way nodes are operated|NodeOperationProtocol]] and the &rarr; [[mechanics of the render process|RenderMechanics]]
     
     !!!object creation
    -The Nodes are small polymorphic objects, carrying configuration data, but no state. They are [[specially allocated|ManagementRenderNodes]], and the object creation is accessible solely by the NodeFactory. They //must not be deallocated manually.// The decision of what concrete node type to create depends on the actual build situation and is worked out by the combination of [[mould|BuilderMould]] and [[processing pattern|ProcPatt]] at the current OperationPoint, issuing a call to one of NodeFactory's {{{operator()}}}
    +The Nodes are small polymorphic objects, carrying configuration data, but no state. They are [[specially allocated|ManagementRenderNodes]], and the object creation is accessible by means of the NodeFactory solely. They //must not be deallocated manually.// The decision of what concrete node type to create depends on the actual build situation and is worked out by the combination of [[mould|BuilderMould]] and [[processing pattern|ProcPatt]] at the current OperationPoint, issuing a call to one of NodeFactory's {{{operator()}}}
     
     !!!node, plugin and processing function
     Its a good idea to distinguish clearly between those concepts. A plugin is a piece of (possibly external) code we use to carry out operations. We have to //discover its properties and capabilities.// We don't have to discover anything regarding nodes, because we (Lumiera builder and renderengine) are creating, configuring and wiring them to fit the specific purpose. Both are to be distinguished from processing functions, which do the actual calculations on the media data. Every node typically encompasses at least one processing function, which may be an internal function in the node object, a library function from Lumiera or GAVL, or external code loaded from a plugin.
    @@ -880,12 +881,12 @@ While building, the application of such a visiting tool (especially the [[NodeCr
     
     
    -
    +
    Besides the primary working tool within the builder (namely the [[Node Creator Tool|PlanningNodeCreatorTool]]), on a lower level, we encounter several [[elementary building situations|BuilderPrimitives]] &mdash; and for each of these elementary situations we can retrieve a suitable "fitting tool" or [[mould|BuilderMould]]. The palette of these moulds is called the ''tool kit'' of the builder. It is subject to configuration by rules.
     
     
     !!addressing a mould
    -All mould instances are owned and managed by the [[tool factory|BuilderToolFactory]], and can be referred to by their type ({{{PipeMould}}}, {{{CombiningMould}}}, {{{SourceChainMould}}}, {{{WiringMould}}}) and a concrete object instance (of suitable type). The returned mould (instance) acts as a handle to stick together the given object instance (from the high-level model) with the corresponding point in the low-level node network under construction. As consequence of this approach, the tool factory instance holds a snapshot of the current building state, including all the active spots in the build process. As the latter is driven by objects from the high-level model appearing (in a sensible order &rarr; see BuilderMechanics) within the NodeCreatorTool, new moulds will be created and fitted as necessary, and existing moulds will be exhausted when finished, until the render node network is complete.
    +All mould instances are owned and managed by the [[tool factory|BuilderToolFactory]], and can be referred to by their type (PipeMould, CombiningMould, SourceChainMould, WiringMould) and a concrete object instance (of suitable type). The returned mould (instance) acts as a handle to stick together the given object instance (from the high-level model) with the corresponding point in the low-level node network under construction. As consequence of this approach, the tool factory instance holds a snapshot of the current building state, including all the active spots in the build process. As the latter is driven by objects from the high-level model appearing (in a sensible order &rarr; see BuilderMechanics) within the NodeCreatorTool, new moulds will be created and fitted as necessary, and existing moulds will be exhausted when finished, until the render node network is complete.
     
     !!configuring a mould
     As each mould kind is different, it has a {{{prepare(...)}}} function with suitably typed parameters. The rest is intended to be  self-configuring (for example, a ~CombiningMould will detect the actual kind of Transition and select the internal mode of operation), so that it's sufficient to just call {{{operate()}}}
    @@ -1007,7 +1008,7 @@ This is an very important external Interface, because it links together all thre
     
    [[ProcLayer and Engine]]
     
    -
    +
    As detailed in the [[definition|DefaultsManagement]], {{{default(Obj)}}} is sort of a Joker along the lines "give me a suitable Object and I don't care for further details". Actually, default objects are implemented by the {{{mobject::session::DefsManager}}}, which remembers and keeps track of anything labeled as "default". This defaults manager is a singleton and can be accessed via the [[Session]] interface, meaning that the memory track regarding defaults is part of the session state. Accessing an object via the query for an default actually //tagges// this object (storing a weak ref in the ~DefsManager). Alongside with each object successfully queried via "default", the degree of constriction is remembered, i.e. the number of additional conditions contained in the query. This enables us to search for default objects starting with the most unspecific.
     
     !Skeleton
    @@ -1027,7 +1028,7 @@ Taken precisely, the "degree of constriction" yields only a partial or
     {{red{WARN}}} there is an interference with the (planned) Undo function. This is a general problem of the config queries; just ignoring this issue seems reasonable.
     
     !!!Problems with the (preliminary) mock implementation
    -As we don't have a Prolog interpreter on board yet, we utilize a mock store with preconfigured answers. (see {{{MockConfigQuery}}}). As this preliminary solution is lacking the ability to create new objects, we need to resort to some trickery here (please look away). The overall logic is quite broken, because the system isn't capable to do any real resolution &mdash; if we ignore this fact, the rest of the algorithm can be implemented, tested and used right now.
    +As we don't have a Prolog interpreter on board yet, we utilize a mock store with preconfigured answers. (see MockConfigQuery). As this preliminary solution is lacking the ability to create new objects, we need to resort to some trickery here (please look away). The overall logic is quite broken, because the system isn't capable to do any real resolution &mdash; if we ignore this fact, the rest of the algorithm can be implemented, tested and used right now.
     
    @@ -1306,7 +1307,7 @@ For this Lumiera design, we could consider making GOP just another raw media dat &rarr;see in [[Wikipedia|http://en.wikipedia.org/wiki/Group_of_pictures]]
    -
    +
    This wiki page is the entry point to detail notes covering some technical decisions, details and problems encountered in the course of the implementation of the Lumiera Renderengine, the Builder and the related parts.
     
     * [[Packages, Interfaces and Namespaces|InterfaceNamespaces]]
    @@ -1323,6 +1324,7 @@ For this Lumiera design, we could consider making GOP just another raw media dat
     * [[integrating the Config Query system|ConfigQueryIntegration]]
     * [[identifying the basic Builder operations|BasicBuildingOperations]] and [[planning the Implementation|PlanningNodeCreatorTool]]
     * [[how to handle »attached placement«|AttachedPlacementProblem]]
    +* working out the [[basic building situations|BuilderPrimitives]] and [[mechanics of rendering|RenderMechanics]]
     
    @@ -1679,7 +1681,7 @@ From experiences with other middle scale projects, I prefer having the test code [img[Example: Interfaces/Namespaces of the ~Session-Subsystems|uml/fig130053.png]]
    -
    +
    Opening and accessing media files on disk poses several problems, most of which belong to the domain of Lumiera's data backend. Here, we focus on the questions related to making media data available to the EDL and the render engine. Each media will be represented by an MediaAsset object, which indeed could be a compound object (in case of MultichannelMedia). Building this asset object thus includes getting informations from the real file on disk. For delegating this to the backend, we use the following query interface:
     * {{{queryFile(char* name)}}} requests accessing the file and yields some (opaque) handle when successful.
     * {{{queryChannel(fHandle, int)}}} will then be issued in sequence with ascending index numbers, until it returns {{{NULL}}}.
    @@ -1690,7 +1692,9 @@ From experiences with other middle scale projects, I prefer having the test code
     
     {{red{to be defined in more detail later...}}}
     
    -{{red{how to create a test stub for this interface...?}}}
    +&rarr; see "~MediaAccessFacade" for a (preliminary) interface definitioin +&rarr; see "~MediaAccessMock" for a mock/test implementaion +
    Used to actually implement the various kinds of [[Placement]] of ~MObjects. ~LocatingPin is the root of a hierarchy of different kinds of placing, constraining and locating a Media Object. Basically, this is an instance of the ''state pattern'': The user sees one Placement object with value semantics, but when the properties of the Placement are changed, actually a ~LocatingPin object (or rather a chain of ~LocatingPins) is changed within the Placement. Subclasses of ~LocatingPin implement different placing/constraining behaviour:
    @@ -1762,9 +1766,11 @@ __5/2008__: the allocation mechanism can surely be improved later, but for now I
     
     <style type="text/css">#contentWrapper {display:none;}</style><div id="SplashScreen" style="border: 3px solid #ccc; display: block; text-align: center; width: 320px; margin: 100px auto; padding: 50px; color:#000; font-size: 28px; font-family:Tahoma; background-color:#eee;">loading <b>Proc-Layer</b> devel doku<blink> ...</blink><br><br><span style="font-size: 14px; color:red;">Requires Javascript.</span></div>
    -
    +
    The Interface asset::Media is a //key abstraction// It ties together several concepts and enables to deal with them on the interfaces in a uniform manner. Besides, as every Asset kind it belongs rather to the bookkeeping view: an asset::Media holds the specific properties and parametrisation of the media source it stands for. Regarding the __inward interface__ &mdash; as used from within the [[EDL]] or the [[Render Nodes|ProcNode]], it is irrelevant if any given asset::Media object stands for a complete media source, just a clip taken from this source or if a placeholder version of the real media source is used instead.
     [img[Asset Classess|uml/fig130437.png]]
    +
    +&rarr; see also LoadingMedia
     
    @@ -1824,12 +1830,12 @@ So, when creating a clip out of such a compound media asset, the clip has to be
    NodeCreaterTool is a [[visiting tool|VisitorUse]] used as second step in the [[Builder]]. Starting out from a [[Fixture]], the builder first [[divides the Timeline into segments|SegmentationTool]] and then processes each segment with the NodeCreaterTool to build a render nodes network (Render Engine) for this part of the timeline. While visiting individual Objects and Placements, the NodeCreaterTool creates and wires the necessary [[nodes|ProcNode]]
    -
    +
    The [[nodes|ProcNode]] are wired to form a "Directed Acyclic Graph"; each node knows its predecessor(s), but not its successor(s).  The RenderProcess is organized according to the ''pull principle'', thus we find an operation {{{pull()}}} at the core of this process. There is no such thing as an "engine object" calling nodes iteratively or table driven, rather, the nodes themselves issue recursive calls to their predecessor(s). For this to work, we need the nodes to adhere to a specific protocol:
    -# Node is pulled, providing a StateProxy object (encapsulating the access to the frames or buffers)
    +# Node is pulled, with a StateProxy object as parameter (encapsulating the access to the frames or buffers)
     # Node may now access current parameter values, using the state accessible via the StateProxy
    -# Node calles back into the StateProxy, providing the //input descriptor//
    -# StateProxy tries to get the input frames from the Cache in the Backend. If this fails, it forwards the call using the information in the input descriptor
    +# Node calles back into the StateProxy for getting the input buffer(s), providing it's //input descriptor//
    +# StateProxy tries to get the input frames from the Cache in the Backend. In case of failure, the call is forwarded according to the input descriptor
     # after this call returns, the Node is allowed to dereference the frame pointers and do its calculations
     # finally, when the {{{pull()}}} call returns, the StateProxy may push down the result frames to the cache
     some points to note:
    @@ -1839,7 +1845,7 @@ some points to note:
     * generally, a node may have N inputs and M output frames, which are expected to be processed in a single call
     
    -
    +
    We have to consider carefully how to handle the Creation of new class instances. Because, when done naively, it can defeat all efforts of separating subsystems, or &mdash; the other extreme &mdash; lead to a //switch-on-typeID//  programming style. We strive at a solution somewhere in the middle by utilizing __Abstract Factories__ on Interface or key abstraction classes, but providing specialized overloads for the different use cases. So in each use case we have to decide if we want to create a instance of some general concept (Interface), or if we have a direct collaboration and thus need the Factory to provide a more specific sub-Interface or even a concrete type.
     
     !Object creation use cases
    @@ -1850,7 +1856,8 @@ some points to note:
     |mark selection as clip|asset::Clip, session::Clip, Placement with unspec. LocatingPin| doesn't add to EDL|
     |loading Plugin|asset::Effect| usually at program startup|
     |create Session|asset::Track, asset::Pipe| |
    -&rarr; [[Creating and registering Assets|AssetCreation]]
    +&rarr; [[creating and registering Assets|AssetCreation]]
    +&rarr; [[loading media|LoadingMedia]]
     
     !![[MObjects|MObject]]
     |add media to EDL|asset::Clip, session::Clip, Placement with unspecified LocatingPin| creating whole-media clip on-the-fly |
    @@ -2628,11 +2635,11 @@ We need a way of addressing existing [[pipes|Pipe]]. Besides, as the Pipes and T
     //Note, we have yet to specify how exactly the building and rendering will work together with the backend. There are several possibilities how to structure the Playlist//
     
    -
    +
    Open issues, Things to be worked out, Problems still to be solved... 
     
     !!Parameter Handling
    -The requirements are not quite clear; obviously Parameters are the foundation for getting automation right and for providing effect editing interfaces, so it seems to me we need some sort of introspection, i.e. Parameters need to be discovered, enumerated and described at runtime.
    +The requirements are not quite clear; obviously Parameters are the foundation for getting automation right and for providing effect editing interfaces, so it seems to me we need some sort of introspection, i.e. Parameters need to be discovered, enumerated and described at runtime. (&rarr; see [[tag:automation|automation]])
     
     ''Automation Type'': Directly connected is the problem of handling the //type// of parameters sensible, including the value type of automation data. My first (somewhat naive) approach was to "make everything a double". But this soon leads into quite some of the same problems haunting the automation solution implemented in the current Cinelerra codebase. What makes the issue difficult is the fact we both need static diversity as well as dynamic flexibility. Usually, when combining hierarchies and templates, one has to be very careful; so I just note the problem down at the moment and will revisit it later, when I have a more clear understanding of the demands put onto the [[ProcNode]]s
     
    @@ -3019,12 +3026,35 @@ At first sight the link between asset and clip-MO is a simple logical relation b
     [img[Entities comprising the Render Engine|uml/fig128389.png]]
     
    -
    +
    +
    While with respect to the dependencies, the builder and the processing function, the render process is sufficiently characterized by referring to the ''pull principle'' and by defining a [[protocol|NodeOperationProtocol]] each node has to adhere to &mdash; for actually make it happen we have to care for some important details, especially //how to manage the buffers.// It may well be that the length of the code path necessary to invoke the individual processing functions is finally not so important, compared with the time spent within the inner pixel loop of these functions. But my guess is (as of 5/08), that the number of data moving and copying operations //will be//&nbsp; of importance.
    +
    +!reguirements
    +* operations should be "in place" as much as possible
    +* because caching necessitates a copy, the points where this happens should be controllable.
    +* buffers should accommodate automatically to provide the necessary space without clipping the image.
    +* the type of the media data can change while passing through the network, and so does the type of the buffers.
    +On the other hand, the processing function within the individual node needs to be shielded from these complexities. It can expect to get just //N~~I~~// input buffers and //N~O~// output buffers of required type. And, moreover, as the decision how to organize the buffers certainly depends on non-local circumstances, it should be preconfigured while building.
    +
    +!data flow
    +[>img[uml/fig131973.png]]
    +Not everything can be preconfigured though. The pull principle opens the possibility for the node to decide on a per call base what predecessor(s) to pull (if any). This decision may rely on automation parameters, which thus need to be accessible prior to 
    +requesting the buffer(s). Additionally, in a later version we plan to have the node network calculate some control values for adjusting the cache and backend timings &mdash; and of course at some point we'll want to utilize the GPU, resulting in the need to feed data from our processing buffers into some texture representation.
    +
    +!buffer management
    +Besides the StateProxy representing the actual render process and holding a couple of buffer (refs), we employ a lightweight adapter object in between. It is used //for a single {{{pull()}}}-call// &mdash; mapping the actual buffers to the input and output port numbers of the processing node and for dealing with the cache calls. While the StateProxy manages a pool of frame buffers, this interspersed adapter allows us to either use a buffer retrieved from the cache as an input, possibly use a new buffer located within the cache as output, or (in case no caching happens) to just use the same buffer as input and output for "in-place"-processing. The idea is that most of the configuration of this adapter object is prepared in the wiring step while building the node network. 
    +@@clear(right):display(block):@@
    +
    +
    +
    For each segment (of the effective timeline), there is a Processor holding the exit node(s) of a processing network, which is a "Directed Acyclic Graph" of small, preconfigured, stateless [[processing nodes|ProcNode]]. This network is operated according to the ''pull principle'', meaning that the rendering is just initiated by "pulling" output from the exit node, causing a cascade of recursive downcalls. Each node knows its predecessor(s) an can pull the necessary input from there. Consequently, there is no centralized "engine object" which may invoke nodes iteratively or table driven &mdash; rather, the rendering can be seen as a passive service provided for the backend, which may pull from the exit nodes at any time, in any order (?), and possibly multithreaded.
    -All State necessary for a given calculation process is encapsulated and accessible by a StateProxy object, which can be seen as the representation of "the process". At the same time, this proxy acts as a gateway to the backend to handle the communication with the Cache.
    +All State necessary for a given calculation process is encapsulated and accessible by a StateProxy object, which can be seen as the representation of "the process". At the same time, this proxy provides the buffers holding data to be processed and acts as a gateway to the backend to handle the communication with the Cache.
    +
     {{red{TODO: fill in more details of the Render Process.}}}
    +[img[uml/fig132101.png]]
     * see also
     &rarr; the [[Entities involved in Rendering|RenderEntities]]
    +&rarr; the [[mechanics of rendering and buffer management|RenderMechanics]]
     &rarr; the protocol [[how to operate the nodes|NodeOperationProtocol]]
     
    @@ -3338,8 +3368,8 @@ h1,h2,h3,h4,h5,h6 { /*}}}*/
    -
    -
    <<timeline better:true maxDays:55 maxEntries:30>>
    +
    +
    <<timeline better:true maxDays:55 maxEntries:45>>
    /***
    @@ -4420,10 +4450,10 @@ Using transitions is a very basic task and thus needs viable support by the GUI.
     Because of this experience, ichthyo wants to support a more general case of transitions, which have N output connections, behave similar to their "simple" counterpart, but leave out the mixing step. As a plus, such transitions can be inserted at the source ports of N clips or between any intermediary or final output pipes as well. Any transition processor capable of handling this situation should provide some flag, in order to decide if he can be placed in such a manner. (wichin the builder, encountering a  inconsistently placed transition is just an [[building error|BuildingError]])
     
    -
    +
    A ''~Meta-Clip'' or ''Virtual Clip'' (both are synonymous) denotes a clip which doesn't just pull media streams out of a source media asset, but rather provides the results of rendering a complete sub-network. In all other respects it behaves exactly like a "real" clip, i.e. it has [[source ports|ClipSourcePort]], can have attached effects (thus forming a local render pipe) and can be placed and combined with other clips. Depending on what is wired to the source ports, we get two flavours:
    -* a __placeholder clip__ has no "embedded" content. Rather, by virtue of placements and wiring requests, the output of some other pipe somewhere in the session will be wired to the clip's source ports. Thus, pulling data from this clip will effectively pull from these source pipes wired to it.
    -* a __nested EDL__ is like the other ~EDLs in the Session, just that any missing placement properties will be derived from the Virtual Clip, which is thought as to "contain" the objects of the nested EDL. Typically, you'd also [[configure the tracks|TrackHandling]] of the "inner" EDL such as to connect any output to the source ports of the Virtual Clip.
    +* a __placeholder clip__; has no "embedded" content. Rather, by virtue of placements and wiring requests, the output of some other pipe somewhere in the session will be wired to the clip's source ports. Thus, pulling data from this clip will effectively pull from these source pipes wired to it.
    +* a __nested EDL __ is like the other ~EDLs in the Session, just that any missing placement properties will be derived from the Virtual Clip, which is thought as to "contain" the objects of the nested EDL. Typically, you'd also [[configure the tracks|TrackHandling]] of the "inner" EDL such as to connect any output to the source ports of the Virtual Clip.
     
     Like any "real" clip, Virtual Clips have a start offset and a length, which will simply translate into an offset of the frame number pulled from the Virtual Clip's source connection or embedded EDL, making it possible to cut, splice, trim and roll them as usual. This of course implies we can have several instances of the same virtual clip with different start offset and length placed differently. The only limitation is that we can't handle cyclic dependencies for pulling data (which has to be detected and flagged as an error by the builder)
     
    From e8378485cc5e5f48c97813ffce9fcdcd9b070b2f Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Wed, 11 Jun 2008 05:44:10 +0200 Subject: [PATCH 05/12] planning the buffer management and render mechanics more precisely --- doc/devel/uml/class131589.html | 2 +- doc/devel/uml/class131717.html | 9 +- doc/devel/uml/class131845.html | 2 +- doc/devel/uml/class131973.html | 2 +- doc/devel/uml/class132101.html | 2 +- doc/devel/uml/class132229.html | 2 +- doc/devel/uml/class132357.html | 2 +- doc/devel/uml/class132485.html | 2 +- doc/devel/uml/class132613.html | 2 +- doc/devel/uml/class132741.html | 9 +- doc/devel/uml/class132869.html | 1 + doc/devel/uml/class132997.html | 1 + doc/devel/uml/class133125.html | 1 + doc/devel/uml/class133765.html | 2 +- doc/devel/uml/class135045.html | 2 +- doc/devel/uml/class142213.html | 27 --- doc/devel/uml/class142469.html | 9 +- doc/devel/uml/class142597.html | 12 +- .../{class142341.html => class142725.html} | 4 +- .../{class142085.html => class143109.html} | 10 +- doc/devel/uml/class143237.html | 20 ++ doc/devel/uml/classdiagrams.html | 2 +- doc/devel/uml/classes.html | 10 +- doc/devel/uml/classes_list.html | 10 +- doc/devel/uml/collaborationdiagrams.html | 2 +- doc/devel/uml/fig131973.png | Bin 16309 -> 18410 bytes doc/devel/uml/fig132101.png | Bin 18071 -> 0 bytes doc/devel/uml/fig132229.png | Bin 0 -> 36167 bytes doc/devel/uml/index.html | 46 +++-- doc/devel/uml/index_60.html | 4 +- doc/devel/uml/index_65.html | 10 +- doc/devel/uml/index_66.html | 2 +- doc/devel/uml/index_67.html | 43 ++-- doc/devel/uml/index_69.html | 5 +- doc/devel/uml/index_70.html | 1 + doc/devel/uml/index_73.html | 3 +- doc/devel/uml/index_78.html | 4 +- doc/devel/uml/index_79.html | 2 +- doc/devel/uml/index_80.html | 7 +- doc/devel/uml/index_82.html | 8 +- doc/devel/uml/index_83.html | 10 +- doc/devel/uml/index_84.html | 4 +- doc/devel/uml/index_86.html | 20 +- doc/devel/uml/public_operations.html | 14 +- uml/lumiera/128389 | 141 +++++++++++++- uml/lumiera/128901 | 65 ++++++- uml/lumiera/129285 | 89 ++++++++- uml/lumiera/131973.diagram | 98 +++++----- uml/lumiera/132101.diagram | 91 --------- uml/lumiera/132229.diagram | 184 ++++++++++++++++++ uml/lumiera/5.session | 18 +- uml/lumiera/lumiera.prj | 2 +- wiki/renderengine.html | 59 ++++-- 53 files changed, 749 insertions(+), 328 deletions(-) delete mode 100644 doc/devel/uml/class142213.html rename doc/devel/uml/{class142341.html => class142725.html} (84%) rename doc/devel/uml/{class142085.html => class143109.html} (64%) create mode 100644 doc/devel/uml/class143237.html delete mode 100644 doc/devel/uml/fig132101.png create mode 100644 doc/devel/uml/fig132229.png delete mode 100644 uml/lumiera/132101.diagram create mode 100644 uml/lumiera/132229.diagram diff --git a/doc/devel/uml/class131589.html b/doc/devel/uml/class131589.html index beefcf13d..86ae3636b 100644 --- a/doc/devel/uml/class131589.html +++ b/doc/devel/uml/class131589.html @@ -18,6 +18,6 @@

    Declaration :

    The output of the render pipeline. Pulling from such exit nodes actually ivokes the render process

    Artifact : exitnode

    -

    All public operations : pull

    +

    All public operations : process , pull

    diff --git a/doc/devel/uml/class131717.html b/doc/devel/uml/class131717.html index 8952f6f05..93a92a0b1 100644 --- a/doc/devel/uml/class131717.html +++ b/doc/devel/uml/class131717.html @@ -20,9 +20,10 @@

    Key abstraction of the Render Engine: A Data processing Node

    Artifact : procnode

    Relation datasrc (<unidirectional association>)

    Declaration :

    The predecessor in a processing pipeline, i.e. a source to get data to be processed

    -
    Relation params (<directional aggregation by value>)

    Declaration :

    -
    Operation pull

    Declaration :

    • Uml : + pull(inout renderProcess : State) : void
    • C++ : public: void pull ()

    trigger data processing by "pulling" results from the node's output

    -
    Relation predecessors (<directional aggregation by value>)

    Declaration :

    preconfigured table of all predecessor nodes, qualified
    with the output port on these nodes and time offset of the data
    we need for doing our calculations

    -

    All public operations : pull

    +
    Relation params (<directional aggregation by value>)

    Declaration :

    +
    Relation predecessors (<directional aggregation by value>)

    Declaration :

    +
    Operation pull

    Declaration :

    • Uml : + pull() :
    • C++ : public: pull ()
    +
    Operation process

    Declaration :

    • Uml : + process() :
    • C++ : public: process ()
    +

    All public operations : process , pull

    diff --git a/doc/devel/uml/class131845.html b/doc/devel/uml/class131845.html index c59787b25..1a439ca08 100644 --- a/doc/devel/uml/class131845.html +++ b/doc/devel/uml/class131845.html @@ -19,6 +19,6 @@

    Declaration :

    Directly inherited by : CodecAdapter Mask PluginAdapter Projector

    Artifact : trafo

    -

    All public operations : pull

    +

    All public operations : process , pull

    diff --git a/doc/devel/uml/class131973.html b/doc/devel/uml/class131973.html index 82d637b48..0ed7acaef 100644 --- a/doc/devel/uml/class131973.html +++ b/doc/devel/uml/class131973.html @@ -19,6 +19,6 @@

    Declaration :

    Directly inherited by : GLPipe

    Artifact : link

    -

    All public operations : pull

    +

    All public operations : process , pull

    diff --git a/doc/devel/uml/class132101.html b/doc/devel/uml/class132101.html index 50eae3f1b..f385d98c0 100644 --- a/doc/devel/uml/class132101.html +++ b/doc/devel/uml/class132101.html @@ -18,6 +18,6 @@

    Declaration :

    Artifact : hub

    -

    All public operations : pull

    +

    All public operations : process , pull

    diff --git a/doc/devel/uml/class132229.html b/doc/devel/uml/class132229.html index 28f198354..8fc999275 100644 --- a/doc/devel/uml/class132229.html +++ b/doc/devel/uml/class132229.html @@ -18,6 +18,6 @@

    Declaration :

    • C++ : class Projector : public Trafo

    Special video processing node used to scale and translate image data.

    Artifact : projector

    -

    All public operations : pull

    +

    All public operations : process , pull

    diff --git a/doc/devel/uml/class132357.html b/doc/devel/uml/class132357.html index 9dab6ff1f..1b054fe8f 100644 --- a/doc/devel/uml/class132357.html +++ b/doc/devel/uml/class132357.html @@ -18,6 +18,6 @@

    Declaration :

    • C++ : class Mask : public Trafo

    Artifact : mask

    -

    All public operations : pull

    +

    All public operations : process , pull

    diff --git a/doc/devel/uml/class132485.html b/doc/devel/uml/class132485.html index 2ccb92506..54bafe5c9 100644 --- a/doc/devel/uml/class132485.html +++ b/doc/devel/uml/class132485.html @@ -18,6 +18,6 @@

    Declaration :

    • C++ : class PluginAdapter : public Trafo

    Adapter used to integrage an effects processor in the render pipeline

    Artifact : pluginadapter

    -

    All public operations : pull

    +

    All public operations : process , pull

    diff --git a/doc/devel/uml/class132613.html b/doc/devel/uml/class132613.html index 763de044c..90fc0acbb 100644 --- a/doc/devel/uml/class132613.html +++ b/doc/devel/uml/class132613.html @@ -18,6 +18,6 @@

    Declaration :

    • C++ : class GLPipe : public Link

    specialized connection node used to handle the transfer of OpenGL data from a image bitmap into texture form

    Artifact : glpipe

    -

    All public operations : pull

    +

    All public operations : process , pull

    diff --git a/doc/devel/uml/class132741.html b/doc/devel/uml/class132741.html index f543def13..1efbe8fa1 100644 --- a/doc/devel/uml/class132741.html +++ b/doc/devel/uml/class132741.html @@ -16,9 +16,14 @@ -

    Declaration :

    • C++ : class State
    • Java : public interface State

    Directly inherited by : ARender GLRender StateAdapter StateProxy VRender

    +

    Declaration :

    • C++ : class State
    • Java : public interface State

    Directly inherited by : ARender GLRender StateAdapter StateProxy VRender

    Artifact : stateproxy, Component(s) : Builder

    -
    Relation currFrame (<unidirectional association>)

    Declaration :

    • Uml : # currFrame : Frame, multiplicity : 1..*
    • C++ : protected: vector<Frame *> currFrame
    +
    Relation currFrame (<unidirectional association>)

    Declaration :

    • Uml : # currFrame : Frame
    • C++ : protected: Frame * currFrame
    +
    Operation fetch

    Declaration :

    • Uml : + fetch() :
    • C++ : public: fetch ()
    +
    Operation allocateBuffer

    Declaration :

    • Uml : + allocateBuffer() :
    • C++ : public: allocateBuffer ()
    +
    Operation releaseBuffer

    Declaration :

    • Uml : + releaseBuffer() :
    • C++ : public: releaseBuffer ()
    +
    Operation isCalculated

    Declaration :

    • Uml : + isCalculated() :
    • C++ : public: isCalculated ()
    +

    All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer

    diff --git a/doc/devel/uml/class132869.html b/doc/devel/uml/class132869.html index 2d6833c2a..a9d6b46c3 100644 --- a/doc/devel/uml/class132869.html +++ b/doc/devel/uml/class132869.html @@ -18,5 +18,6 @@

    Declaration :

    • C++ : class ARender : public State

    Representation of a Audio render process

    Artifact : arender

    +

    All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer

    diff --git a/doc/devel/uml/class132997.html b/doc/devel/uml/class132997.html index a45d3c828..e59220a95 100644 --- a/doc/devel/uml/class132997.html +++ b/doc/devel/uml/class132997.html @@ -18,5 +18,6 @@

    Declaration :

    • C++ : class VRender : public State

    Representation of a Video render process. (Encapsulates the video buffers for the actual calculations)

    Artifact : vrender

    +

    All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer

    diff --git a/doc/devel/uml/class133125.html b/doc/devel/uml/class133125.html index d1cf4b2b6..8c1acac1f 100644 --- a/doc/devel/uml/class133125.html +++ b/doc/devel/uml/class133125.html @@ -18,5 +18,6 @@

    Declaration :

    • C++ : class GLRender : public State

    Representation of a OpenGL accelerated Video render process

    Artifact : glrender

    +

    All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer

    diff --git a/doc/devel/uml/class133765.html b/doc/devel/uml/class133765.html index 384101f0a..b6f9bde2d 100644 --- a/doc/devel/uml/class133765.html +++ b/doc/devel/uml/class133765.html @@ -18,6 +18,6 @@

    Declaration :

    Source Node: represents a media source to pull data from.

    Artifact : source

    -

    All public operations : pull

    +

    All public operations : process , pull

    diff --git a/doc/devel/uml/class135045.html b/doc/devel/uml/class135045.html index a651d86b1..c91ed83fb 100644 --- a/doc/devel/uml/class135045.html +++ b/doc/devel/uml/class135045.html @@ -18,6 +18,6 @@

    Declaration :

    • C++ : class CodecAdapter : public Trafo

    Artifact : codecadapter

    -

    All public operations : pull

    +

    All public operations : process , pull

    diff --git a/doc/devel/uml/class142213.html b/doc/devel/uml/class142213.html deleted file mode 100644 index a43acb9ac..000000000 --- a/doc/devel/uml/class142213.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -Class StateAdapter - - - - - -
    Class StateAdapter
    -

    - - - - -

    Declaration :

    • C++ : class StateAdapter : public State

    lightweight value class used to manage the buffer associations for a single pull() call on a processing node

    - -
    Operation pull

    Declaration :

    • Uml : + pull(inout renderProcess : State) : void
    • C++ : public: void pull ()

    trigger data processing by "pulling" results from the node's output

    -
    Operation retrieveBuffers

    Declaration :

    • Uml : + retrieveBuffers(in requiredSource : vector<InputDescriptor> const) : void
    • C++ : public: void retrieveBuffers (const vector<InputDescriptor> const& requiredSource)

    invoked from within the pull() - call of a node to set up the data buffers.
    @param requiredSource descriptor denoting the predecessors and the frames required from them

    -
    Relation <unidirectional association>

    Declaration :

    -
    Relation state (<unidirectional association>)

    Declaration :

    -

    All public operations : pull , retrieveBuffers

    - - diff --git a/doc/devel/uml/class142469.html b/doc/devel/uml/class142469.html index 9b6ed01a1..58c82f008 100644 --- a/doc/devel/uml/class142469.html +++ b/doc/devel/uml/class142469.html @@ -4,17 +4,20 @@ -Class caller +Class StateProxy -
    Class caller
    +
    Class StateProxy

    -

    Declaration :

    • C++ : class caller
    +

    Declaration :

    • C++ : class StateProxy : public State
    +
    +

    All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer

    + diff --git a/doc/devel/uml/class142597.html b/doc/devel/uml/class142597.html index 6465a8cd5..69ed2147c 100644 --- a/doc/devel/uml/class142597.html +++ b/doc/devel/uml/class142597.html @@ -4,17 +4,23 @@ -Class Backend_Cache +Class StateAdapter -
    Class Backend_Cache
    +
    Class StateAdapter

    -

    Declaration :

    • C++ : class Backend_Cache
    +

    Declaration :

    • C++ : class StateAdapter : public State
    + +
    Operation retrieve

    Declaration :

    • Uml : + retrieve() :
    • C++ : public: retrieve ()
    +
    Relation state (<unidirectional association>)

    Declaration :

    +
    Relation <unidirectional association>

    Declaration :

    +

    All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer , retrieve

    + diff --git a/doc/devel/uml/class142341.html b/doc/devel/uml/class142725.html similarity index 84% rename from doc/devel/uml/class142341.html rename to doc/devel/uml/class142725.html index e9ac0ff67..2118cb163 100644 --- a/doc/devel/uml/class142341.html +++ b/doc/devel/uml/class142725.html @@ -15,6 +15,6 @@ - -

    Declaration :

    • C++ : class InputDescriptor

    Artifact : procnode

    + +

    Declaration :

    • C++ : class InputDescriptor
    diff --git a/doc/devel/uml/class142085.html b/doc/devel/uml/class143109.html similarity index 64% rename from doc/devel/uml/class142085.html rename to doc/devel/uml/class143109.html index 70fbc4c7b..f2696562b 100644 --- a/doc/devel/uml/class142085.html +++ b/doc/devel/uml/class143109.html @@ -4,19 +4,17 @@ -Class StateProxy +Class BackendCache -
    Class StateProxy
    +
    Class BackendCache

    - -

    Declaration :

    • C++ : class StateProxy : public State
    -
    - + +

    Declaration :

    • C++ : class BackendCache
    diff --git a/doc/devel/uml/class143237.html b/doc/devel/uml/class143237.html new file mode 100644 index 000000000..b1b5a8387 --- /dev/null +++ b/doc/devel/uml/class143237.html @@ -0,0 +1,20 @@ + + + + + + +Class Caller + + + + + +
    Class Caller
    +

    + + + + +

    Declaration :

    • C++ : class Caller
    + diff --git a/doc/devel/uml/classdiagrams.html b/doc/devel/uml/classdiagrams.html index c08c6d8a8..1df0fcd1d 100644 --- a/doc/devel/uml/classdiagrams.html +++ b/doc/devel/uml/classdiagrams.html @@ -20,7 +20,6 @@ Automation Entities Builder Entities Controller Entities -Engine Details File MappingShows whats used to access Frames HierarchyLumiera Exception hierarchy In Memory Database @@ -28,6 +27,7 @@ Media-Asset Relations Proc-Asset Relations Render Entities +Render Mechanics Rules access Session structure Struct-Asset Relations diff --git a/doc/devel/uml/classes.html b/doc/devel/uml/classes.html index e1343f56e..9375f3648 100644 --- a/doc/devel/uml/classes.html +++ b/doc/devel/uml/classes.html @@ -26,12 +26,12 @@ AssetinterfaceSuperinterface describing especially the bookeeping properties of Assets AssetManagerboundaryFacade for the Asset subsystem AutoAutomation data for some parameter (i.e. a time varying function) -Backend_Cache +BackendCache Buildableinterface BuilderFacadeboundaryProvides unified access to the builder functionality. While individual components of the builder subsystem may be called if necessary or suitable, it is usually better to do all extern invocations via the high level methods of this Facade BuilderToolinterfaceUsed according to the visitor pattern: each Tool contains the concrete implementation for one task to be done to the various MObject classes BuildInstruct(Interface) building instructions to be executed by the Builder on the render node network under construction. -caller +Caller Categorytree like classification of Assets Clipbookkeeping (asset) view of a media clip. Clip @@ -76,7 +76,7 @@ GLPipespecialized connection node used to handle the transfer of OpenGL data from a image bitmap into texture form GLRenderRepresentation of a OpenGL accelerated Video render process Hub -InputDescriptor +InputDescriptor InterpolatorProvides the implementation for getting the acutal value of a time varying or automated effect/plugin parameter Invalid Label @@ -128,8 +128,8 @@ SourceSource Node: represents a media source to pull data from. Stateinterface State -StateAdapterlightweight value class used to manage the buffer associations for a single pull() call on a processing node -StateProxyimplementation +StateAdapter +StateProxyimplementation std::exceptionauxiliary Structkey abstraction: structural asset ThreadWe can basically reuse the Thread class design from Cinelerra2, Thread becomes a baseclass for all Threads diff --git a/doc/devel/uml/classes_list.html b/doc/devel/uml/classes_list.html index 153e47670..38b7af7d1 100644 --- a/doc/devel/uml/classes_list.html +++ b/doc/devel/uml/classes_list.html @@ -27,12 +27,12 @@ Asset
    AssetManager
    Auto
    -Backend_Cache
    +BackendCache
    Buildable
    BuilderFacade
    BuilderTool
    BuildInstruct
    -caller
    +Caller
    Category
    Clip
    Clip
    @@ -77,7 +77,7 @@ GLPipe
    GLRender
    Hub
    -InputDescriptor
    +InputDescriptor
    Interpolator
    Invalid
    Label
    @@ -129,8 +129,8 @@ Source
    State
    State
    -StateAdapter
    -StateProxy
    +StateAdapter
    +StateProxy
    std::exception
    Struct
    Thread
    diff --git a/doc/devel/uml/collaborationdiagrams.html b/doc/devel/uml/collaborationdiagrams.html index 9090762bc..5ccf1d4a5 100644 --- a/doc/devel/uml/collaborationdiagrams.html +++ b/doc/devel/uml/collaborationdiagrams.html @@ -18,7 +18,7 @@ - +
    "default" object
    build processThis figure shows the process of building and starting a RenderEngine
    pull call
    Render Process
    diff --git a/doc/devel/uml/fig131973.png b/doc/devel/uml/fig131973.png index 31b9b2a183d3c5ee8d642c4187e939b00921be56..7ed45dca7a110940795f165d53c21648bc62223e 100644 GIT binary patch literal 18410 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 literal 16309 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 diff --git a/doc/devel/uml/fig132229.png b/doc/devel/uml/fig132229.png new file mode 100644 index 0000000000000000000000000000000000000000..4cc4b71d5be185ffa2382bc0367a47569fc6e473 GIT binary patch literal 36167 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%0Dv2dWowyWAuA`Ggux`yM{A>(16G@ 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 literal 0 HcmV?d00001 diff --git a/doc/devel/uml/index.html b/doc/devel/uml/index.html index a054cc161..1cfd68cc1 100644 --- a/doc/devel/uml/index.html +++ b/doc/devel/uml/index.html @@ -116,7 +116,7 @@ Documentation
    Artifact Lumiera

    Depends on common

    Depends on gui

    Depends on proc

    Depends on backend

    the main executable to be built

    -

    executable associated with : placement, sessionimpl, builderfacade, controllerfacade, processor, pluginadapter, effect, buildertool, segmentationtool, aframe, assembler, trafo, explicitplacement, auto, glrender, link, parameter, renderengine, allocation, vframe, toolfactory, arender, renderstate, label, glbuf, procnode, stateproxy, hub, buildable, abstractmo, nodecreatertool, projector, interpolator, edl, fixture, glpipe, vrender, exitnode, pathmanager, track, paramprovider, mask, main, conmanager, clip, meta, fixedlocation, relativelocation, mobject, source, frame

    +

    executable associated with : effect, buildertool, segmentationtool, aframe, assembler, trafo, explicitplacement, auto, glrender, link, parameter, renderengine, allocation, vframe, toolfactory, arender, renderstate, label, glbuf, procnode, stateproxy, hub, buildable, abstractmo, nodecreatertool, projector, interpolator, edl, fixture, glpipe, vrender, exitnode, pathmanager, track, paramprovider, mask, main, conmanager, clip, meta, fixedlocation, relativelocation, mobject, source, frame, placement, sessionimpl, builderfacade, controllerfacade, processor, pluginadapter

    Artifact main

    Artifact source

    @@ -509,7 +509,7 @@ Documentation
    Artifact procnode

    Key abstraction of the Render Engine: a Processing Node

    -

    Artifact source associated with : ProcNode, InputDescriptor

    +

    Artifact source associated with : ProcNode

    Artifact trafo

    transforming processing Node

    @@ -764,6 +764,7 @@ Documentation
    Class Assembler
    +
    Class State
    Class Buildable
    @@ -876,6 +877,9 @@ reuse exiting Engine

    Selection :

      Transformation

      Automation Entities



      + +

      +

      Render Mechanics



      Class Processor
      Class ExitNode
      @@ -896,27 +900,9 @@ reuse exiting Engine

      Selection :

        Transformation
        Class VFrame
        Class GLBuf
        Class Source
        - -

        -

        Engine Details



        -
        Class State
        -
        -
        -
        -
        - -

        2.3.3 Use Case View render process

        -
        - -

        -

        pull call



        - -
        Class instance

        type :StateAdapter

        -
        Class instance node1

        type :ProcNode

        -
        Class instance node2

        type :ProcNode

        -
        Class instance next_adapter

        type :StateAdapter

        -
        Class instance current_state

        type :StateProxy

        Class caller
        -
        +
        +
        +
        @@ -1092,7 +1078,19 @@ reuse exiting Engine

        Selection :

          Transformation

          Class instance video

          type :ExitNode

          relations :

          +

          +

          +

          Render Process



          + +
          Class instance node1

          type :ProcNode

          +
          Class instance ad1

          type :StateAdapter

          +
          Class instance current

          type :StateProxy

          +
          Class instance node2

          type :ProcNode

          +
          Class instance ad2

          type :StateAdapter

          +
          Class Caller
          + +
          Class instance node3

          type :ProcNode

          +
          Class instance ad3

          type :StateAdapter

          3 Package BackendLayer

          diff --git a/doc/devel/uml/index_60.html b/doc/devel/uml/index_60.html index 8712d7074..cc286ecf2 100644 --- a/doc/devel/uml/index_60.html +++ b/doc/devel/uml/index_60.html @@ -28,10 +28,10 @@ <flow>transition <flow>transition <flow>transition -<flow>transition <flow>transition -<flow>transition +<flow>transition <flow>transition +<flow>transition <flow>transition <flow>transition <flow>transition diff --git a/doc/devel/uml/index_65.html b/doc/devel/uml/index_65.html index c1c05066a..8bc6b2fca 100644 --- a/doc/devel/uml/index_65.html +++ b/doc/devel/uml/index_65.html @@ -23,9 +23,13 @@ access Fileuse case activity finalactivity final activity finalactivity final +ad1class instance +ad2class instance +ad3class instance add new object to sessionuse case AFrameclass aframeartifacta buffer and render process holding a Audio frame +allocateBufferoperation allocationartifact Allocationclassa directive to place a MObject in a specific way anchorrelation @@ -52,12 +56,12 @@ Assetsclass view ATTACHattributeattach subject to anchor (e.g. an effect to a clip) au1class instance -aud_Aclass instance aud_aclass instance +aud_Aclass instance audioclass instance -audio1class instance -audio1class instance audio1class instance +audio1class instance +audio1class instance autoartifactMedia Object holding automation data AutoclassAutomation data for some parameter (i.e. a time varying function) Automation Entitiesclass diagram diff --git a/doc/devel/uml/index_66.html b/doc/devel/uml/index_66.html index 592c6f15d..f37527c49 100644 --- a/doc/devel/uml/index_66.html +++ b/doc/devel/uml/index_66.html @@ -21,7 +21,7 @@ Backend Componentsclass view backend use casesuse case diagram backend-componentscomponent diagram -Backend_Cacheclass +BackendCacheclass BackendLayerpackage buildoperation build flowactivity diagram diff --git a/doc/devel/uml/index_67.html b/doc/devel/uml/index_67.html index 996ed7eb6..2b841a011 100644 --- a/doc/devel/uml/index_67.html +++ b/doc/devel/uml/index_67.html @@ -19,7 +19,7 @@ NameKindDescription Cachecomponent Cachecomponent view -callerclass +Callerclass categoryrelationprimary tree like classification of the asset Categoryclasstree like classification of Assets categoryartifacttree like classification of Assets @@ -28,35 +28,34 @@ chainoperationcreate and add another Placement for this media object, thus increasingly constraining the (possible) position of this object. checked_inrelationchecked_in objects are subject of cache aging and must be not in use checked_outrelationthis list keeps all mappings which are in use, and thus prevents them from Cache aging -class instanceclass instance +class instanceclass instance class instanceclass instance -class instanceclass instance class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance class instanceclass instance class instanceclass instance -class instanceclass instance -class instanceclass instance class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance +class instanceclass instance +class instanceclass instance class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance class instanceclass instance class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance clearoperationclear current session contents
          without resetting overall session config.
          Afterwards, the session will contain only one
          empty EDL, while all Assets are retained.
          client codecomponent Clipclassbookkeeping (asset) view of a media clip. @@ -96,8 +95,8 @@ constraintartifactLocatingPin representing an directive by the user that
          must not be violated Constraintclass Controllercomponent -Controllerpackage controllerpackagesourcecode package

          The Processing and Render Controller,
          located within the MObject Subsystem +Controllerpackage Controller Entitiesclass diagram Controller Workingsclass view ControllerFacadeclassProvides unified access to the Proc-Subsystem Controller. Especially, this Facade class provides the functions to get a render engine to carry out actual renderings. @@ -107,8 +106,8 @@ create specific objectuse case createClipoperationcreate a (possibly compound) Clip refering to this media, ready to be added to the EDL. currEDLoperationThe EDL currently in focus. In most cases, Session and EDL are almost the same, just EDL emphasizes the collection aspect. But generally (for larger editing projects) one Session can contain several EDLs, which may even be nested. At any given time, only one of these EDLs has focus and recieves the editing commands. +currentclass instance currentrelationStandard access path to get at the current session via the Session Manager, which acts as a "PImpl" smart pointer -current_stateclass instance currFramerelation diff --git a/doc/devel/uml/index_69.html b/doc/devel/uml/index_69.html index c9eb2c76d..6c17d406d 100644 --- a/doc/devel/uml/index_69.html +++ b/doc/devel/uml/index_69.html @@ -18,21 +18,20 @@ - + - + - diff --git a/doc/devel/uml/index_70.html b/doc/devel/uml/index_70.html index f328ad207..3d833b61f 100644 --- a/doc/devel/uml/index_70.html +++ b/doc/devel/uml/index_70.html @@ -18,6 +18,7 @@
          NameKindDescription
          edlartifactthe (high level) Edit Decision List within the current Session
          EDLcomponent
          EDLclass
          EDLcomponent
          EDL Example1object diagramA simple example showing how the actual objects are placed in the Fixture (=definitive playlist). It shows a Video and Audio clip placed on two tracks
          EDL Example2object diagramMore complex example showing the Object graph in the EDL and how it is linked into the Fixture to yield the actual locations. In this example, an HUE Effect is applied on a part of the Clip
          edlsrelation
          EffectclassEffect or media processing component
          effectartifactEffect or media processing component
          effectartifactEDL representation of a pluggable and automatable effect.
          effectartifactEffect or media processing component
          Effectclass
          elementsrelationrelevant MObjects comprising this segment. TODO: actually necessary??
          enableoperationchange the enabled status of this asset. Note the corresponding #isActive predicate may depend on the enablement status of parent assets as well
          endattributeend of the timerange (excl)
          Enginecomponent
          enginepackagesourcecode package

          The Core Render Engine
          Engine Detailsclass diagram
          Engine Example1object diagramExample1 (from EDL) continued: here the RenderEngine to be created by the Builder from the Input shown in Example1
          Engine Example2object diagramExample2 (from EDL) continued: notably in this RenderEngine the Effect has been partitioned into 2 segments with constant configuration.
          Engine Partsdeployment view
          + diff --git a/doc/devel/uml/index_73.html b/doc/devel/uml/index_73.html index fa68d81e1..12fe67359 100644 --- a/doc/devel/uml/index_73.html +++ b/doc/devel/uml/index_73.html @@ -23,7 +23,7 @@ - + @@ -34,6 +34,7 @@ +
          NameKindDescription
          Factoryclassa template for generating functor-like Factory objects, used to encapsulate object creation and providing access via smart-pointers only.
          fetchoperation
          Fileclass
          filerelation
          File Mappingclass diagramShows whats used to access Frames
          inputclass instance
          inputclass instance
          inputclass instance
          InputDescriptorclass
          InputDescriptorclass
          instanceoperation
          instructionsrelation
          Interfaceclass view
          Invalidclass
          iporelation
          isActiveoperationweather this asset is swithced on and consequently included in the fixture and participates in rendering
          isCalculatedoperation
          diff --git a/doc/devel/uml/index_78.html b/doc/devel/uml/index_78.html index 8afac3d9f..d0f7bd42e 100644 --- a/doc/devel/uml/index_78.html +++ b/doc/devel/uml/index_78.html @@ -20,9 +20,9 @@ nameattributeelement ID, comprehensible but sanitized. The tuple (category, name, org) is unique. need sub objectuse case nextrelationnext additional LocatingPin, if any -next_adapterclass instance node1class instance -node2class instance +node2class instance +node3class instance nodecreatertoolartifactcentral Tool implementing the Renderengine building NodeCreatorToolclassThis Tool implementation plays the central role in the buld process: given a MObject from Session, it is able to attach ProcNodes to the render engine under construction such as to reflect the properties of the MObject in the actual render. nodesrelation diff --git a/doc/devel/uml/index_79.html b/doc/devel/uml/index_79.html index f63687c5b..bfec5f683 100644 --- a/doc/devel/uml/index_79.html +++ b/doc/devel/uml/index_79.html @@ -19,8 +19,8 @@ NameKindDescription offsetattributeOffset the actual position by this (time) value relative to the anchor point. TODO: Representation? orgattributeorigin or authorship id. Can be a project abbreviation, a package id or just the authors nickname or UID. This allows for the compnent name to be more generic (e.g. "blur"). Default for all assets provided by the core Lumiera codebase is "lumi". -ouputclass instance ouputclass instance +ouputclass instance ouputclass instance outPortrelationthe Port this MObject wants to be conected to outputrelation diff --git a/doc/devel/uml/index_80.html b/doc/devel/uml/index_80.html index 83ab6f76d..0cff29b1c 100644 --- a/doc/devel/uml/index_80.html +++ b/doc/devel/uml/index_80.html @@ -40,7 +40,7 @@ pnodenode pointattributeidentifying the point where the nodes should be attached Posix Threads Abstractionclass viewC++ wrapers for pthreads -predecessorsrelationpreconfigured table of all predecessor nodes, qualified
          with the output port on these nodes and time offset of the data
          we need for doing our calculations
          +predecessorsrelation predicate implclass instance Prefetchclass Previewclassalternative version of the media data, probably with lower resolution @@ -53,6 +53,7 @@ Proc-Asset Relationsclass diagram proc-componentscomponent diagram ProcDispatcherclass +processoperation ProcessingLayerpackage Processorclass processorartifacta single render pipeline for one segment of the timeline @@ -64,9 +65,7 @@ ProjectorclassSpecial video processing node used to scale and translate image data. projectorartifactvideo ProcNode for scaling and translating image data providerrelation -pulloperationtrigger data processing by "pulling" results from the node's output -pulloperationtrigger data processing by "pulling" results from the node's output -pull callcollaboration diagram +pulloperation diff --git a/doc/devel/uml/index_82.html b/doc/devel/uml/index_82.html index c807e8ca4..7f2b69c16 100644 --- a/doc/devel/uml/index_82.html +++ b/doc/devel/uml/index_82.html @@ -22,11 +22,13 @@ registryrelation@internal Table or DB holding all registered asset instances. relativelocationartifactPlacement implemnetaion providing various ways of attaching a MObject to another one RelativeLocationclass -relTypeattributethe kind of relation denoted by this Placement +releaseBufferoperation RelTypeclassthe possible kinds of RelativePlacements +relTypeattributethe kind of relation denoted by this Placement removeoperationremove the given asset <i>together with all its dependants</i> from the internal DB Render Entitiesclass diagram -render processuse case view +Render Mechanicsclass diagram +Render Processcollaboration diagram Render Requestactivity parameter RenderEngineclass renderengineartifacta complete network of processing nodes usable for rendering @@ -43,7 +45,7 @@ resolveoperation Resolvercomponent ResolverBaseclass -retrieveBuffersoperationinvoked from within the pull() - call of a node to set up the data buffers.
          @param requiredSource descriptor denoting the predecessors and the frames required from them +retrieveoperation rootCauseoperationIf this exception was caused by a chain of further exceptions,
          return the first one registered in this throw sequence.
          This works only, if every exceptions thrown as a consequence
          of another exception is propperly constructed by passing
          the original exception to the constructor Rule Basecomponent Rules accessclass diagram diff --git a/doc/devel/uml/index_83.html b/doc/devel/uml/index_83.html index 2edde4200..c7b3fed84 100644 --- a/doc/devel/uml/index_83.html +++ b/doc/devel/uml/index_83.html @@ -47,20 +47,20 @@ SimpleClipclassElementary clip consisting of only one media stream SmartPointerclass SmartPointersclass view -sourcerelationthe media source this clip referes to sourcerelationmedia source of this clip +sourcerelationthe media source this clip referes to SourceclassSource Node: represents a media source to pull data from. sourceartifactRepresentation of a Media source Source Overviewdeployment diagram startattributestartpos in source startattributebegin of the timerange covered by this processor startattribute -Statenode Stateclass +Statenode Stateclass -staterelation -StateAdapterclasslightweight value class used to manage the buffer associations for a single pull() call on a processing node -StateProxyclass +staterelation +StateAdapterclass +StateProxyclass stateproxyartifactKey Interface representing a render process and encapsulating state std::exceptionclass Structclasskey abstraction: structural asset diff --git a/doc/devel/uml/index_84.html b/doc/devel/uml/index_84.html index bfcae496d..78e737858 100644 --- a/doc/devel/uml/index_84.html +++ b/doc/devel/uml/index_84.html @@ -42,12 +42,12 @@ trafoartifacttransforming processing Node treatoperation treatoperationThis operation is to be overloaded for the specific MObject subclasses to be treated. +treatoperation treatoperation treatoperation -treatoperation treatoperation -treatoperation treatoperation +treatoperation treatoperation TypeHandlerclass TypeHandler<Pipe>class diff --git a/doc/devel/uml/index_86.html b/doc/devel/uml/index_86.html index 364ff0811..c2ce0bff8 100644 --- a/doc/devel/uml/index_86.html +++ b/doc/devel/uml/index_86.html @@ -20,23 +20,23 @@ versionattributeversion number of the thing or concept represented by this asset. Of each unique tuple (name, category, org) there will be only one version in the whole system. Version 0 is reserved for internal purposes. Versions are considered to be ordered, and any higher version is supposed to be fully backwards compatible to all previous versions. VFrameclass vframeartifacta buffer and render process holding a Video frame -vid1class instance vid1class instance -vid_aclass instance -vid_Aclass instance -vid_Aclass instance -vid_aclass instance +vid1class instance vid_Aclass instance -videoclass instance -videoclass instance +vid_aclass instance +vid_Aclass instance +vid_Aclass instance +vid_aclass instance videoclass instance +videoclass instance videoclass instance -video1class instance -video1class instance -video1class instance +videoclass instance video1class instance +video1class instance video1class instance +video1class instance video1class instance +video1class instance Visitableclass visitorpackagesub-namespace for visitor library implementation visitorartifactAcyclic Visitor library diff --git a/doc/devel/uml/public_operations.html b/doc/devel/uml/public_operations.html index 03a780210..c252030f0 100644 --- a/doc/devel/uml/public_operations.html +++ b/doc/devel/uml/public_operations.html @@ -17,6 +17,7 @@ + @@ -29,6 +30,7 @@ + @@ -47,29 +49,31 @@ + - - + + + - + - + + - diff --git a/uml/lumiera/128389 b/uml/lumiera/128389 index 52c1b5245..20d07a18b 100644 --- a/uml/lumiera/128389 +++ b/uml/lumiera/128389 @@ -1,6 +1,6 @@ format 40 "RenderEngine" // ProcessingLayer::RenderEngine - revision 13 + revision 15 modified_by 5 "hiv" // class settings //class diagram settings @@ -82,6 +82,11 @@ format 40 size A4 end + classdiagram 131973 "Render Mechanics" + draw_all_relations no hide_attributes default hide_operations default show_members_full_definition yes show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + size A4 + end + class 131333 "RenderEngine" visibility package cpp_decl "${comment}${template}class ${name}${inherit} @@ -155,7 +160,7 @@ ${inlines} a package cpp default "#include in source" classrelation_ref 136325 // - b multiplicity "" parent class_ref 132741 // StateProxy + b multiplicity "" parent class_ref 132741 // State end attribute 129413 "start" @@ -233,6 +238,46 @@ ${members}}; classrelation_ref 137861 // params () b multiplicity "" parent class_ref 134533 // Parameter end + + classrelation 152581 // predecessors () + relation 149125 *--> + stereotype "vector" + a role_name "predecessors" multiplicity "*" protected + cpp default " ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value}; +" + classrelation_ref 152581 // predecessors () + b multiplicity "" parent class_ref 142725 // InputDescriptor + end + + operation 135685 "pull" + public explicit_return_type "" + nparams 0 + cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${)}${const}${volatile} ${throw}${abstract};" + cpp_def "${comment}${inline}${type} +${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl} +{ + ${body} +} + +" + + + end + + operation 136069 "process" + public explicit_return_type "" + nparams 0 + cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${)}${const}${volatile} ${throw}${abstract};" + cpp_def "${comment}${inline}${type} +${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl} +{ + ${body} +} + +" + + + end end class 131845 "Trafo" @@ -415,7 +460,7 @@ ${inlines} a public cpp default "${type}" classrelation_ref 134661 // - b multiplicity "" parent class_ref 132741 // StateProxy + b multiplicity "" parent class_ref 132741 // State end end @@ -436,7 +481,7 @@ ${inlines} a public cpp default "${type}" classrelation_ref 134789 // - b multiplicity "" parent class_ref 132741 // StateProxy + b multiplicity "" parent class_ref 132741 // State end end @@ -457,7 +502,7 @@ ${inlines} a public cpp default "${type}" classrelation_ref 134917 // - b multiplicity "" parent class_ref 132741 // StateProxy + b multiplicity "" parent class_ref 132741 // State end end @@ -568,5 +613,91 @@ ${inlines} b multiplicity "" parent class_ref 136709 // Media end end + + class 142469 "StateProxy" + visibility package stereotype "implementation" + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + classrelation 152453 // + relation 148997 ---|> + a public + cpp default "${type}" + classrelation_ref 152453 // + b multiplicity "" parent class_ref 132741 // State + end + end + + class 142597 "StateAdapter" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + classrelation 152325 // + relation 148869 ---|> + a public + cpp default "${type}" + classrelation_ref 152325 // + b multiplicity "" parent class_ref 132741 // State + end + + operation 135557 "retrieve" + public explicit_return_type "" + nparams 0 + cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${)}${const}${volatile} ${throw}${abstract};" + cpp_def "${comment}${inline}${type} +${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl} +{ + ${body} +} + +" + + + end + + classrelation 152709 // state () + relation 149253 ---> + a role_name "state" multiplicity "1" protected + cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; +" + classrelation_ref 152709 // state () + b multiplicity "" parent class_ref 142469 // StateProxy + end + + classrelation 152837 // + relation 149381 ---> + a role_name "" multiplicity "" protected + cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; +" + classrelation_ref 152837 // + b multiplicity "" parent class_ref 133253 // Frame + end + end + + class 142725 "InputDescriptor" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + end end end diff --git a/uml/lumiera/128901 b/uml/lumiera/128901 index e4d919380..455fee7d7 100644 --- a/uml/lumiera/128901 +++ b/uml/lumiera/128901 @@ -1,6 +1,6 @@ format 40 "Builder" // ProcessingLayer::MObject::Builder - revision 14 + revision 16 modified_by 5 "hiv" // class settings //class diagram settings @@ -299,7 +299,7 @@ ${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl} end end - class 132741 "StateProxy" + class 132741 "State" abstract visibility public stereotype "interface" cpp_decl "${comment}${template}class ${name}${inherit} { @@ -316,12 +316,73 @@ ${members}}; classrelation 135941 // currFrame () relation 134533 ---> + stereotype "vector" a role_name "currFrame" multiplicity "" protected cpp default " ${comment}${static}${mutable}${volatile}${const}${type} * ${name}${value}; " classrelation_ref 135941 // currFrame () b multiplicity "1" parent class_ref 133253 // Frame end + + operation 135813 "fetch" + public explicit_return_type "" + nparams 0 + cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${)}${const}${volatile} ${throw}${abstract};" + cpp_def "${comment}${inline}${type} +${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl} +{ + ${body} +} + +" + + + end + + operation 135941 "allocateBuffer" + public explicit_return_type "" + nparams 0 + cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${)}${const}${volatile} ${throw}${abstract};" + cpp_def "${comment}${inline}${type} +${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl} +{ + ${body} +} + +" + + + end + + operation 136197 "releaseBuffer" + public explicit_return_type "" + nparams 0 + cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${)}${const}${volatile} ${throw}${abstract};" + cpp_def "${comment}${inline}${type} +${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl} +{ + ${body} +} + +" + + + end + + operation 136325 "isCalculated" + public explicit_return_type "" + nparams 0 + cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${)}${const}${volatile} ${throw}${abstract};" + cpp_def "${comment}${inline}${type} +${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl} +{ + ${body} +} + +" + + + end end class 134021 "Buildable" diff --git a/uml/lumiera/129285 b/uml/lumiera/129285 index 7883c598c..72c222be4 100644 --- a/uml/lumiera/129285 +++ b/uml/lumiera/129285 @@ -1,6 +1,6 @@ format 40 "ProcessingLayer" // ProcessingLayer - revision 15 + revision 19 modified_by 5 "hiv" // class settings //class diagram settings @@ -602,5 +602,92 @@ format 40 classinstance_ref 134405 // ouput end end + + collaborationdiagram 132229 "Render Process" + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + size A4 + end + + classinstance 136197 "node1" + type class_ref 131717 // ProcNode + attributes + end + relations + end + end + + classinstance 136325 "ad1" + type class_ref 142597 // StateAdapter + attributes + end + relations + end + end + + classinstance 136453 "current" + type class_ref 142469 // StateProxy + attributes + end + relations + end + end + + classinstance 136581 "node2" + type class_ref 131717 // ProcNode + attributes + end + relations + end + end + + classinstance 136709 "ad2" + type class_ref 142597 // StateAdapter + attributes + end + relations + end + end + + class 143109 "BackendCache" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + end + + class 143237 "Caller" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + end + + classinstance 136837 "node3" + type class_ref 131717 // ProcNode + attributes + end + relations + end + end + + classinstance 136965 "ad3" + type class_ref 142597 // StateAdapter + attributes + end + relations + end + end end end diff --git a/uml/lumiera/131973.diagram b/uml/lumiera/131973.diagram index 9d11f2c5a..7a9c0af13 100644 --- a/uml/lumiera/131973.diagram +++ b/uml/lumiera/131973.diagram @@ -2,66 +2,66 @@ format 40 classcanvas 128005 class_ref 131717 // ProcNode draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 106 330 2004 + xyz 106 313 2004 end classcanvas 128517 class_ref 132741 // State draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 83 21 2000 - end -classcanvas 128645 class_ref 142085 // StateProxy - draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 127 135 2000 - end -classcanvas 128773 class_ref 142213 // StateAdapter - draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 36 216 2000 - end -classcanvas 129157 class_ref 142341 // InputDescriptor - draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 183 446 2000 + xyz 79 -16 2000 end classcanvas 129669 class_ref 133253 // Frame draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default xyz 267 221 3005 end -relationcanvas 128901 relation_ref 148229 // - geometry VHV unfixed - from ref 128645 z 1999 to point 179 108 - line 131589 z 1999 to point 120 108 - line 131717 z 1999 to ref 128517 - no_role_a no_role_b - no_multiplicity_a no_multiplicity_b -relationcanvas 129029 relation_ref 148357 // - geometry VHV unfixed - from ref 128773 z 1999 to point 80 108 - line 131333 z 1999 to point 120 108 - line 131461 z 1999 to ref 128517 - no_role_a no_role_b - no_multiplicity_a no_multiplicity_b -relationcanvas 129285 relation_ref 148485 // - geometry HV - from ref 128005 z 1999 to point 228 367 - line 129541 z 1999 to ref 129157 - role_a_pos 240 421 3000 no_role_b - multiplicity_a_pos 216 421 3000 no_multiplicity_b +classcanvas 131845 class_ref 142469 // StateProxy + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 149 135 2000 + end +classcanvas 131973 class_ref 142597 // StateAdapter + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 43 225 3010 + end +classcanvas 132357 class_ref 142725 // InputDescriptor + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 233 434 2000 + end relationcanvas 129797 relation_ref 134533 // - from ref 128517 z 1999 to point 303 129 - line 130053 z 1999 stereotype "<>" xyz 248 128 3000 to ref 129669 - role_a_pos 312 194 3000 no_role_b - multiplicity_a_pos 281 158 3000 multiplicity_b_pos 171 82 3000 -relationcanvas 129925 relation_ref 148613 // - from ref 128773 z 1999 to ref 129669 + from ref 128517 z 1999 stereotype "<>" xyz 282 103 3000 to point 303 129 + line 130053 z 1999 to ref 129669 + role_a_pos 315 196 3000 no_role_b + no_multiplicity_a multiplicity_b_pos 175 84 3000 +relationcanvas 132101 relation_ref 148869 // + geometry VHV unfixed + from ref 131973 z 1999 to point 81 108 + line 134021 z 1999 to point 120 108 + line 134149 z 1999 to ref 128517 no_role_a no_role_b no_multiplicity_a no_multiplicity_b -relationcanvas 130181 relation_ref 148741 // - from ref 128773 z 1999 to point 179 226 - line 130309 z 1999 to ref 128645 - role_a_pos 149 210 3000 no_role_b +relationcanvas 132229 relation_ref 148997 // + geometry VHV + from ref 131845 z 1999 to point 201 126 + line 134277 z 1999 to point 120 126 + line 134405 z 1999 to ref 128517 + no_role_a no_role_b no_multiplicity_a no_multiplicity_b -line 130437 -_-_ - from ref 128773 z 1999 to point 136 328 - line 130693 z 1999 to ref 128005 -line 130565 -_-_ - from ref 128773 z 1999 to ref 128005 +relationcanvas 132485 relation_ref 149125 // + geometry HV + from ref 128005 z 1999 stereotype "<>" xyz 220 359 3000 to point 278 360 + line 133381 z 1999 to ref 132357 + role_a_pos 290 409 3000 no_role_b + multiplicity_a_pos 266 409 3000 no_multiplicity_b +relationcanvas 133509 relation_ref 149253 // + from ref 131973 z 1999 to point 200 215 + line 133637 z 1999 to ref 131845 + role_a_pos 180 222 3000 no_role_b + multiplicity_a_pos 185 199 3000 no_multiplicity_b +relationcanvas 134533 relation_ref 149381 // + from ref 131973 z 3004 to ref 129669 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +line 134661 -_-_ + from ref 131973 z 2003 to ref 128005 +line 134789 -_-_ + from ref 131973 z 2003 to point 137 322 + line 134917 z 2003 to ref 128005 preferred_whz 414 544 1 end diff --git a/uml/lumiera/132101.diagram b/uml/lumiera/132101.diagram deleted file mode 100644 index 39dd25211..000000000 --- a/uml/lumiera/132101.diagram +++ /dev/null @@ -1,91 +0,0 @@ -format 40 - -classinstancecanvas 128005 classinstance_ref 136069 // - xyz 144 217 2000 - end -classinstancecanvas 128133 classinstance_ref 136197 // node1 - xyz 169 309 2000 - end -classinstancecanvas 128261 classinstance_ref 136325 // node2 - xyz 485 277 2000 - end -classinstancecanvas 128389 classinstance_ref 136453 // next_adapter - xyz 388 216 2005 - end -classinstancecanvas 128901 classinstance_ref 136581 // current_state - xyz 114 20 2000 - end -classinstance 129285 class_ref 142469 // caller - name "" xyz 29 106 2000 -classinstance 129541 class_ref 142597 // Backend_Cache - name "" xyz 412 39 2000 -textcanvas 130565 "node1 using node2 as predecessor" - xyzwh 267 343 2000 133 24 -textcanvas 130693 "try to get frame from Cache first" - xyzwh 468 121 2000 89 43 -note 130821 "Triggered by pulling" - xyzwh 5 176 2005 118 38 -note 130949 "Buffers" - xyzwh 255 20 2005 61 35 -linkcanvas 128517 - from ref 128005 z 1999 to ref 128133 -dirscanvas 128645 z 1000 linkcanvas_ref 128517 - show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default - forward_label "2 pull()" xyz 217 255 3000 - backward_label "3 retrieveBuffers()" xyz 95 282 3000 -linkcanvas 128773 - from ref 128005 z 1999 to ref 128389 -dirscanvas 130053 z 1000 linkcanvas_ref 128773 - show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default - forward_label "4 create" xyz 281 192 3000 -linkcanvas 129029 - from ref 128005 z 1999 to ref 128901 -linkcanvas 129157 - from ref 128389 z 1999 to ref 128261 -dirscanvas 130309 z 1000 linkcanvas_ref 129157 - show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default - forward_label "6 pull()" xyz 515 246 3000 -linkcanvas 129413 - from ref 129285 z 1999 to ref 128005 -dirscanvas 129925 z 1000 linkcanvas_ref 129413 - show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default - forward_label "1 pull()" xyz 124 140 3000 -linkcanvas 129669 - from ref 128389 z 1999 to ref 129541 -dirscanvas 130181 z 1000 linkcanvas_ref 129669 - show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default - forward_label "5 try_fetch" xyz 386 132 3000 -linkcanvas 129797 - from ref 128005 z 1999 to ref 129541 -dirscanvas 130437 z 1000 linkcanvas_ref 129797 - show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default - forward_label "7 store" xyz 280 108 3000 -msgs - msg operation_ref 135685 // "pull(inout renderProcess : State) : void" - forward ranks 1 "1" dirscanvas_ref 129925 - msgs - msg operation_ref 135557 // "pull(inout renderProcess : State) : void" - forward ranks 2 "1.1" dirscanvas_ref 128645 - msgs - msg operation_ref 135813 // "retrieveBuffers(in requiredSource : vector const) : void" - backward ranks 3 "1.1.1" dirscanvas_ref 128645 - msgs - explicitmsg "create" - forward ranks 4 "1.1.1.1" dirscanvas_ref 130053 - msgs - explicitmsg "try_fetch" - forward ranks 5 "1.1.1.1.1" dirscanvas_ref 130181 - no_msg - msg operation_ref 135557 // "pull(inout renderProcess : State) : void" - forward ranks 6 "1.1.1.1.2" dirscanvas_ref 130309 - no_msg - msgsend - explicitmsg "store" - forward ranks 7 "1.1.1.2" dirscanvas_ref 130437 - no_msg - msgsend - msgsend - msgsend -msgsend -preferred_whz 599 408 1 -end diff --git a/uml/lumiera/132229.diagram b/uml/lumiera/132229.diagram new file mode 100644 index 000000000..af599827d --- /dev/null +++ b/uml/lumiera/132229.diagram @@ -0,0 +1,184 @@ +format 40 + +classinstancecanvas 128261 classinstance_ref 136197 // node1 + xyz 152 504 2000 + end +classinstancecanvas 128389 classinstance_ref 136325 // ad1 + xyz 191 393 2000 + end +classinstancecanvas 128517 classinstance_ref 136453 // current + xyz 188 92 2000 + end +classinstancecanvas 128645 classinstance_ref 136581 // node2 + xyz 388 393 2000 + end +classinstancecanvas 128773 classinstance_ref 136709 // ad2 + xyz 422 301 2000 + end +classinstance 128901 class_ref 143109 // BackendCache + name "" xyz 692 12 2000 +classinstance 129029 class_ref 143237 // Caller + name "" xyz 28 505 2000 +classinstancecanvas 130949 classinstance_ref 136837 // node3 + xyz 625 300 2000 + end +classinstancecanvas 131077 classinstance_ref 136965 // ad3 + xyz 665 199 2000 + end +textcanvas 133381 "node1 using node2 as predecessor; calculates in-place, will push result to Cache" + xyzwh 149 538 2000 408 21 +textcanvas 133509 "node2 using node3 as predecessor. Calculates without caching" + xyzwh 385 427 2005 350 18 +textcanvas 133637 "node3 doesn't calc, but fetch result from Cache" + xyzwh 564 329 2000 231 18 +linkcanvas 129157 + from ref 129029 z 1999 to ref 128261 +dirscanvas 129285 z 1000 linkcanvas_ref 129157 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "1 pull()" xyz 97 480 3000 +linkcanvas 129413 + from ref 128261 z 1999 to ref 128389 +dirscanvas 130309 z 1000 linkcanvas_ref 129413 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "2 retrieve()" xyz 141 437 3000 + backward_label "16 process()" xyz 236 471 3000 +linkcanvas 129541 + from ref 128389 z 1999 to ref 128517 +dirscanvas 131717 z 1000 linkcanvas_ref 129541 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "3 fetch() +11 allocateBuffer() +17 isCalculated()" xyz 128 228 3000 +linkcanvas 129669 + from ref 128389 z 1999 to ref 128645 +dirscanvas 130437 z 1000 linkcanvas_ref 129669 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "4 pull()" xyz 319 369 3000 +linkcanvas 129797 + from ref 128645 z 1999 to ref 128773 +dirscanvas 130693 z 1000 linkcanvas_ref 129797 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "5 retrieve()" xyz 379 349 3000 + backward_label "13 process()" xyz 469 372 3000 +linkcanvas 130181 + from ref 128773 z 1999 to ref 128517 +dirscanvas 133765 z 1000 linkcanvas_ref 130181 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "14 releaseBuffer()" xyz 285 227 3000 +linkcanvas 131205 + from ref 128773 z 1999 to ref 130949 +dirscanvas 131845 z 1000 linkcanvas_ref 131205 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "6 pull()" xyz 553 276 3000 +linkcanvas 131333 + from ref 130949 z 1999 to ref 131077 +dirscanvas 131973 z 1000 linkcanvas_ref 131333 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "7 retrieve()" xyz 615 236 3000 +linkcanvas 131461 + from ref 131077 z 1999 to ref 128517 +dirscanvas 132101 z 1000 linkcanvas_ref 131461 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "8 fetch()" xyz 449 179 3000 +linkcanvas 131589 + from ref 128517 z 1999 to point 295 24 + line 134277 z 1999 to ref 128901 +dirscanvas 132229 z 1000 linkcanvas_ref 134277 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "9 fetch +12 allocateNewFrame +15 releaseFrame +18 isCalculatedFrame +20 releaseFrame" xyz 487 29 3000 +linkcanvas 132357 + from ref 131077 z 1999 to point 515 211 + line 132613 z 1999 to ref 128773 +dirscanvas 132741 z 1000 linkcanvas_ref 132357 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default +linkcanvas 132485 + from ref 128773 z 1999 to point 280 312 + line 132869 z 1999 to ref 128389 +dirscanvas 132997 z 1000 linkcanvas_ref 132485 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "10 allocateBuffer()" xyz 306 293 3000 +linkcanvas 133893 + from ref 129029 z 1999 to point 49 155 + line 134021 z 1999 to ref 128517 +dirscanvas 134149 z 1000 linkcanvas_ref 134021 + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + forward_label "19 releaseBuffer()" xyz 65 100 3000 +msgs + msg operation_ref 135685 // "pull()" + forward ranks 1 "1" dirscanvas_ref 129285 + msgs + msg operation_ref 135557 // "retrieve()" + forward ranks 2 "1.1" dirscanvas_ref 130309 + msgs + msg operation_ref 135813 // "fetch()" + forward ranks 3 "1.1.1" dirscanvas_ref 131717 + no_msg + msg operation_ref 135685 // "pull()" + forward ranks 4 "1.1.2" dirscanvas_ref 130437 + msgs + msg operation_ref 135557 // "retrieve()" + forward ranks 5 "1.1.2.1" dirscanvas_ref 130693 + msgs + msg operation_ref 135685 // "pull()" + forward ranks 6 "1.1.2.1.1" dirscanvas_ref 131845 + msgs + msg operation_ref 135557 // "retrieve()" + forward ranks 7 "1.1.2.1.1.1" dirscanvas_ref 131973 + msgs + msg operation_ref 135813 // "fetch()" + forward ranks 8 "1.1.2.1.1.1.1" dirscanvas_ref 132101 + msgs + explicitmsg "fetch" + forward ranks 9 "1.1.2.1.1.1.1.1" dirscanvas_ref 132229 + no_msg + msgsend + msgsend + msgsend + msgsend + msgsend + msgsend + msgsend + msg operation_ref 135941 // "allocateBuffer()" + forward ranks 10 "2" dirscanvas_ref 132997 + msgs + msg operation_ref 135941 // "allocateBuffer()" + forward ranks 11 "2.1" dirscanvas_ref 131717 + msgs + explicitmsg "allocateNewFrame" + forward ranks 12 "2.1.1" dirscanvas_ref 132229 + no_msg + msgsend + msgsend + msg operation_ref 136069 // "process()" + backward ranks 13 "3" dirscanvas_ref 130693 + no_msg + msg operation_ref 136197 // "releaseBuffer()" + forward ranks 14 "4" dirscanvas_ref 133765 + msgs + explicitmsg "releaseFrame" + forward ranks 15 "4.1" dirscanvas_ref 132229 + no_msg + msgsend + msg operation_ref 136069 // "process()" + backward ranks 16 "5" dirscanvas_ref 130309 + no_msg + msg operation_ref 136325 // "isCalculated()" + forward ranks 17 "6" dirscanvas_ref 131717 + msgs + explicitmsg "isCalculatedFrame" + forward ranks 18 "6.1" dirscanvas_ref 132229 + no_msg + msgsend + msg operation_ref 136197 // "releaseBuffer()" + forward ranks 19 "7" dirscanvas_ref 134149 + msgs + explicitmsg "releaseFrame" + forward ranks 20 "7.1" dirscanvas_ref 132229 + no_msg + msgsend +msgsend +end diff --git a/uml/lumiera/5.session b/uml/lumiera/5.session index 5f7a09a5a..dc8936ef6 100644 --- a/uml/lumiera/5.session +++ b/uml/lumiera/5.session @@ -1,20 +1,20 @@ window_sizes 1140 830 270 860 680 71 diagrams - active collaborationdiagram_ref 132101 // pull call - 599 408 100 4 0 0 - classdiagram_ref 131973 // Engine Details - 414 544 100 4 0 0 - classdiagram_ref 128389 // Render Entities - 829 656 100 4 162 0 + classdiagram_ref 131973 // Render Mechanics + 428 623 100 4 2 0 + active collaborationdiagram_ref 132229 // Render Process + 817 644 100 4 0 0 end show_stereotypes selected package_ref 129 // lumiera open + class_ref 132741 // State - package_ref 128261 // MObject - classview_ref 128133 // Engine Workings - usecaseview_ref 128517 // render process + package_ref 129029 // Controller + class_ref 131717 // ProcNode + class_ref 142597 // StateAdapter + usecaseview_ref 128005 // Renderengine Use class_ref 140677 // QueryHandler class_ref 140805 // TypeHandler class_ref 140933 // ResolverBase diff --git a/uml/lumiera/lumiera.prj b/uml/lumiera/lumiera.prj index 93cb8fa6f..2b3a34ea7 100644 --- a/uml/lumiera/lumiera.prj +++ b/uml/lumiera/lumiera.prj @@ -1,6 +1,6 @@ format 40 "lumiera" - revision 45 + revision 46 modified_by 5 "hiv" cpp_root_dir "../../src/" diff --git a/wiki/renderengine.html b/wiki/renderengine.html index 09256ec75..6f55a4ef0 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -917,6 +917,15 @@ TertiaryMid: #99a TertiaryDark: #667 Error: #f88 +
          +
          The Connection Manager is a __Facade__ for querying information and deriving decisions regarding various aspects of data streams and possible connections.
          +* retrieve information about capabilities of a stream type given by ID
          +* decide if a connection is possible
          +* retrieve a //strategy// for implementing a connection
          +
          +In the intended implementation, a good deal of this functionality will actually be implemented by [[rules|ConfigRules]], while other parts need to be provided by hard wired logic, at least as a fallback. Anyway, the purpose of the Connection Manager ois to isolate the [[Builder]], which is client of this information and decision services, from these details
          +
          +
          Configuration Queries are requests to the system to "create or retrieve an object with //this and that // capabilities". They are resolved by a rule based system ({{red{planned feature}}}) and the user can extend the used rules for each Session. Syntactically, they are stated in ''prolog'' syntax as a conjunction (=logical and) of ''predicates'', for example {{{stream(mpeg), pipe(myPipe)}}}. Queries are typed to the kind of expected result object: {{{Query<Pipe> ("stream(mpeg)")}}} requests a pipe excepting/delivering mpeg stream data &mdash; and it depends on the current configuration what "mpeg" means. If there is any stream data producing component in the system, which advertises to deliver {{{stream(mpeg)}}}, and a pipe can be configured or connected with this component, then the [[defaults manager|DefaultsManagement]] will create/deliver a [[Pipe|PipeHandling]] object configured accordingly.
           &rarr; [[Configuration Rules system|ConfigRules]]
          @@ -1886,12 +1895,12 @@ But because I know the opinions on this topc are varying (users tend to be delig
           My proposed aproach is to treat OpenGL as a separate video raw data type, requiring separete and specialized [[Processing Nodes|ProcNode]] for all calculations. Thus the Builder could connect OpenGL nodes if it is possible to cover the whole render path for preview and fall back to the normal ~ProcNodes for all relevant renders
           
          -
          +
          A low-level abstraction within the [[Builder]] &mdash; it serves to encapsulate the details of making multi-channel connections between the render nodes: In some cases, a node can handle N channels internally, while in other cases we need to replicate the node N times and wire each channel individually.
           
           The operation point is provided by the current BuilderMould and used by the [[processing pattern|ProcPatt]] executing within this mould and conducting the current build step. The operation point's interface allows //to abstract//&nbsp; these details, as well as to //gain additional control//&nbsp; if necessary (e.g. addressing only one of the channels). The most prominent build instruction used within the processing patterns (which is the instruction {{{"attach"}}}) relies on the aforementioned //approach of abstracted handling,// letting the operation point determine automatically how to make the connection.
           
          -This is possible because the operation point has been provided (by the mould) with informations about the media stream type to be wired, while at the same time relying on the [[render node interface|ProcNode]] for finding out whats possible and making the desired connections.
          +This is possible because the operation point has been provided (by the mould) with informations about the media stream type to be wired, which, together with information accessible at the the [[render node interface|ProcNode]] and from the [[referred processing assets|ProcAsset]], with the help of the [[connection manager|ConManager]] allows to figure out what's possible and how to do the desired connections.
           
          @@ -3026,33 +3035,57 @@ At first sight the link between asset and clip-MO is a simple logical relation b [img[Entities comprising the Render Engine|uml/fig128389.png]]
          -
          -
          While with respect to the dependencies, the builder and the processing function, the render process is sufficiently characterized by referring to the ''pull principle'' and by defining a [[protocol|NodeOperationProtocol]] each node has to adhere to &mdash; for actually make it happen we have to care for some important details, especially //how to manage the buffers.// It may well be that the length of the code path necessary to invoke the individual processing functions is finally not so important, compared with the time spent within the inner pixel loop of these functions. But my guess is (as of 5/08), that the number of data moving and copying operations //will be//&nbsp; of importance.
          +
          +
          While the render process, with respect to the dependencies, the builder and the processing function is sufficiently characterized by referring to the ''pull principle'' and by defining a [[protocol|NodeOperationProtocol]] each node has to adhere to &mdash; for actually get it coded we have to care for some important details, especially //how to manage the buffers.// It may well be that the length of the code path necessary to invoke the individual processing functions is finally not so important, compared with the time spent at the inner pixel loop within these functions. But my guess is (as of 5/08), that the overall number of data moving and copying operations //will be//&nbsp; of importance.
           
           !reguirements
           * operations should be "in place" as much as possible
           * because caching necessitates a copy, the points where this happens should be controllable.
           * buffers should accommodate automatically to provide the necessary space without clipping the image.
           * the type of the media data can change while passing through the network, and so does the type of the buffers.
          -On the other hand, the processing function within the individual node needs to be shielded from these complexities. It can expect to get just //N~~I~~// input buffers and //N~O~// output buffers of required type. And, moreover, as the decision how to organize the buffers certainly depends on non-local circumstances, it should be preconfigured while building.
          +On the other hand, the processing function within the individual node needs to be shielded from these complexities. It can expect to get just //N~~I~~// input buffers and //N~~O~~// output buffers of required type. And, moreover, as the decision how to organize the buffers certainly depends on non-local circumstances, it should be preconfigured while building.
           
           !data flow
           [>img[uml/fig131973.png]]
          -Not everything can be preconfigured though. The pull principle opens the possibility for the node to decide on a per call base what predecessor(s) to pull (if any). This decision may rely on automation parameters, which thus need to be accessible prior to 
          -requesting the buffer(s). Additionally, in a later version we plan to have the node network calculate some control values for adjusting the cache and backend timings &mdash; and of course at some point we'll want to utilize the GPU, resulting in the need to feed data from our processing buffers into some texture representation.
          +Not everything can be preconfigured though. The pull principle opens the possibility for the node to decide on a per call base what predecessor(s) to pull (if any). This decision may rely on automation parameters, which thus need to be accessible prior to requesting the buffer(s). Additionally, in a later version we plan to have the node network calculate some control values for adjusting the cache and backend timings &mdash; and of course at some point we'll want to utilize the GPU, resulting in the need to feed data from our processing buffers into some texture representation.
           
           !buffer management
          -Besides the StateProxy representing the actual render process and holding a couple of buffer (refs), we employ a lightweight adapter object in between. It is used //for a single {{{pull()}}}-call// &mdash; mapping the actual buffers to the input and output port numbers of the processing node and for dealing with the cache calls. While the StateProxy manages a pool of frame buffers, this interspersed adapter allows us to either use a buffer retrieved from the cache as an input, possibly use a new buffer located within the cache as output, or (in case no caching happens) to just use the same buffer as input and output for "in-place"-processing. The idea is that most of the configuration of this adapter object is prepared in the wiring step while building the node network. 
          +Besides the StateProxy representing the actual render process and holding a couple of buffer (refs), we employ a lightweight adapter object in between. It is used //for a single {{{pull()}}}-call// &mdash; mapping the actual buffers to the input and output port numbers of the processing node and for dealing with the cache calls. While the StateProxy manages a pool of frame buffers, this interspersed adapter allows us to either use a buffer retrieved from the cache as an input, possibly use a new buffer located within the cache as output, or (in case no caching happens) to just use the same buffer as input and output for "in-place"-processing. The idea is that most of the configuration of this adapter object is prepared in the wiring step while building the node network.
          +
          +The usage patern of the buffers can be stack-like when processing nodes requiring multiple input buffers. In the standard case, which also is the simplest case, a pair of buffers (or a single buffer for "in-place" capable nodes) suffices to calculate a whole chain of nodes. But &mdash; as the recursive descent means depth-first processing &mdash; in case multiple input buffers are needed, we may encounter a situation where some of these input buffers already contain processed data, while we have to descend into yet another predecessor node chain to pull the data for the remaining buffers. Care has to be taken //to allocate the buffers as late as possible,// otherwise we could end up holding onto a buffer almost for each node in the network. Effectively this translates into the rule to allocate output buffers only after all input buffers are ready and filled with data; thus we shouldn't allocate buffers when //entering// the recursive call to the predecessor(s), rather we have to wait until we are about to return from the downcall chain.
          +Besides, these considerations also show we need a means of passing on the current buffer usage pattern while calling down. This usage pattern not only includes a record of what buffers are occupied, but also the intended use of these occupied buffers, especially if they can be modified in-place, and at which point they may be released and reused.
           @@clear(right):display(block):@@
           
          -
          +
          For each segment (of the effective timeline), there is a Processor holding the exit node(s) of a processing network, which is a "Directed Acyclic Graph" of small, preconfigured, stateless [[processing nodes|ProcNode]]. This network is operated according to the ''pull principle'', meaning that the rendering is just initiated by "pulling" output from the exit node, causing a cascade of recursive downcalls. Each node knows its predecessor(s) an can pull the necessary input from there. Consequently, there is no centralized "engine object" which may invoke nodes iteratively or table driven &mdash; rather, the rendering can be seen as a passive service provided for the backend, which may pull from the exit nodes at any time, in any order (?), and possibly multithreaded.
          -All State necessary for a given calculation process is encapsulated and accessible by a StateProxy object, which can be seen as the representation of "the process". At the same time, this proxy provides the buffers holding data to be processed and acts as a gateway to the backend to handle the communication with the Cache.
          +All State necessary for a given calculation process is encapsulated and accessible by a StateProxy object, which can be seen as the representation of "the process". At the same time, this proxy provides the buffers holding data to be processed and acts as a gateway to the backend to handle the communication with the Cache. In addition to this //top-level State,// each calculation step includes a small [[state adapter object|StateAdapter]] (stack allocated), which is pre-configured by the builder and serves the purpose to isolate the processing function from the detals of buffer management.
           
          -{{red{TODO: fill in more details of the Render Process.}}}
          -[img[uml/fig132101.png]]
          -* see also
          +!!Example: calculating a 3 node chain
          +[img[uml/fig132229.png]]
          +# Caller invokes calculation by pulling from exit node, providing the top-level StateProxy
          +# node1 (exit node) builds StateAdapter and calls retrieve() on it to get the desired output result
          +# this StateAdapter (ad1) knows he could get the result from Cache, so he tries, but it's a miss
          +# thus he pulls from the predecessor node2 according to the [[input descriptor|ProcNodeInputDescriptor]] of node1
          +# node2 builds its StateAdapter and calls retrieve()
          +# but because StateAdapter (ad2) is configured to directly forward the call down, it pulls from node3
          +# node3 builds its StateAdapter and calls retrieve()
          +# this StateAdapter (ad3) is configured to look into the Cache...
          +# this time producing a Cache hit
          +# now StateAdapter ad2 has input data, but needs a output buffer location, which re requests from its //parent state// (ad1)
          +# and, because ad1 is configured for Caching, it's clear that this output buffer will be located within the cache
          +# thus the allocation request is forwarded to the cache, which provides a new "slot"
          +# now node2 has both a valid input and a usable output buffer, thus the process function can be invoked
          +# and after the result has been rendered into the output buffer, the input is no longer needed
          +# and can be "unlocked" in the Cache
          +# now the input data for node1 is available, and as node1 is in-place-capable, no further buffer allocation is necessary prior to calculating
          +# the finished result is now in the buffer (which happens to be also the input buffer and is actually located within the Cache)
          +# thus it can be marked as ready for the Cache, which may now provide it to other processes (but isn't allowed to overwrite it)
          +# finally, when the caller is done with the data, it signalles this to the top-level State object
          +# which forwards this information to the cache, which in turn may now do with the released Buffer as he sees fit.
          +
          +
          +__see also__
           &rarr; the [[Entities involved in Rendering|RenderEntities]]
           &rarr; the [[mechanics of rendering and buffer management|RenderMechanics]]
           &rarr; the protocol [[how to operate the nodes|NodeOperationProtocol]]
          
          From eeb2d04dee6f109831c1874150a7df8a14d35ba2 Mon Sep 17 00:00:00 2001
          From: Ichthyostega 
          Date: Sat, 14 Jun 2008 04:19:58 +0200
          Subject: [PATCH 06/12] WIP trying to translate some of the planned pull()
           process into code...
          
          ---
           doc/devel/uml/fig131973.png                 | Bin 18410 -> 19757 bytes
           src/proc/engine/aframe.cpp                  |  34 --------
           src/proc/engine/aframe.hpp                  |  41 ----------
           src/proc/engine/arender.cpp                 |  34 --------
           src/proc/engine/arender.hpp                 |  44 ----------
           src/proc/engine/exitnode.cpp                |  33 --------
           src/proc/engine/exitnode.hpp                |  45 ----------
           src/proc/engine/glbuf.cpp                   |  34 --------
           src/proc/engine/glbuf.hpp                   |  39 ---------
           src/proc/engine/glrender.cpp                |  33 --------
           src/proc/engine/glrender.hpp                |  42 ----------
           src/proc/engine/processor.cpp               |   3 +-
           src/proc/engine/processor.hpp               |   2 +-
           src/proc/engine/procnode.hpp                |  86 ++++++++++++++++----
           src/proc/{ => engine}/stateproxy.cpp        |  10 +--
           src/proc/{ => engine}/stateproxy.hpp        |  21 ++---
           src/proc/engine/vframe.cpp                  |  33 --------
           src/proc/engine/vframe.hpp                  |  41 ----------
           src/proc/engine/vrender.cpp                 |  33 --------
           src/proc/engine/vrender.hpp                 |  47 -----------
           src/proc/mobject/controller/renderstate.cpp |  44 ----------
           src/proc/mobject/controller/renderstate.hpp |   7 +-
           src/proc/{frame.cpp => state.cpp}           |   5 +-
           src/proc/{frame.hpp => state.hpp}           |  31 ++++---
           uml/lumiera/131973.diagram                  |  40 ++++-----
           wiki/renderengine.html                      |  33 +++++---
           26 files changed, 155 insertions(+), 660 deletions(-)
           delete mode 100644 src/proc/engine/aframe.cpp
           delete mode 100644 src/proc/engine/aframe.hpp
           delete mode 100644 src/proc/engine/arender.cpp
           delete mode 100644 src/proc/engine/arender.hpp
           delete mode 100644 src/proc/engine/exitnode.cpp
           delete mode 100644 src/proc/engine/exitnode.hpp
           delete mode 100644 src/proc/engine/glbuf.cpp
           delete mode 100644 src/proc/engine/glbuf.hpp
           delete mode 100644 src/proc/engine/glrender.cpp
           delete mode 100644 src/proc/engine/glrender.hpp
           rename src/proc/{ => engine}/stateproxy.cpp (81%)
           rename src/proc/{ => engine}/stateproxy.hpp (73%)
           delete mode 100644 src/proc/engine/vframe.cpp
           delete mode 100644 src/proc/engine/vframe.hpp
           delete mode 100644 src/proc/engine/vrender.cpp
           delete mode 100644 src/proc/engine/vrender.hpp
           delete mode 100644 src/proc/mobject/controller/renderstate.cpp
           rename src/proc/{frame.cpp => state.cpp} (80%)
           rename src/proc/{frame.hpp => state.hpp} (56%)
          
          diff --git a/doc/devel/uml/fig131973.png b/doc/devel/uml/fig131973.png
          index 7ed45dca7a110940795f165d53c21648bc62223e..be9cb51564238eb28f1a53ac2650c41be296ed25 100644
          GIT binary patch
          literal 19757
          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
          OkMs+9XyLQBKK~0|cLhZN
          
          literal 18410
          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
          
          diff --git a/src/proc/engine/aframe.cpp b/src/proc/engine/aframe.cpp
          deleted file mode 100644
          index e8713897b..000000000
          --- a/src/proc/engine/aframe.cpp
          +++ /dev/null
          @@ -1,34 +0,0 @@
          -/*
          -  AFrame  -  buffer holding a Audio samples for the render process
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program is free software; you can redistribute it and/or
          -  modify it under the terms of the GNU General Public License as
          -  published by the Free Software Foundation; either version 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program is distributed in the hope that it will be useful,
          -  but WITHOUT ANY WARRANTY; without even the implied warranty of
          -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          -  GNU General Public License for more details.
          - 
          -  You should have received a copy of the GNU General Public License
          -  along with this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -* *****************************************************/
          -
          -
          -#include "proc/engine/aframe.hpp"
          -
          -namespace engine
          -  {
          -
          -  /** */
          -
          -
          -
          -
          -} // namespace engine
          diff --git a/src/proc/engine/aframe.hpp b/src/proc/engine/aframe.hpp
          deleted file mode 100644
          index 0d77e15ca..000000000
          --- a/src/proc/engine/aframe.hpp
          +++ /dev/null
          @@ -1,41 +0,0 @@
          -/*
          -  AFRAME.hpp  -  buffer holding a Audio samples for the render process
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program is free software; you can redistribute it and/or
          -  modify it under the terms of the GNU General Public License as
          -  published by the Free Software Foundation; either version 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program is distributed in the hope that it will be useful,
          -  but WITHOUT ANY WARRANTY; without even the implied warranty of
          -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          -  GNU General Public License for more details.
          - 
          -  You should have received a copy of the GNU General Public License
          -  along with this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -*/
          -
          -
          -#ifndef ENGINE_AFRAME_H
          -#define ENGINE_AFRAME_H
          -
          -#include "proc/frame.hpp"
          -
          -
          -
          -namespace engine
          -  {
          -
          -
          -  class AFrame : public proc_interface::Frame
          -    {};
          -
          -
          -
          -} // namespace engine
          -#endif
          diff --git a/src/proc/engine/arender.cpp b/src/proc/engine/arender.cpp
          deleted file mode 100644
          index ac7171998..000000000
          --- a/src/proc/engine/arender.cpp
          +++ /dev/null
          @@ -1,34 +0,0 @@
          -/*
          -  ARender  -  Representation of a Audio Render process
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program is free software; you can redistribute it and/or
          -  modify it under the terms of the GNU General Public License as
          -  published by the Free Software Foundation; either version 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program is distributed in the hope that it will be useful,
          -  but WITHOUT ANY WARRANTY; without even the implied warranty of
          -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          -  GNU General Public License for more details.
          - 
          -  You should have received a copy of the GNU General Public License
          -  along with this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -* *****************************************************/
          -
          -
          -#include "proc/engine/arender.hpp"
          -
          -namespace engine
          -  {
          -
          -  /** */
          -
          -
          -
          -
          -} // namespace engine
          diff --git a/src/proc/engine/arender.hpp b/src/proc/engine/arender.hpp
          deleted file mode 100644
          index 79c70c460..000000000
          --- a/src/proc/engine/arender.hpp
          +++ /dev/null
          @@ -1,44 +0,0 @@
          -/*
          -  ARENDER.hpp  -  Representation of a Audio Render process
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program is free software; you can redistribute it and/or
          -  modify it under the terms of the GNU General Public License as
          -  published by the Free Software Foundation; either version 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program is distributed in the hope that it will be useful,
          -  but WITHOUT ANY WARRANTY; without even the implied warranty of
          -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          -  GNU General Public License for more details.
          - 
          -  You should have received a copy of the GNU General Public License
          -  along with this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -*/
          -
          -
          -#ifndef ENGINE_ARENDER_H
          -#define ENGINE_ARENDER_H
          -
          -#include "proc/stateproxy.hpp"
          -
          -
          -
          -namespace engine
          -  {
          -  
          -  
          -  /**
          -   * Representation of a Audio render process
          -   */
          -  class ARender : public proc_interface::StateProxy
          -    {};
          -    
          -    
          -    
          -} // namespace engine
          -#endif
          diff --git a/src/proc/engine/exitnode.cpp b/src/proc/engine/exitnode.cpp
          deleted file mode 100644
          index 8c26b7cd9..000000000
          --- a/src/proc/engine/exitnode.cpp
          +++ /dev/null
          @@ -1,33 +0,0 @@
          -/*
          -  ExitNode  -  special Processing Node providing "pullable" output
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program is free software; you can redistribute it and/or
          -  modify it under the terms of the GNU General Public License as
          -  published by the Free Software Foundation; either version 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program is distributed in the hope that it will be useful,
          -  but WITHOUT ANY WARRANTY; without even the implied warranty of
          -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          -  GNU General Public License for more details.
          - 
          -  You should have received a copy of the GNU General Public License
          -  along with this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -* *****************************************************/
          -
          -
          -#include "proc/engine/exitnode.hpp"
          -
          -namespace engine
          -  {
          -
          -  /** */
          -
          -
          -
          -} // namespace engine
          diff --git a/src/proc/engine/exitnode.hpp b/src/proc/engine/exitnode.hpp
          deleted file mode 100644
          index 1cb6e51c2..000000000
          --- a/src/proc/engine/exitnode.hpp
          +++ /dev/null
          @@ -1,45 +0,0 @@
          -/*
          -  EXITNODE.hpp  -  special Processing Node providing "pullable" output
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program is free software; you can redistribute it and/or
          -  modify it under the terms of the GNU General Public License as
          -  published by the Free Software Foundation; either version 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program is distributed in the hope that it will be useful,
          -  but WITHOUT ANY WARRANTY; without even the implied warranty of
          -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          -  GNU General Public License for more details.
          - 
          -  You should have received a copy of the GNU General Public License
          -  along with this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -*/
          -
          -
          -#ifndef ENGINE_EXITNODE_H
          -#define ENGINE_EXITNODE_H
          -
          -#include "proc/engine/procnode.hpp"
          -
          -
          -
          -namespace engine
          -  {
          -
          -
          -  /**
          -   * The output end of each render pipeline.
          -   * Pulling from such exit nodes actually ivokes the render process
          -   */
          -  class ExitNode : public ProcNode
          -    {};
          -
          -
          -
          -} // namespace engine
          -#endif
          diff --git a/src/proc/engine/glbuf.cpp b/src/proc/engine/glbuf.cpp
          deleted file mode 100644
          index 6970a3114..000000000
          --- a/src/proc/engine/glbuf.cpp
          +++ /dev/null
          @@ -1,34 +0,0 @@
          -/*
          -  GLBuf  -  a buffer and render process holding a Video frame for OpenGL rendering
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program is free software; you can redistribute it and/or
          -  modify it under the terms of the GNU General Public License as
          -  published by the Free Software Foundation; either version 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program is distributed in the hope that it will be useful,
          -  but WITHOUT ANY WARRANTY; without even the implied warranty of
          -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          -  GNU General Public License for more details.
          - 
          -  You should have received a copy of the GNU General Public License
          -  along with this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -* *****************************************************/
          -
          -
          -#include "proc/engine/glbuf.hpp"
          -
          -namespace engine
          -  {
          -
          -  /** */
          -
          -
          -
          -
          -} // namespace engine
          diff --git a/src/proc/engine/glbuf.hpp b/src/proc/engine/glbuf.hpp
          deleted file mode 100644
          index 8e8ee2ea5..000000000
          --- a/src/proc/engine/glbuf.hpp
          +++ /dev/null
          @@ -1,39 +0,0 @@
          -/*
          -  GLBUF.hpp  -  a buffer and render process holding a Video frame for OpenGL rendering
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program is free software; you can redistribute it and/or
          -  modify it under the terms of the GNU General Public License as
          -  published by the Free Software Foundation; either version 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program is distributed in the hope that it will be useful,
          -  but WITHOUT ANY WARRANTY; without even the implied warranty of
          -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          -  GNU General Public License for more details.
          - 
          -  You should have received a copy of the GNU General Public License
          -  along with this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -*/
          -
          -
          -#ifndef ENGINE_GLBUF_H
          -#define ENGINE_GLBUF_H
          -
          -#include "proc/frame.hpp"
          -
          -
          -
          -namespace engine
          -  {
          -
          -
          -  class GLBuf : public proc_interface::Frame
          -    {};
          -
          -} // namespace engine
          -#endif
          diff --git a/src/proc/engine/glrender.cpp b/src/proc/engine/glrender.cpp
          deleted file mode 100644
          index 32420201b..000000000
          --- a/src/proc/engine/glrender.cpp
          +++ /dev/null
          @@ -1,33 +0,0 @@
          -/*
          -  GLRender  -  Representation of a OpenGL accellerated Video render process
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program is free software; you can redistribute it and/or
          -  modify it under the terms of the GNU General Public License as
          -  published by the Free Software Foundation; either version 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program is distributed in the hope that it will be useful,
          -  but WITHOUT ANY WARRANTY; without even the implied warranty of
          -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          -  GNU General Public License for more details.
          - 
          -  You should have received a copy of the GNU General Public License
          -  along with this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -* *****************************************************/
          -
          -
          -#include "proc/engine/glrender.hpp"
          -
          -namespace engine
          -  {
          -
          -  /** */
          -
          -
          -
          -} // namespace engine
          diff --git a/src/proc/engine/glrender.hpp b/src/proc/engine/glrender.hpp
          deleted file mode 100644
          index e9c73c3a3..000000000
          --- a/src/proc/engine/glrender.hpp
          +++ /dev/null
          @@ -1,42 +0,0 @@
          -/*
          -  GLRENDER.hpp  -  Representation of a OpenGL accellerated Video render process
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program is free software; you can redistribute it and/or
          -  modify it under the terms of the GNU General Public License as
          -  published by the Free Software Foundation; either version 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program is distributed in the hope that it will be useful,
          -  but WITHOUT ANY WARRANTY; without even the implied warranty of
          -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          -  GNU General Public License for more details.
          - 
          -  You should have received a copy of the GNU General Public License
          -  along with this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -*/
          -
          -
          -#ifndef ENGINE_GLRENDER_H
          -#define ENGINE_GLRENDER_H
          -
          -#include "proc/stateproxy.hpp"
          -
          -
          -
          -namespace engine
          -  {
          -
          -
          -  /**
          -   * Representation of a OpenGL accelerated Video render process
          -   */
          -  class GLRender : public proc_interface::StateProxy
          -    {};
          -
          -} // namespace engine
          -#endif
          diff --git a/src/proc/engine/processor.cpp b/src/proc/engine/processor.cpp
          index c8a228845..38ed34c5d 100644
          --- a/src/proc/engine/processor.cpp
          +++ b/src/proc/engine/processor.cpp
          @@ -22,8 +22,7 @@
           
           
           #include "proc/engine/processor.hpp"
          -#include "proc/engine/exitnode.hpp"
          -#include "proc/stateproxy.hpp"
          +#include "proc/state.hpp"
           
           namespace engine
             {
          diff --git a/src/proc/engine/processor.hpp b/src/proc/engine/processor.hpp
          index 164fa8bfa..3f0890c93 100644
          --- a/src/proc/engine/processor.hpp
          +++ b/src/proc/engine/processor.hpp
          @@ -25,7 +25,7 @@
           #define ENGINE_PROCESSOR_H
           
           #include "proc/lumiera.hpp"
          -#include "proc/stateproxy.hpp"
          +#include "proc/state.hpp"
           
           
           
          diff --git a/src/proc/engine/procnode.hpp b/src/proc/engine/procnode.hpp
          index e2a4c89b9..a3dc5d702 100644
          --- a/src/proc/engine/procnode.hpp
          +++ b/src/proc/engine/procnode.hpp
          @@ -26,6 +26,7 @@
           
           #include 
           
          +#include "proc/state.hpp"
           #include "proc/mobject/parameter.hpp"
           
           
          @@ -34,25 +35,63 @@
           namespace engine {
           
             using std::vector;
          +  using proc_interface::State;
             
             class ProcNode;
             class NodeFactory;
             
          -  typedef ProcNode* PNode;    ///< @todo handle ProcNode by pointer or by shared-ptr??
          -
          +  typedef ProcNode* PNode;
          +  
          +  
          +  /**
          +   * Description of the input and output ports and the
          +   * predecessor nodes for a given ProcNode.
          +   */
          +  struct WiringDescriptor
          +    {
          +      
          +    };
          +    
           
          +  /**
          +   * Adapter to shield the ProcNode from the actual buffer management,
          +   * allowing the processing function within ProcNode to use logical
          +   * buffer IDs. StateAdapter is created on the stack for each pull()
          +   * call, using setup/wiring data preconfigured by the builder.
          +   * Its job is to provide the actual implementation of the Cache
          +   * push / fetch and recursive downcall to render the source frames.
          +   */
          +  class StateAdapter
          +    : public State
          +    {
          +      State& parent_;
          +      State& current_;
          +      
          +    protected:
          +      StateAdapter (State& callingProcess, WiringDescriptor const&) 
          +        : parent_ (callingProcess),
          +          current_(callingProcess.getCurrentImplementation())
          +        { }
          +      
          +      friend class ProcNode; // both are sharing implementation details...
          +      
          +      
          +      virtual State& getCurrentImplementation () { return current_; }
          +      
          +      /** contains the details of Cache query and recursive calls
          +       *  to the predecessor node(s), eventually followed by the 
          +       *  ProcNode::process() callback
          +       */
          +      void retrieve();
          +    };
          +  
          +  
             /**
              * Key abstraction of the Render Engine: A Data processing Node
              */
             class ProcNode
               {
          -      typedef mobject::Parameter Param;
          -
          -      /** The predecessor in a processing pipeline.
          -       *  I.e. a source to get data to be processed
          -       */
          -      PNode datasrc;
          -
          +      typedef mobject::Parameter Param;   //////TODO: just a placeholder for automation as of 6/2008
                 vector params;
           
               protected:
          @@ -62,20 +101,35 @@ namespace engine {
                 friend class NodeFactory;
                 
                 
          -      /** do the actual calculations.
          +      /** Callback doing the actual calculations
          +       *  after input / output buffers are ready
                  *  @internal dispatch to implementation. 
          -       *            Client code should use #render()
          -       *  @todo obviously we need a parameter!!!
          +       *            Client code should use #pull()
                  */
          -      virtual void process() = 0;
          +      virtual void process(State&) = 0;
          +      
          +      friend void StateAdapter::retrieve();  // to issue the process() callback if necessary
          +      
          +      
          +      /** Extension point for subclasses to modify the input sources
          +       *  according to automation data and other state dependent properties. 
          +       */
          +      virtual WiringDescriptor const& getWiring (State&); 
          +      
           
               public:
                 static NodeFactory create;
                 
          -      /** render and pull output from this node.
          -       *  @todo define the parameter!!!
          +      /** Engine Core operation: render and pull output from this node.
          +       *  On return, currentProcess will hold onto output buffer(s)
          +       *  containing the calculated result frames.
                  */
          -      void render() { this->process(); }
          +      void 
          +      pull (State& currentProcess) 
          +        {
          +          StateAdapter thisStep (currentProcess, getWiring (currentProcess));
          +          thisStep.retrieve(); // fetch or calculate results
          +        }
           
               };
           
          diff --git a/src/proc/stateproxy.cpp b/src/proc/engine/stateproxy.cpp
          similarity index 81%
          rename from src/proc/stateproxy.cpp
          rename to src/proc/engine/stateproxy.cpp
          index f4125a41e..6e2566d3e 100644
          --- a/src/proc/stateproxy.cpp
          +++ b/src/proc/engine/stateproxy.cpp
          @@ -1,5 +1,5 @@
           /*
          -  StateProxy  -  Key Interface representing a render process and encapsulating state
          +  StateProxy  -  Encapsulation of the state corresponding to a render calculation
            
             Copyright (C)         Lumiera.org
               2008,               Hermann Vosseler 
          @@ -21,14 +21,12 @@
           * *****************************************************/
           
           
          -#include "proc/stateproxy.hpp"
          -#include "proc/frame.hpp"
          +#include "proc/engine/stateproxy.hpp"
           
          -namespace proc_interface
          -  {
          +namespace engine {
             
             /** */
             
             
             
          -} // namespace proc_interface
          +} // namespace engine
          diff --git a/src/proc/stateproxy.hpp b/src/proc/engine/stateproxy.hpp
          similarity index 73%
          rename from src/proc/stateproxy.hpp
          rename to src/proc/engine/stateproxy.hpp
          index 7c338bd1d..ff7d107d3 100644
          --- a/src/proc/stateproxy.hpp
          +++ b/src/proc/engine/stateproxy.hpp
          @@ -1,5 +1,5 @@
           /*
          -  STATEPROXY.hpp  -  Key Interface representing a render process and encapsulating state
          +  STATEPROXY.hpp  -  Encapsulation of the state corresponding to a render calculation
            
             Copyright (C)         Lumiera.org
               2008,               Hermann Vosseler 
          @@ -21,25 +21,26 @@
           */
           
           
          -#ifndef PROC_INTERFACE_STATEPROXY_H
          -#define PROC_INTERFACE_STATEPROXY_H
          -
          -#include "proc/frame.hpp"
          +#ifndef ENGINE_STATEPROXY_H
          +#define ENGINE_STATEPROXY_H
           
           
          +#include "proc/state.hpp"
          +
          +
          +namespace engine {
           
          -namespace proc_interface
          -  {
           
           
             class StateProxy
          +    : public proc_interface::State
               {
               protected:
          -      Frame * currFrame;
          -
          +      virtual State& getCurrentImplementation () { return *this; }
          +      
               };
               
               
               
          -} // namespace proc_interface
          +} // namespace engine
           #endif
          diff --git a/src/proc/engine/vframe.cpp b/src/proc/engine/vframe.cpp
          deleted file mode 100644
          index 180faca70..000000000
          --- a/src/proc/engine/vframe.cpp
          +++ /dev/null
          @@ -1,33 +0,0 @@
          -/*
          -  VFrame  -  a buffer holding a Video frame for the render process 
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program is free software; you can redistribute it and/or
          -  modify it under the terms of the GNU General Public License as
          -  published by the Free Software Foundation; either version 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program is distributed in the hope that it will be useful,
          -  but WITHOUT ANY WARRANTY; without even the implied warranty of
          -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          -  GNU General Public License for more details.
          - 
          -  You should have received a copy of the GNU General Public License
          -  along with this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -* *****************************************************/
          -
          -
          -#include "proc/engine/vframe.hpp"
          -
          -namespace engine
          -  {
          -
          -  /** */
          -
          -
          -
          -} // namespace engine
          diff --git a/src/proc/engine/vframe.hpp b/src/proc/engine/vframe.hpp
          deleted file mode 100644
          index 6b1e8153b..000000000
          --- a/src/proc/engine/vframe.hpp
          +++ /dev/null
          @@ -1,41 +0,0 @@
          -/*
          -  VFRAME.hpp  -  a buffer holding a Video frame for the render process 
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program is free software; you can redistribute it and/or
          -  modify it under the terms of the GNU General Public License as
          -  published by the Free Software Foundation; either version 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program is distributed in the hope that it will be useful,
          -  but WITHOUT ANY WARRANTY; without even the implied warranty of
          -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          -  GNU General Public License for more details.
          - 
          -  You should have received a copy of the GNU General Public License
          -  along with this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -*/
          -
          -
          -#ifndef ENGINE_VFRAME_H
          -#define ENGINE_VFRAME_H
          -
          -#include "proc/frame.hpp"
          -
          -
          -
          -namespace engine
          -  {
          -
          -
          -  class VFrame : public proc_interface::Frame
          -    {
          -      ///////////////////////
          -    };
          -
          -} // namespace engine
          -#endif
          diff --git a/src/proc/engine/vrender.cpp b/src/proc/engine/vrender.cpp
          deleted file mode 100644
          index 2bed41099..000000000
          --- a/src/proc/engine/vrender.cpp
          +++ /dev/null
          @@ -1,33 +0,0 @@
          -/*
          -  VRender  -  Representation of a Video render process
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program is free software; you can redistribute it and/or
          -  modify it under the terms of the GNU General Public License as
          -  published by the Free Software Foundation; either version 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program is distributed in the hope that it will be useful,
          -  but WITHOUT ANY WARRANTY; without even the implied warranty of
          -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          -  GNU General Public License for more details.
          - 
          -  You should have received a copy of the GNU General Public License
          -  along with this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -* *****************************************************/
          -
          -
          -#include "proc/engine/vrender.hpp"
          -
          -namespace engine
          -  {
          -
          -  /** */
          -
          -
          -
          -  } // namespace engine
          diff --git a/src/proc/engine/vrender.hpp b/src/proc/engine/vrender.hpp
          deleted file mode 100644
          index c6a34bda2..000000000
          --- a/src/proc/engine/vrender.hpp
          +++ /dev/null
          @@ -1,47 +0,0 @@
          -/*
          -  VRENDER.hpp  -  Representation of a Video render process
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program is free software; you can redistribute it and/or
          -  modify it under the terms of the GNU General Public License as
          -  published by the Free Software Foundation; either version 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program is distributed in the hope that it will be useful,
          -  but WITHOUT ANY WARRANTY; without even the implied warranty of
          -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          -  GNU General Public License for more details.
          - 
          -  You should have received a copy of the GNU General Public License
          -  along with this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -*/
          -
          -
          -#ifndef ENGINE_VRENDER_H
          -#define ENGINE_VRENDER_H
          -
          -#include "proc/stateproxy.hpp"
          -
          -
          -
          -namespace engine
          -  {
          -
          -
          -  /**
          -   * Representation of a Video render process.
          -   * (Encapsulates the video buffers for the actual calculations)
          -   */
          -  class VRender : public proc_interface::StateProxy
          -    {
          -      /////////////
          -    };
          -
          -
          -
          -} // namespace engine
          -#endif
          diff --git a/src/proc/mobject/controller/renderstate.cpp b/src/proc/mobject/controller/renderstate.cpp
          deleted file mode 100644
          index 98ca2ccd1..000000000
          --- a/src/proc/mobject/controller/renderstate.cpp
          +++ /dev/null
          @@ -1,44 +0,0 @@
          -/*
          -  RenderState  -  renderengine state manager
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program is free software; you can redistribute it and/or
          -  modify it under the terms of the GNU General Public License as
          -  published by the Free Software Foundation; either version 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program is distributed in the hope that it will be useful,
          -  but WITHOUT ANY WARRANTY; without even the implied warranty of
          -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          -  GNU General Public License for more details.
          - 
          -  You should have received a copy of the GNU General Public License
          -  along with this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -* *****************************************************/
          -
          -
          -#include "proc/mobject/controller/renderstate.hpp"
          -
          -
          -namespace mobject
          -  {
          -  namespace controller
          -    {
          -
          -
          -
          -    StateProxy&
          -    RenderState::getStateProxy ()
          -    {
          -      //////////////TODO
          -    }
          -
          -
          -
          -  } // namespace mobject::controller
          -
          -} // namespace mobject
          diff --git a/src/proc/mobject/controller/renderstate.hpp b/src/proc/mobject/controller/renderstate.hpp
          index c547772ea..833e2d347 100644
          --- a/src/proc/mobject/controller/renderstate.hpp
          +++ b/src/proc/mobject/controller/renderstate.hpp
          @@ -24,7 +24,7 @@
           #ifndef MOBJECT_CONTROLLER_RENDERSTATE_H
           #define MOBJECT_CONTROLLER_RENDERSTATE_H
           
          -#include "proc/stateproxy.hpp"
          +#include "proc/state.hpp"
           
           
           
          @@ -33,7 +33,7 @@ namespace mobject
             namespace controller
               {
           
          -    typedef proc_interface::StateProxy StateProxy;
          +    typedef proc_interface::State State;
           
           
               /**
          @@ -42,11 +42,12 @@ namespace mobject
                * The provided StateProxy serves to hold any mutalbe state used
                * in the render process, so the rest of the render engine 
                * can be stateless.
          +     * @todo probably the state management will work different (6/08)
                */
               class RenderState
                 {
                 public:
          -        StateProxy& getStateProxy () ;
          +        State& getRenderProcess () ;
                 };
           
           
          diff --git a/src/proc/frame.cpp b/src/proc/state.cpp
          similarity index 80%
          rename from src/proc/frame.cpp
          rename to src/proc/state.cpp
          index 46ad06950..fa9f32dc3 100644
          --- a/src/proc/frame.cpp
          +++ b/src/proc/state.cpp
          @@ -1,5 +1,5 @@
           /*
          -  Frame  -  Key Abstraction: render process and buffer holding frame data.
          +  State  -  Key Interface representing a render process and encapsulating state
            
             Copyright (C)         Lumiera.org
               2008,               Hermann Vosseler 
          @@ -21,11 +21,12 @@
           * *****************************************************/
           
           
          -#include "proc/frame.hpp"
          +#include "proc/state.hpp"
           
           namespace proc_interface
             {
             
          +  ////////////////////////////////TODO: State is a high -level interface, so can we get rid of this implementation file?
             /** */
             
             
          diff --git a/src/proc/frame.hpp b/src/proc/state.hpp
          similarity index 56%
          rename from src/proc/frame.hpp
          rename to src/proc/state.hpp
          index 239987e97..98fe1aa9f 100644
          --- a/src/proc/frame.hpp
          +++ b/src/proc/state.hpp
          @@ -1,5 +1,5 @@
           /*
          -  FRAME.hpp  -  Key Abstraction: render process and buffer holding frame data.
          +  STATE.hpp  -  Key Interface representing a render process and encapsulating state
            
             Copyright (C)         Lumiera.org
               2008,               Hermann Vosseler 
          @@ -21,23 +21,34 @@
           */
           
           
          -#ifndef PROC_INTERFACE_FRAME_H
          -#define PROC_INTERFACE_FRAME_H
          +#ifndef PROC_INTERFACE_STATE_H
          +#define PROC_INTERFACE_STATE_H
           
           
           
          +namespace engine { class StateAdapter; }
          +
           namespace proc_interface
             {
           
           
          -  /**
          -   * TODO: how to relate to Cehteh's Frame entity in the Backend?
          -   * The latter is the fundamental Frame entity, wheras this Object 
          -   * rather represents a buffer set containing frame date.
          -   */
          -  class Frame
          +  class State
               {
          -      /////////////////
          +    protected:
          +      virtual ~State() {};
          +      
          +      /** resolves to the State object currently "in charge".
          +       *  Intended as a performance shortcut to avoid calling
          +       *  up through a chain of virtual functions when deep down
          +       *  in chained ProcNode::pull() calls. This allows derived
          +       *  classes to proxy the state inteface.
          +       */ 
          +      virtual State& getCurrentImplementation () =0;
          +      
          +      friend class engine::StateAdapter;
          +      
          +    public:
          +      
               };
               
               
          diff --git a/uml/lumiera/131973.diagram b/uml/lumiera/131973.diagram
          index 7a9c0af13..42c38a979 100644
          --- a/uml/lumiera/131973.diagram
          +++ b/uml/lumiera/131973.diagram
          @@ -2,58 +2,58 @@ format 40
           
           classcanvas 128005 class_ref 131717 // ProcNode
             draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default
          -  xyz 106 313 2004
          +  xyz 103 405 2004
             end
           classcanvas 128517 class_ref 132741 // State
             draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default
          -  xyz 79 -16 2000
          +  xyz 77 18 2000
             end
           classcanvas 129669 class_ref 133253 // Frame
             draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default
          -  xyz 267 221 3005
          +  xyz 264 313 3005
             end
           classcanvas 131845 class_ref 142469 // StateProxy
             draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default
          -  xyz 149 135 2000
          +  xyz 146 227 2000
             end
           classcanvas 131973 class_ref 142597 // StateAdapter
             draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default
          -  xyz 43 225 3010
          +  xyz 40 317 3010
             end
           classcanvas 132357 class_ref 142725 // InputDescriptor
             draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default
          -  xyz 233 434 2000
          +  xyz 230 526 2000
             end
           relationcanvas 129797 relation_ref 134533 // 
          -  from ref 128517 z 1999 stereotype "<>" xyz 282 103 3000 to point 303 129
          +  from ref 128517 z 1999 stereotype "<>" xyz 277 115 3000 to point 300 136
             line 130053 z 1999 to ref 129669
          -  role_a_pos 315 196 3000 no_role_b
          -  no_multiplicity_a multiplicity_b_pos 175 84 3000
          +  role_a_pos 312 288 3000 no_role_b
          +  no_multiplicity_a multiplicity_b_pos 173 109 3000
           relationcanvas 132101 relation_ref 148869 // 
             geometry VHV unfixed
          -  from ref 131973 z 1999 to point 81 108
          -  line 134021 z 1999 to point 120 108
          +  from ref 131973 z 1999 to point 78 189
          +  line 134021 z 1999 to point 118 189
             line 134149 z 1999 to ref 128517
             no_role_a no_role_b
             no_multiplicity_a no_multiplicity_b
           relationcanvas 132229 relation_ref 148997 // 
             geometry VHV
          -  from ref 131845 z 1999 to point 201 126
          -  line 134277 z 1999 to point 120 126
          +  from ref 131845 z 1999 to point 198 189
          +  line 134277 z 1999 to point 118 189
             line 134405 z 1999 to ref 128517
             no_role_a no_role_b
             no_multiplicity_a no_multiplicity_b
           relationcanvas 132485 relation_ref 149125 // 
             geometry HV
          -  from ref 128005 z 1999 stereotype "<>" xyz 220 359 3000 to point 278 360
          +  from ref 128005 z 1999 stereotype "<>" xyz 217 451 3000 to point 275 452
             line 133381 z 1999 to ref 132357
          -  role_a_pos 290 409 3000 no_role_b
          -  multiplicity_a_pos 266 409 3000 no_multiplicity_b
          +  role_a_pos 287 501 3000 no_role_b
          +  multiplicity_a_pos 263 501 3000 no_multiplicity_b
           relationcanvas 133509 relation_ref 149253 // 
          -  from ref 131973 z 1999 to point 200 215
          +  from ref 131973 z 1999 to point 197 307
             line 133637 z 1999 to ref 131845
          -  role_a_pos 180 222 3000 no_role_b
          -  multiplicity_a_pos 185 199 3000 no_multiplicity_b
          +  role_a_pos 177 314 3000 no_role_b
          +  multiplicity_a_pos 182 291 3000 no_multiplicity_b
           relationcanvas 134533 relation_ref 149381 // 
             from ref 131973 z 3004 to ref 129669
             no_role_a no_role_b
          @@ -61,7 +61,7 @@ relationcanvas 134533 relation_ref 149381 // 
           line 134661 -_-_
             from ref 131973 z 2003 to ref 128005
           line 134789 -_-_
          -  from ref 131973 z 2003 to point 137 322
          +  from ref 131973 z 2003 to point 134 414
             line 134917 z 2003 to ref 128005
           preferred_whz 414 544 1
           end
          diff --git a/wiki/renderengine.html b/wiki/renderengine.html
          index 6f55a4ef0..6c6366bb0 100644
          --- a/wiki/renderengine.html
          +++ b/wiki/renderengine.html
          @@ -1839,14 +1839,16 @@ So, when creating a clip out of such a compound media asset, the clip has to be
           
          NodeCreaterTool is a [[visiting tool|VisitorUse]] used as second step in the [[Builder]]. Starting out from a [[Fixture]], the builder first [[divides the Timeline into segments|SegmentationTool]] and then processes each segment with the NodeCreaterTool to build a render nodes network (Render Engine) for this part of the timeline. While visiting individual Objects and Placements, the NodeCreaterTool creates and wires the necessary [[nodes|ProcNode]]
          -
          +
          The [[nodes|ProcNode]] are wired to form a "Directed Acyclic Graph"; each node knows its predecessor(s), but not its successor(s).  The RenderProcess is organized according to the ''pull principle'', thus we find an operation {{{pull()}}} at the core of this process. There is no such thing as an "engine object" calling nodes iteratively or table driven, rather, the nodes themselves issue recursive calls to their predecessor(s). For this to work, we need the nodes to adhere to a specific protocol:
           # Node is pulled, with a StateProxy object as parameter (encapsulating the access to the frames or buffers)
           # Node may now access current parameter values, using the state accessible via the StateProxy
          -# Node calles back into the StateProxy for getting the input buffer(s), providing it's //input descriptor//
          -# StateProxy tries to get the input frames from the Cache in the Backend. In case of failure, the call is forwarded according to the input descriptor
          -# after this call returns, the Node is allowed to dereference the frame pointers and do its calculations
          -# finally, when the {{{pull()}}} call returns, the StateProxy may push down the result frames to the cache
          +# using it's //input-output descriptor,// the Node creates a StateAdapter wrapping the StateProxy for accessing the output to pull and probably the input needed to calculate this output
          +# StateAdapter first tries to get the output frames from the Cache in the Backend. In case of failure, a {{{process()}}} call is prepared by generating {{{pull()}}} call(s) for the input
          +# as late as possible, typically on return, these recursive pull-calls have allocated a buffer containing the input data.
          +# after all input is ready and prior to the {{{process()}}} call, the output buffers will be allocated, either from the cache, or alternatively (if not caching) from the "parent" StateAdapter up the callstack.
          +# after all buffers are available, the StateAdapter issues the {{{process()}}} call back to the originating node, which now may dereference the frame pointers and do its calculations
          +# finally, when the {{{pull()}}} call returns, "parent" state originating the pull holds onto the buffers containing the calculated output result.
           some points to note:
           * the input descriptor is {{{const}}} and precalculated while building (remember another thread may call in parallel)
           * when a node is "inplace-capable", input and output buffer may actually point to the same location
          @@ -3035,7 +3037,7 @@ At first sight the link between asset and clip-MO is a simple logical relation b
           [img[Entities comprising the Render Engine|uml/fig128389.png]]
           
          -
          +
          While the render process, with respect to the dependencies, the builder and the processing function is sufficiently characterized by referring to the ''pull principle'' and by defining a [[protocol|NodeOperationProtocol]] each node has to adhere to &mdash; for actually get it coded we have to care for some important details, especially //how to manage the buffers.// It may well be that the length of the code path necessary to invoke the individual processing functions is finally not so important, compared with the time spent at the inner pixel loop within these functions. But my guess is (as of 5/08), that the overall number of data moving and copying operations //will be//&nbsp; of importance.
           
           !reguirements
          @@ -3054,15 +3056,8 @@ Besides the StateProxy representing the actual render process and holding a coup
           
           The usage patern of the buffers can be stack-like when processing nodes requiring multiple input buffers. In the standard case, which also is the simplest case, a pair of buffers (or a single buffer for "in-place" capable nodes) suffices to calculate a whole chain of nodes. But &mdash; as the recursive descent means depth-first processing &mdash; in case multiple input buffers are needed, we may encounter a situation where some of these input buffers already contain processed data, while we have to descend into yet another predecessor node chain to pull the data for the remaining buffers. Care has to be taken //to allocate the buffers as late as possible,// otherwise we could end up holding onto a buffer almost for each node in the network. Effectively this translates into the rule to allocate output buffers only after all input buffers are ready and filled with data; thus we shouldn't allocate buffers when //entering// the recursive call to the predecessor(s), rather we have to wait until we are about to return from the downcall chain.
           Besides, these considerations also show we need a means of passing on the current buffer usage pattern while calling down. This usage pattern not only includes a record of what buffers are occupied, but also the intended use of these occupied buffers, especially if they can be modified in-place, and at which point they may be released and reused.
          -@@clear(right):display(block):@@
          -
          -
          -
          -
          For each segment (of the effective timeline), there is a Processor holding the exit node(s) of a processing network, which is a "Directed Acyclic Graph" of small, preconfigured, stateless [[processing nodes|ProcNode]]. This network is operated according to the ''pull principle'', meaning that the rendering is just initiated by "pulling" output from the exit node, causing a cascade of recursive downcalls. Each node knows its predecessor(s) an can pull the necessary input from there. Consequently, there is no centralized "engine object" which may invoke nodes iteratively or table driven &mdash; rather, the rendering can be seen as a passive service provided for the backend, which may pull from the exit nodes at any time, in any order (?), and possibly multithreaded.
          -All State necessary for a given calculation process is encapsulated and accessible by a StateProxy object, which can be seen as the representation of "the process". At the same time, this proxy provides the buffers holding data to be processed and acts as a gateway to the backend to handle the communication with the Cache. In addition to this //top-level State,// each calculation step includes a small [[state adapter object|StateAdapter]] (stack allocated), which is pre-configured by the builder and serves the purpose to isolate the processing function from the detals of buffer management.
           
           !!Example: calculating a 3 node chain
          -[img[uml/fig132229.png]]
           # Caller invokes calculation by pulling from exit node, providing the top-level StateProxy
           # node1 (exit node) builds StateAdapter and calls retrieve() on it to get the desired output result
           # this StateAdapter (ad1) knows he could get the result from Cache, so he tries, but it's a miss
          @@ -3083,6 +3078,18 @@ All State necessary for a given calculation process is encapsulated and accessib
           # thus it can be marked as ready for the Cache, which may now provide it to other processes (but isn't allowed to overwrite it)
           # finally, when the caller is done with the data, it signalles this to the top-level State object
           # which forwards this information to the cache, which in turn may now do with the released Buffer as he sees fit.
          +[img[uml/fig132229.png]]
          +
          +@@clear(right):display(block):@@
          +__see also__
          +&rarr; the [[Entities involved in Rendering|RenderEntities]]
          +&rarr; [[Memory management for render nodes|ManagementRenderNodes]]
          +&rarr; the protocol [[how to operate the nodes|NodeOperationProtocol]]
          +
          +
          +
          +
          For each segment (of the effective timeline), there is a Processor holding the exit node(s) of a processing network, which is a "Directed Acyclic Graph" of small, preconfigured, stateless [[processing nodes|ProcNode]]. This network is operated according to the ''pull principle'', meaning that the rendering is just initiated by "pulling" output from the exit node, causing a cascade of recursive downcalls. Each node knows its predecessor(s) an can pull the necessary input from there. Consequently, there is no centralized "engine object" which may invoke nodes iteratively or table driven &mdash; rather, the rendering can be seen as a passive service provided for the backend, which may pull from the exit nodes at any time, in any order (?), and possibly multithreaded.
          +All State necessary for a given calculation process is encapsulated and accessible by a StateProxy object, which can be seen as the representation of "the process". At the same time, this proxy provides the buffers holding data to be processed and acts as a gateway to the backend to handle the communication with the Cache. In addition to this //top-level State,// each calculation step includes a small [[state adapter object|StateAdapter]] (stack allocated), which is pre-configured by the builder and serves the purpose to isolate the processing function from the detals of buffer management.
           
           
           __see also__
          
          From da49742826823bfb5e5bff85724e6efc096544dd Mon Sep 17 00:00:00 2001
          From: Ichthyostega 
          Date: Tue, 24 Jun 2008 05:19:11 +0200
          Subject: [PATCH 07/12] WIP sorting out some details of the node network impl
          
          ---
           src/proc/engine/codecadapter.cpp  |  30 -------
           src/proc/engine/codecadapter.hpp  |  49 -----------
           src/proc/engine/glpipe.cpp        |  34 --------
           src/proc/engine/glpipe.hpp        |  46 ----------
           src/proc/engine/hub.cpp           |  34 --------
           src/proc/engine/hub.hpp           |  44 ----------
           src/proc/engine/link.hpp          |   4 +
           src/proc/engine/nodeoperation.hpp |  72 ++++++++++++++++
           src/proc/engine/nodewiring.cpp    |  49 +++++++++++
           src/proc/engine/nodewiring.hpp    |  77 +++++++++++++++++
           src/proc/engine/procnode.hpp      | 100 ++++++++++------------
           src/proc/engine/projector.hpp     |   2 +-
           src/proc/engine/source.hpp        |   4 +-
           src/proc/engine/trafo.hpp         |   4 +-
           src/proc/state.hpp                |  22 ++++-
           wiki/index.html                   | 137 +++++++++++++++++++++++++++++-
           wiki/renderengine.html            |  49 +++++++++--
           17 files changed, 448 insertions(+), 309 deletions(-)
           delete mode 100644 src/proc/engine/codecadapter.cpp
           delete mode 100644 src/proc/engine/codecadapter.hpp
           delete mode 100644 src/proc/engine/glpipe.cpp
           delete mode 100644 src/proc/engine/glpipe.hpp
           delete mode 100644 src/proc/engine/hub.cpp
           delete mode 100644 src/proc/engine/hub.hpp
           create mode 100644 src/proc/engine/nodeoperation.hpp
           create mode 100644 src/proc/engine/nodewiring.cpp
           create mode 100644 src/proc/engine/nodewiring.hpp
          
          diff --git a/src/proc/engine/codecadapter.cpp b/src/proc/engine/codecadapter.cpp
          deleted file mode 100644
          index b65694679..000000000
          --- a/src/proc/engine/codecadapter.cpp
          +++ /dev/null
          @@ -1,30 +0,0 @@
          -/*
          -  CodecAdapter  -  Processing Node for (de)coding media data
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program is free software; you can redistribute it and/or
          -  modify it under the terms of the GNU General Public License as
          -  published by the Free Software Foundation; either version 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program is distributed in the hope that it will be useful,
          -  but WITHOUT ANY WARRANTY; without even the implied warranty of
          -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          -  GNU General Public License for more details.
          - 
          -  You should have received a copy of the GNU General Public License
          -  along with this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -* *****************************************************/
          -
          -
          -#include "proc/engine/codecadapter.hpp"
          -
          -namespace engine
          -  {
          -
          -
          -} // namespace engine
          diff --git a/src/proc/engine/codecadapter.hpp b/src/proc/engine/codecadapter.hpp
          deleted file mode 100644
          index 724763eaa..000000000
          --- a/src/proc/engine/codecadapter.hpp
          +++ /dev/null
          @@ -1,49 +0,0 @@
          -/*
          -  CODECADAPTER.hpp  -  Processing Node for (de)coding media data
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program is free software; you can redistribute it and/or
          -  modify it under the terms of the GNU General Public License as
          -  published by the Free Software Foundation; either version 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program is distributed in the hope that it will be useful,
          -  but WITHOUT ANY WARRANTY; without even the implied warranty of
          -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          -  GNU General Public License for more details.
          - 
          -  You should have received a copy of the GNU General Public License
          -  along with this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -*/
          -
          -
          -#ifndef ENGINE_CODECADAPTER_H
          -#define ENGINE_CODECADAPTER_H
          -
          -#include "proc/engine/trafo.hpp"
          -
          -
          -
          -namespace engine
          -  {
          -
          -
          -  /**
          -   * Adapter for wiring an externally loaded 
          -   * codec into the render pipeline. The decoding
          -   * process thus is integrated into the framework
          -   * of the Renderengine, while the actual implementation
          -   * can be delegated to an external library accessed
          -   * through Lumiera's data backend. 
          -   */
          -  class CodecAdapter : public Trafo
          -    {};
          -
          -
          -
          -} // namespace engine
          -#endif
          diff --git a/src/proc/engine/glpipe.cpp b/src/proc/engine/glpipe.cpp
          deleted file mode 100644
          index 9d4d28b48..000000000
          --- a/src/proc/engine/glpipe.cpp
          +++ /dev/null
          @@ -1,34 +0,0 @@
          -/*
          -  GLPipe  -  specialized connection element for handling OpenGL implementation details
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program is free software; you can redistribute it and/or
          -  modify it under the terms of the GNU General Public License as
          -  published by the Free Software Foundation; either version 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program is distributed in the hope that it will be useful,
          -  but WITHOUT ANY WARRANTY; without even the implied warranty of
          -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          -  GNU General Public License for more details.
          - 
          -  You should have received a copy of the GNU General Public License
          -  along with this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -* *****************************************************/
          -
          -
          -#include "proc/engine/glpipe.hpp"
          -
          -namespace engine
          -  {
          -
          -  /** */
          -
          -
          -
          -
          -} // namespace engine
          diff --git a/src/proc/engine/glpipe.hpp b/src/proc/engine/glpipe.hpp
          deleted file mode 100644
          index 39a98a7ab..000000000
          --- a/src/proc/engine/glpipe.hpp
          +++ /dev/null
          @@ -1,46 +0,0 @@
          -/*
          -  GLPIPE.hpp  -  specialized connection element for handling OpenGL implementation details
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program is free software; you can redistribute it and/or
          -  modify it under the terms of the GNU General Public License as
          -  published by the Free Software Foundation; either version 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program is distributed in the hope that it will be useful,
          -  but WITHOUT ANY WARRANTY; without even the implied warranty of
          -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          -  GNU General Public License for more details.
          - 
          -  You should have received a copy of the GNU General Public License
          -  along with this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -*/
          -
          -
          -#ifndef ENGINE_GLPIPE_H
          -#define ENGINE_GLPIPE_H
          -
          -#include "proc/engine/link.hpp"
          -
          -
          -
          -namespace engine
          -  {
          -
          -
          -  /**
          -   * specialized connection node used to handle the transfer of OpenGL data
          -   * from a image bitmap into texture form.
          -   */
          -  class GLPipe : public Link
          -    {};
          -
          -
          -
          -
          -} // namespace engine
          -#endif
          diff --git a/src/proc/engine/hub.cpp b/src/proc/engine/hub.cpp
          deleted file mode 100644
          index 394d24197..000000000
          --- a/src/proc/engine/hub.cpp
          +++ /dev/null
          @@ -1,34 +0,0 @@
          -/*
          -  Hub  -  special ProcNode used to build data distributing connections
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program is free software; you can redistribute it and/or
          -  modify it under the terms of the GNU General Public License as
          -  published by the Free Software Foundation; either version 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program is distributed in the hope that it will be useful,
          -  but WITHOUT ANY WARRANTY; without even the implied warranty of
          -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          -  GNU General Public License for more details.
          - 
          -  You should have received a copy of the GNU General Public License
          -  along with this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -* *****************************************************/
          -
          -
          -#include "proc/engine/hub.hpp"
          -
          -namespace engine
          -  {
          -
          -  /** */
          -
          -
          -
          -
          -} // namespace engine
          diff --git a/src/proc/engine/hub.hpp b/src/proc/engine/hub.hpp
          deleted file mode 100644
          index b6ec69fcb..000000000
          --- a/src/proc/engine/hub.hpp
          +++ /dev/null
          @@ -1,44 +0,0 @@
          -/*
          -  HUB.hpp  -  special ProcNode used to build data distributing connections
          - 
          -  Copyright (C)         Lumiera.org
          -    2008,               Hermann Vosseler 
          - 
          -  This program is free software; you can redistribute it and/or
          -  modify it under the terms of the GNU General Public License as
          -  published by the Free Software Foundation; either version 2 of the
          -  License, or (at your option) any later version.
          - 
          -  This program is distributed in the hope that it will be useful,
          -  but WITHOUT ANY WARRANTY; without even the implied warranty of
          -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          -  GNU General Public License for more details.
          - 
          -  You should have received a copy of the GNU General Public License
          -  along with this program; if not, write to the Free Software
          -  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          - 
          -*/
          -
          -
          -#ifndef ENGINE_HUB_H
          -#define ENGINE_HUB_H
          -
          -#include "proc/engine/procnode.hpp"
          -
          -
          -
          -namespace engine
          -  {
          -
          -
          -  class Hub : public ProcNode
          -    {};
          -  ///TODO: seems rather we don't need this one anymore??
          -  //////// to be decided after the implementing the basic render engine....
          -
          -
          -
          -
          -} // namespace engine
          -#endif
          diff --git a/src/proc/engine/link.hpp b/src/proc/engine/link.hpp
          index ad2f3a625..d677fca9c 100644
          --- a/src/proc/engine/link.hpp
          +++ b/src/proc/engine/link.hpp
          @@ -40,6 +40,10 @@ namespace engine
              */
             class Link : public ProcNode
               {
          +      Link (WiringDescriptor const& wd)
          +        : ProcNode(wd)
          +        { }
          +
                 ///////TODO: flatten hierarchy if we don't have common functionallity for all Link-Subclasses
                 ///////TODO:  can be decdiede when we know more how to handle OpenGL rendering
               };
          diff --git a/src/proc/engine/nodeoperation.hpp b/src/proc/engine/nodeoperation.hpp
          new file mode 100644
          index 000000000..6c8378cc5
          --- /dev/null
          +++ b/src/proc/engine/nodeoperation.hpp
          @@ -0,0 +1,72 @@
          +/*
          +  NODEOPERATION.hpp  -  Specify how the nodes call each other and how processing is organized
          + 
          +  Copyright (C)         Lumiera.org
          +    2008,               Hermann Vosseler 
          + 
          +  This program is free software; you can redistribute it and/or
          +  modify it under the terms of the GNU General Public License as
          +  published by the Free Software Foundation; either version 2 of the
          +  License, or (at your option) any later version.
          + 
          +  This program is distributed in the hope that it will be useful,
          +  but WITHOUT ANY WARRANTY; without even the implied warranty of
          +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          +  GNU General Public License for more details.
          + 
          +  You should have received a copy of the GNU General Public License
          +  along with this program; if not, write to the Free Software
          +  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          + 
          +*/
          +
          +
          +#ifndef ENGINE_NODEOPERATION_H
          +#define ENGINE_NODEOPERATION_H
          +
          +
          +#include "proc/engine/procnode.hpp"
          +
          +
          +
          +
          +namespace engine {
          +  
          +  
          +  
          +  /**
          +   * Adapter to shield the ProcNode from the actual buffer management,
          +   * allowing the processing function within ProcNode to use logical
          +   * buffer IDs. StateAdapter is created on the stack for each pull()
          +   * call, using setup/wiring data preconfigured by the builder.
          +   * Its job is to provide the actual implementation of the Cache
          +   * push / fetch and recursive downcall to render the source frames.
          +   */
          +  class StateAdapter
          +    : public State
          +    {
          +      State& parent_;
          +      State& current_;
          +      
          +    protected:
          +      StateAdapter (State& callingProcess, WiringDescriptor const&) 
          +        : parent_ (callingProcess),
          +          current_(callingProcess.getCurrentImplementation())
          +        { }
          +      
          +      friend class ProcNode; // both are sharing implementation details...
          +      
          +      
          +      virtual State& getCurrentImplementation () { return current_; }
          +      
          +      /** contains the details of Cache query and recursive calls
          +       *  to the predecessor node(s), eventually followed by the 
          +       *  ProcNode::process() callback
          +       */
          +      void retrieve();
          +    };
          +  
          +  
          +  
          +} // namespace engine
          +#endif
          diff --git a/src/proc/engine/nodewiring.cpp b/src/proc/engine/nodewiring.cpp
          new file mode 100644
          index 000000000..02930604b
          --- /dev/null
          +++ b/src/proc/engine/nodewiring.cpp
          @@ -0,0 +1,49 @@
          +/*
          +  NodeWiring  -  Implementation of the node network and operation control
          + 
          +  Copyright (C)         Lumiera.org
          +    2008,               Hermann Vosseler 
          + 
          +  This program is free software; you can redistribute it and/or
          +  modify it under the terms of the GNU General Public License as
          +  published by the Free Software Foundation; either version 2 of the
          +  License, or (at your option) any later version.
          + 
          +  This program is distributed in the hope that it will be useful,
          +  but WITHOUT ANY WARRANTY; without even the implied warranty of
          +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          +  GNU General Public License for more details.
          + 
          +  You should have received a copy of the GNU General Public License
          +  along with this program; if not, write to the Free Software
          +  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          + 
          +* *****************************************************/
          +
          +
          +#include "proc/engine/procnode.hpp"
          +#include "proc/engine/nodewiring.hpp"
          +#include "proc/engine/nodeoperation.hpp"
          +
          +namespace engine {
          +  
          +  
          +  /** create and configure a concrete wiring descriptor to tie
          +   *  a ProcNode to its predecessor nodes. This includes selecting
          +   *  the actual StateProxy type, configuring it out of some operation
          +   *  control templates (policy classes). Compiling this operator function
          +   *  actually drives the necessary template instantiations for all cases
          +   *  encountered while building the node network.
          +   *  The created WiringDescriptor objects are bulk allocated similar to the ProcNode
          +   *  objects for a given segment of ther Timeline. It should be further configured
          +   *  with the actual predecessor nodes pointers and can then be used to create
          +   *  the new processing node to be wired up.  
          +   */
          +  WiringDescriptor&
          +  WiringFactory::operator() (uint nrOut, uint nrIn, bool cache)
          +  {
          +    UNIMPLEMENTED ("build the actual wiring descriptor based on given operation options");
          +  }
          +
          +  
          +} // namespace engine
          diff --git a/src/proc/engine/nodewiring.hpp b/src/proc/engine/nodewiring.hpp
          new file mode 100644
          index 000000000..3a157fb47
          --- /dev/null
          +++ b/src/proc/engine/nodewiring.hpp
          @@ -0,0 +1,77 @@
          +/*
          +  NODEWIRING.hpp  -  Implementation of the node network and operation control
          + 
          +  Copyright (C)         Lumiera.org
          +    2008,               Hermann Vosseler 
          + 
          +  This program is free software; you can redistribute it and/or
          +  modify it under the terms of the GNU General Public License as
          +  published by the Free Software Foundation; either version 2 of the
          +  License, or (at your option) any later version.
          + 
          +  This program is distributed in the hope that it will be useful,
          +  but WITHOUT ANY WARRANTY; without even the implied warranty of
          +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          +  GNU General Public License for more details.
          + 
          +  You should have received a copy of the GNU General Public License
          +  along with this program; if not, write to the Free Software
          +  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
          + 
          +*/
          +
          +
          +#ifndef ENGINE_NODEWIRING_H
          +#define ENGINE_NODEWIRING_H
          +
          +
          +#include "proc/engine/procnode.hpp"
          +
          +#include 
          +
          +
          +
          +namespace engine {
          +
          +
          +  class WiringFactory;
          +  
          +  
          +  /**
          +   * Actual implementation of the link between nodes
          +   * and also the track switch for the execution path
          +   * while operating the node network for rendering.
          +   * @param STATE StateAdapter object controlling the
          +   *        behaviour of callDown() while rendering.
          +   * @see NodeFactory 
          +   */
          +  template
          +  class NodeWiring
          +    : public WiringDescriptor
          +    {
          +      
          +      friend class WiringFactory;
          +      
          +    protected:
          +      virtual BufferID
          +      callDown (State& currentProcess, BufferID requiredOutputNr)  const 
          +        {
          +          STATE thisStep (currentProcess, *this);
          +          return thisStep.retrieve (requiredOutputNr); // fetch or calculate results
          +        }
          +      
          +    };
          +
          +    
          +    
          +  class WiringFactory
          +    {
          +    public:
          +      WiringDescriptor&
          +      operator() (uint nrOut, uint nrIn, bool cache);
          +    };
          +  
          +  
          +  
          +} // namespace engine
          +#endif
          diff --git a/src/proc/engine/procnode.hpp b/src/proc/engine/procnode.hpp
          index a3dc5d702..e85f45fae 100644
          --- a/src/proc/engine/procnode.hpp
          +++ b/src/proc/engine/procnode.hpp
          @@ -20,15 +20,33 @@
            
           */
           
          +/** @file procnode.hpp
          + ** Interface to the processing nodes and the render nodes network.
          + **
          + ** Actually, there are three different interfaces to consider
          + ** - the ProcNode#pull is the invocation interface. It is call-style (easily callable by C)
          + ** - the builder interface, comprised by the NodeFactory and the WiringFactory. It's C++ (using templates)
          + ** - the actual processing function is supposed to be a C function; it uses a set of C functions 
          + **   for accessing the frame buffers with the data to be processed.
          + **
          + ** By using the builder interface, concrete node and wiring descriptor classes are created,
          + ** based on some templates. These concrete classes form the "glue" to tie the node network
          + ** together and contain much of the operation beahviour in a hard wired fashion.
          + **
          + ** @see nodefactory.hpp
          + ** @see operationpoint.hpp
          + */
           
           #ifndef ENGINE_PROCNODE_H
           #define ENGINE_PROCNODE_H
           
          -#include 
          +#include "pre.hpp"
           
          +#include "proc/lumiera.hpp"
           #include "proc/state.hpp"
           #include "proc/mobject/parameter.hpp"
           
          +#include 
           
           
           
          @@ -47,45 +65,21 @@ namespace engine {
              * Description of the input and output ports and the
              * predecessor nodes for a given ProcNode.
              */
          -  struct WiringDescriptor
          +  class WiringDescriptor
               {
          -      
          -    };
          -    
          -
          -  /**
          -   * Adapter to shield the ProcNode from the actual buffer management,
          -   * allowing the processing function within ProcNode to use logical
          -   * buffer IDs. StateAdapter is created on the stack for each pull()
          -   * call, using setup/wiring data preconfigured by the builder.
          -   * Its job is to provide the actual implementation of the Cache
          -   * push / fetch and recursive downcall to render the source frames.
          -   */
          -  class StateAdapter
          -    : public State
          -    {
          -      State& parent_;
          -      State& current_;
          +    public:
          +      virtual ~WiringDescriptor() {}
                 
               protected:
          -      StateAdapter (State& callingProcess, WiringDescriptor const&) 
          -        : parent_ (callingProcess),
          -          current_(callingProcess.getCurrentImplementation())
          -        { }
          +      virtual BufferID  callDown (State& currentProcess, BufferID requiredOutputNr)  const =0; 
                 
          -      friend class ProcNode; // both are sharing implementation details...
          +      friend class ProcNode;
                 
          -      
          -      virtual State& getCurrentImplementation () { return current_; }
          -      
          -      /** contains the details of Cache query and recursive calls
          -       *  to the predecessor node(s), eventually followed by the 
          -       *  ProcNode::process() callback
          -       */
          -      void retrieve();
               };
             
             
          +  
          +  
             /**
              * Key abstraction of the Render Engine: A Data processing Node
              */
          @@ -93,45 +87,39 @@ namespace engine {
               {
                 typedef mobject::Parameter Param;   //////TODO: just a placeholder for automation as of 6/2008
                 vector params;
          -
          +      
          +      const WiringDescriptor& wiringConfig_;
          +      
               protected:
          -      ProcNode();
          +      ProcNode (WiringDescriptor const& wd)
          +        : wiringConfig_(wd)
          +        { }
          +        
                 virtual ~ProcNode() {};
                 
                 friend class NodeFactory;
                 
                 
          -      /** Callback doing the actual calculations
          -       *  after input / output buffers are ready
          -       *  @internal dispatch to implementation. 
          -       *            Client code should use #pull()
          -       */
          -      virtual void process(State&) = 0;
                 
          -      friend void StateAdapter::retrieve();  // to issue the process() callback if necessary
          -      
          -      
          -      /** Extension point for subclasses to modify the input sources
          -       *  according to automation data and other state dependent properties. 
          -       */
          -      virtual WiringDescriptor const& getWiring (State&); 
          -      
          -
               public:
                 static NodeFactory create;
                 
                 /** Engine Core operation: render and pull output from this node.
          -       *  On return, currentProcess will hold onto output buffer(s)
          +       *  On return, currentProcess will hold onto output buffer
                  *  containing the calculated result frames.
          +       *  @param currentProcess the current processing state for 
          +       *         managing buffers and accessing current parameter values
          +       *  @param requiredOutputNr the output channel requested (in case
          +       *         this node delivers more than one output channel)
          +       *  @return ID of the result buffer (accessible via currentProcess) 
                  */
          -      void 
          -      pull (State& currentProcess) 
          +      BufferID
          +      pull (State& currentProcess, BufferID requiredOutputNr=0) 
                   {
          -          StateAdapter thisStep (currentProcess, getWiring (currentProcess));
          -          thisStep.retrieve(); // fetch or calculate results
          +          return this->wiringConfig_.callDown (currentProcess, requiredOutputNr);
                   }
          -
          +      
               };
          -
          +  
           } // namespace engine
           #endif
          diff --git a/src/proc/engine/projector.hpp b/src/proc/engine/projector.hpp
          index 0908eec38..4e03c4cc2 100644
          --- a/src/proc/engine/projector.hpp
          +++ b/src/proc/engine/projector.hpp
          @@ -37,7 +37,7 @@ namespace engine
              */
             class Projector : public Trafo
               {
          -      ////////////
          +      ////////////TODO adapt ctor
               };
           
           
          diff --git a/src/proc/engine/source.hpp b/src/proc/engine/source.hpp
          index 37af97841..3573f3e0b 100644
          --- a/src/proc/engine/source.hpp
          +++ b/src/proc/engine/source.hpp
          @@ -40,7 +40,9 @@ namespace engine
              */
             class Source : public ProcNode
               {
          -      /////////////////TODO
          +      Source (WiringDescriptor const& wd)
          +        : ProcNode(wd)
          +        { }
               };
           
           
          diff --git a/src/proc/engine/trafo.hpp b/src/proc/engine/trafo.hpp
          index d1b6ba3cb..166154674 100644
          --- a/src/proc/engine/trafo.hpp
          +++ b/src/proc/engine/trafo.hpp
          @@ -43,7 +43,9 @@ namespace engine
             class Trafo : public ProcNode
               {
               protected:
          -      Trafo() : ProcNode() { };
          +      Trafo (WiringDescriptor const& wd)
          +        : ProcNode(wd)
          +        { }
                 
                 friend class NodeFactory;
                 
          diff --git a/src/proc/state.hpp b/src/proc/state.hpp
          index 98fe1aa9f..307c66714 100644
          --- a/src/proc/state.hpp
          +++ b/src/proc/state.hpp
          @@ -25,13 +25,20 @@
           #define PROC_INTERFACE_STATE_H
           
           
          +#include "pre.hpp"
           
          -namespace engine { class StateAdapter; }
          +#include "proc/lumiera.hpp"
           
          -namespace proc_interface
          -  {
          +#include 
           
           
          +namespace engine { 
          +  
          +  class StateAdapter;
          +  
          +  typedef std::size_t BufferID;
          +  
          +  
             class State
               {
               protected:
          @@ -50,7 +57,14 @@ namespace proc_interface
               public:
                 
               };
          -    
          +  
          +} // namespace engine
          +
          +
          +
          +namespace proc_interface {
          +
          +  using engine::State;
               
               
           } // namespace proc_interface
          diff --git a/wiki/index.html b/wiki/index.html
          index 1ed553afd..7fc560bb2 100755
          --- a/wiki/index.html
          +++ b/wiki/index.html
          @@ -930,14 +930,16 @@ git push git://git.pipapo.org/lumiera/mob
           
           lumiera/mob is an anonymous account at pipapo.org where everyone can commit changes. 
          -
          +
          We keep a protocol or short summary of each important discussion. The summaries of the monthly developer meetings are posted to the Mailinglist and can be found on pipapo.org too
           
           * [[04-08 developer meeting 3.Apr.2008|IRC_2008-04-03]]
           * [[03-08 developer meeting 6.Mar.2008|IRC_2008-03-06]]
           * [[1.official developer meeting 1.Feb.2008|IRC_2008-02-01]]
           * [[informal developer meeting 10.Aug.2007|IRC_2007-08-10]]
          -
          + +!talks about distinct topics +* [[buffer allocation for render nodes (6/08)|IRC_log_BufferAllocation_2008-06]]
          !10/11 aug 2007
          @@ -1448,6 +1450,137 @@ The next meeting will be at thuesday 8th may 21:00GMT
           
           
          +
          +
          ! 5.June 2008 on #lumiera
          +__cehteh__ and __ichthyo__
          +{{{
          +[2008-06-05 19:21:21] <cehteh> do you need me? .. i am away if not .. i have no much to say for the today meeting either
          +[2008-06-05 19:21:57] <ichthyo> I have one topic I want to discuss with you, cehteh
          +[2008-06-05 19:22:07] <ichthyo> but it need not be now, or in the meeting
          +[2008-06-05 19:22:07] <cehteh> ok
          +[2008-06-05 19:22:24] <ichthyo> it's about allocating processing buffers 
          +[2008-06-05 19:23:20] <cehteh> the backend will provide them as temporary files/cyclic buffers
          +[2008-06-05 19:23:52] <cehteh> its not there yet but in my mind
          +[2008-06-05 19:24:11] <ichthyo> haha, same for the builder... it's mostly just in my mind
          +[2008-06-05 19:24:42] <cehteh> opened almost like a normal file but giving frame properties instead filename
          +[2008-06-05 19:24:56] <cehteh> (there will be a distinct api for that)
          +[2008-06-05 19:25:01] <ichthyo> ok
          +[2008-06-05 19:25:05] <ichthyo> regarding the buffers: my question is more special
          +[2008-06-05 19:25:19] <ichthyo> if you want to cache a frame (intermediary result)
          +[2008-06-05 19:25:35] <ichthyo> then I thought we could avoid the copy operation
          +[2008-06-05 19:25:44] <ichthyo> I could arrange things accordingly
          +[2008-06-05 19:25:46] <cehteh> then the backend creates a backing mmaped file for that maybe manages its size (or do you want to tell how much frames you want to cache?)
          +[2008-06-05 19:26:06] <cehteh> yes perfect .. thats what i am planning
          +[2008-06-05 19:26:26] <ichthyo> you know, many processing nodes will be able to process "in place"
          +[2008-06-05 19:26:34] <ichthyo> but ther are some that can't do this
          +[2008-06-05 19:27:44] <ichthyo> so basically each processing function will "see" input frame buffer(s) and output frame buffer(s). but when a node is "in-place-capable", actually the in and out buffer may point to the same location
          +[2008-06-05 19:26:55] <cehteh> basiically all temporary frames with the same properties are allcoated from the same backing file (well maybe 2 caching levels but not important here)
          +[2008-06-05 19:27:06] <cehteh> the index give them meaning
          +[2008-06-05 19:27:49] <cehteh> do you can query (and lock) a frame by that
          +[2008-06-05 19:28:04] <ichthyo> that sounds good
          +[2008-06-05 19:28:24] <cehteh> do some inplace editing and then tell the backend "this is now frame N of node X"
          +[2008-06-05 19:28:34] <ichthyo> yeah, exactly
          +[2008-06-05 19:28:44] <cehteh> (plus a uuid or preferably genertion number)
          +[2008-06-05 19:28:39] <ichthyo> basically my Idea was as follows:
          +[2008-06-05 19:29:47] <ichthyo> when I know the result will be cached, I'll let the node process into the location of the cache frame, and any node which will /use/ this frame as an input will be wired such that it isn't allowed to modify this frame (which is supposed to be located in the cache)
          +[2008-06-05 19:30:45] <cehteh> yes thats managed in the index
          +[2008-06-05 19:30:48] <ichthyo> for this to work, I need to "allocate and lock" a location in the cache, and release it when it contains the final processed result
          +[2008-06-05 19:31:17] <cehteh> well i try to make no locks there, you query frames which are uniquely identified
          +[2008-06-05 19:31:44] <ichthyo> it doesnt need to be a "lock
          +[2008-06-05 19:31:55] <ichthyo> just some way to tell that this frame is "under construction"
          +[2008-06-05 19:32:01] <cehteh> yes
          +[2008-06-05 19:32:14] <cehteh> we thinking the same :)
          +[2008-06-05 19:32:57] <cehteh> well problem is when shortly after that another node queries the source frame which got destructed .. thats something the builder needs to avoid, nothing i can do then
          +[2008-06-05 19:33:21] <ichthyo> yes, builder will care for that
          +[2008-06-05 19:33:41] <ichthyo> I can even tell in advance the maximum number of temporary buffers I need
          +[2008-06-05 19:33:51] <cehteh> and it not only needs a under-construcion
          +[2008-06-05 19:34:44] <cehteh> there are 2 indices one for source and one for destination
          +[2008-06-05 19:35:11] <cehteh> indices will have a pointer to the 'job' working on it i tihnk
          +[2008-06-05 19:35:24] <ichthyo> ok
          +[2008-06-05 19:35:48] <cehteh> (actually there is a list planed many jobs can read-share an frame)
          +[2008-06-05 19:36:40] <cehteh> i would like if I do not need to do *any* checks in that direction ... means the builder delivers clean jobs which dont step on their own foot
          +[2008-06-05 19:36:54] <ichthyo> my understanding too
          +[2008-06-05 19:37:07] <ichthyo> also, I want the nodes to be freed of any checks
          +[2008-06-05 19:37:33] <ichthyo> so they can assume they get a valid buffer pointer to the right sort of buffer
          +[2008-06-05 19:37:54] <cehteh> yes thats guranteed
          +[2008-06-05 19:37:41] <cehteh> if it fails then we get some hairy bugs ... but checking job dependencies afterwards is costly
          +[2008-06-05 19:38:53] <ichthyo> I mean -- I want to prepare everything as much as possible while building, so that all that needs to be "filled in" when starting the processing are the actual buffer locations
          +[2008-06-05 19:38:58] <cehteh> *thinkin* prolly easier than it looks
          +[2008-06-05 19:39:10] <cehteh> exaxctly
          +[2008-06-05 19:39:50] <ichthyo> we can't prepare everything, because, some nodes may include a variable ammount of source frames
          +[2008-06-05 19:40:11] <ichthyo> and this number can depend on automation. Classic example is the "time average" video effect
          +[2008-06-05 19:39:53] <cehteh> problem is only when the builder generates one node which takes X and in-place generates Y from it
          +[2008-06-05 19:40:10] <cehteh> and you have a 2nd node which takes X too 
          +[2008-06-05 19:40:23] <cehteh> this needs to be serialized somehow
          +[2008-06-05 19:41:12] <ichthyo> regarding the problem you mention: I want to exclude/avoid this situation already when building
          +[2008-06-05 19:41:35] <cehteh> yes thats what i was thinking .. thats easiest addressed there
          +[2008-06-05 19:41:46] <cehteh> and a very ugly bug when it fails :(
          +[2008-06-05 19:41:42] <ichthyo> when a node puts its result into a frame located within the cache
          +[2008-06-05 19:41:59] <ichthyo> this frame is treated as if it is read-only
          +[2008-06-05 19:42:21] <ichthyo> no node depending on this frame will be wired in a way that allows "in-place"
          +[2008-06-05 19:42:33] <cehteh> about the time averaging: i plan to hint some dependencies so you can ask for "maybe" or by some priority depending on quality/whatever
          +[2008-06-05 19:43:19] <cehteh> where quality should be runtime adjusted by the profiler
          +[2008-06-05 19:43:39] <ichthyo> the problem with time averaging is: we don't know how much frames will be averaged at build time, because that's a automatable effect parameter
          +[2008-06-05 19:43:47] <cehteh> thats a case where a dependencie might not be fullfilled .. but only on request
          +[2008-06-05 19:44:08] <ichthyo> but the "quality" thing sounds like a good idea
          +[2008-06-05 19:44:17] <cehteh> yes then split that rendering into 3 passes?
          +[2008-06-05 19:44:27] <cehteh> 1st pass : building the graph
          +[2008-06-05 19:44:53] <cehteh> 2nd pass: determine dependencies (by inspecting automation)
          +[2008-06-05 19:45:00] <cehteh> 3rd pass: do the render
          +[2008-06-05 19:45:10] <ichthyo> maybe?
          +[2008-06-05 19:45:17] <ichthyo> 1st pass of course is clear
          +[2008-06-05 19:45:25] <cehteh> well do you have a better idea?
          +[2008-06-05 19:45:49] <cehteh> so far i thought about 2 pass where the dependency analysis was part of the builder
          +[2008-06-05 19:46:02] <ichthyo> agreed
          +[2008-06-05 19:46:28] <cehteh> but making it three pass shouldnt be a problem or?
          +[2008-06-05 19:46:51] <ichthyo> I also thought after having finished the raw graph, I'll do some configuration calldown, e.g. to determine the maximum number of buffers needed
          +[2008-06-05 19:46:59] <cehteh> maybe even adaptive 2/3 pass depending on effects ... but maybe that would complicate it unnecessary
          +[2008-06-05 19:47:43] <ichthyo> its not really a problem, just need to be aware and work the details out correctlyy
          +[2008-06-05 19:47:49] <cehteh> i dont think you need  to count the buffers (not yet, maybe i oversee soemthing)
          +[2008-06-05 19:48:08] <cehteh> otherwise the backend should manage that automatically
          +[2008-06-05 19:48:18] <ichthyo> yes, I'm fine with that
          +[2008-06-05 19:48:46] <ichthyo> just to note, if it helps with the allocation, I /can/ tell the maximum number of buffers needed
          +[2008-06-05 19:49:00] <ichthyo> (for a given segment of the graph, of course)
          +[2008-06-05 19:49:09] <cehteh> not sure if i overseen something, but i think when needed such a 'configuration calldown' (and optimizing pass) could be added later
          +[2008-06-05 19:49:27] <ichthyo> sure
          +[2008-06-05 19:49:50] <cehteh> buffers itself doesnt cost .. but if you really need a lot it will cause IO
          +[2008-06-05 19:49:57] <cehteh> but that unavoidable anyways
          +[2008-06-05 19:50:05] <ichthyo> no no
          +[2008-06-05 19:50:19] <cehteh> yes yes
          +[2008-06-05 19:50:20] <ichthyo> I'll try to minimize buffer use as much as possible
          +[2008-06-05 19:50:24] <cehteh> :)
          +[2008-06-05 19:50:30] <cehteh> of course
          +[2008-06-05 19:51:00] <cehteh> but there are always some limits on finite machines
          +[2008-06-05 19:51:26] <ichthyo> the problematic case are usual rather rare corner cases, but it should handle those flawless, of course
          +[2008-06-05 19:51:36] <ichthyo> similar for the size of the buffers
          +[2008-06-05 19:51:46] <ichthyo> I dont want Lumiera to clip the image
          +[2008-06-05 19:51:49] <ichthyo> as cinelerra does
          +[2008-06-05 19:52:04] <ichthyo> e.g. when using the motion tracker
          +[2008-06-05 19:52:20] <cehteh> well if you need safe-regions around you need to use biggier frames
          +[2008-06-05 19:52:31] <cehteh> but memory requirements grow quadratic!
          +[2008-06-05 19:52:46] <ichthyo> the user should NEVER need to set up the processing buffer size, as is necessary in cinelerra
          +[2008-06-05 19:52:59] <cehteh> yes agreed
          +[2008-06-05 19:53:15] <ichthyo> I don't think we need safe-regions allways, 
          +[2008-06-05 19:53:31] <ichthyo> but, as e.g. the motion tracking will create automation data in Lumiera
          +[2008-06-05 19:53:38] <cehteh> yes only for some effect .. motion tracker doesnt need it
          +[2008-06-05 19:53:50] <ichthyo> it means the actual buffer size depends on automation data for a given frame
          +[2008-06-05 19:53:56] <cehteh> that just xyr transformation
          +[2008-06-05 19:54:35] <cehteh> a blur is something which might require a small safe-region to bleed over the edges
          +[2008-06-05 19:54:43] <ichthyo> yes, you are right
          +[2008-06-05 19:54:52] <ichthyo> if the motion tracker is wired intelligently
          +[2008-06-05 19:55:05] <ichthyo> it doesn't need to move anyting itself
          +[2008-06-05 19:55:18] <cehteh> mapping the motion tracker transformation to a destionation might need safe regions
          +[2008-06-05 19:55:30] <cehteh> (in case of rotations)
          +[2008-06-05 19:55:36] <ichthyo> yes agreed
          +[2008-06-05 19:56:16] <cehteh> well temp buffers will be allcocated for frames of the same 'class' i aleready saied that
          +[2008-06-05 19:56:50] <cehteh> and i will group these classes so that some similar sizes fall in the same class 
          +[2008-06-05 19:57:19] <cehteh> that might waste some memory on disk at the end of each frame .. but that doesnt need to be mapped in
          +[2008-06-05 19:57:32] <cehteh> the kernel will do that automatically for us
          +[2008-06-05 19:57:37] <ichthyo> :)
          +[2008-06-05 19:57:59] <cehteh> well mostly .. i need to whip it with the right hints ;)
          +[2008-06-05 19:58:10] <ichthyo> :-o
          +}}}
          +
          /***
           ''InlineJavascriptPlugin for ~TiddlyWiki version 1.2.x and 2.0''
          diff --git a/wiki/renderengine.html b/wiki/renderengine.html
          index 6c6366bb0..8afd00705 100644
          --- a/wiki/renderengine.html
          +++ b/wiki/renderengine.html
          @@ -881,7 +881,7 @@ While building, the application of such a visiting tool (especially the [[NodeCr
           
           
          -
          +
          Besides the primary working tool within the builder (namely the [[Node Creator Tool|PlanningNodeCreatorTool]]), on a lower level, we encounter several [[elementary building situations|BuilderPrimitives]] &mdash; and for each of these elementary situations we can retrieve a suitable "fitting tool" or [[mould|BuilderMould]]. The palette of these moulds is called the ''tool kit'' of the builder. It is subject to configuration by rules.
           
           
          @@ -895,7 +895,7 @@ As each mould kind is different, it has a {{{prepare(...)}}} function with suita
           When {{{operate()}}} doesn't throw, the result is a list of //successor moulds// &mdash; you shouldn't use the original mould after triggering its operation, because it may have been retracted as a result and reused for another purpose by the tool factory. It is not necessary to store these resulting moulds either (as they can be retrieved as described above), but they can be used right away for the next building step if applicable. In the state they are returned from a successful building step (mould operation = execution of a contained [[processing pattern|ProcPatt]]), they are usually already holding a reference to the part of the network just created and need to be configured only with the next high-level object (effect, placement, pipe, processing pattern or similar, depending on the concrete situation) in order to carry out the next step.
           
           !!single connection step
          -at the lowest level within the builder there is the step of building a //connection.// This step is executed by the processing pattern with the help of the mould. Actually, making such a connection is more complicated, because in the standard case it will connect N media streams simultaneously (N=2 for stereo sound or 3D video, N=6 for 5.1 Surround, N=9 for 2nd order Ambisonics). These details are encapsulated within the OperationPoint, which is provides by the mould and exhibits a common interface for the processing pattern to express the connecting operation.
          +at the lowest level within the builder there is the step of building a //connection.// This step is executed by the processing pattern with the help of the mould. Actually, making such a connection is more complicated, because in the standard case it will connect N media streams simultaneously (N=2 for stereo sound or 3D video, N=6 for 5.1 Surround, N=9 for 2nd order Ambisonics). These details are encapsulated within the OperationPoint, which is provided by the mould and exhibits a common interface for the processing pattern to express the connecting operation.
           
           &rarr;see also: BuilderPrimitives for the elementary working situations corresponding to each of these [[builder moulds|BuilderMould]]
           
          @@ -1839,7 +1839,7 @@ So, when creating a clip out of such a compound media asset, the clip has to be
          NodeCreaterTool is a [[visiting tool|VisitorUse]] used as second step in the [[Builder]]. Starting out from a [[Fixture]], the builder first [[divides the Timeline into segments|SegmentationTool]] and then processes each segment with the NodeCreaterTool to build a render nodes network (Render Engine) for this part of the timeline. While visiting individual Objects and Placements, the NodeCreaterTool creates and wires the necessary [[nodes|ProcNode]]
          -
          +
          The [[nodes|ProcNode]] are wired to form a "Directed Acyclic Graph"; each node knows its predecessor(s), but not its successor(s).  The RenderProcess is organized according to the ''pull principle'', thus we find an operation {{{pull()}}} at the core of this process. There is no such thing as an "engine object" calling nodes iteratively or table driven, rather, the nodes themselves issue recursive calls to their predecessor(s). For this to work, we need the nodes to adhere to a specific protocol:
           # Node is pulled, with a StateProxy object as parameter (encapsulating the access to the frames or buffers)
           # Node may now access current parameter values, using the state accessible via the StateProxy
          @@ -1854,6 +1854,9 @@ some points to note:
           * when a node is "inplace-capable", input and output buffer may actually point to the same location
           * but there is no guarantee for this to happen, because the cache may be involved (and we can't overwrite the contents of a cache frame)
           * generally, a node may have N inputs and M output frames, which are expected to be processed in a single call
          +
          +&rarr; the [["mechanics" of the render process|RenderMechanics]]
          +&rarr; more fine grained [[implementation details|RenderImplDetails]]
           
          @@ -2731,7 +2734,7 @@ The system is ''open'' inasmuch every part mirrors the structure of correspondin &rarr; [[Implementation Details|ImplementationDetails]] {{red{WIP}}}
          -
          +
          A data processing node within the Render Engine. Its key feature is the possibility to pull from it one (freely addressable) [[Frame]] of calculated data. Further, each ~ProcNode has the ability to be wired with other nodes and [[Parameter Providers|ParamProvider]]
           
           !! {{red{open questions}}}
          @@ -2742,6 +2745,7 @@ The system is ''open'' inasmuch every part mirrors the structure of correspondin
           * how to define and query for additional capabilities
           
           &rarr; see also the [[open design process draft|http://www.pipapo.org/pipawiki/Lumiera/DesignProcess/DesignRenderNodesInterface]]
          +&rarr; see [[mem management|ManagementRenderNodes]]
           &rarr; see RenderProcess
           
          @@ -3037,10 +3041,39 @@ At first sight the link between asset and clip-MO is a simple logical relation b [img[Entities comprising the Render Engine|uml/fig128389.png]]
          -
          +
          +
          Below are some notes regarding details of the actual implementation of the render process and processing node operation. In the description of the [[render node operation protocol|NodeOperationProtocol]] and the [[mechanics of the render process|RenderMechanics]], these details were left out deliberately.
          +
          +!Layered structure of State
          +State can be seen as structured like an onion. All the [[StateAdapter]]s in one call stack are supposed to be within one layer: they all know of a "current state", which in turn is a StateProxy (and thus may refer yet to another state, maybe accros the network or in the backend or whatever). The actual {{{process()}}} function "within" the individual nodes just sees a single StateAdapter and thus can be thought to be a layer below.
          +
          +!Buffer identification
          +Buffers are identified by a //handle-id,// which actually is an int index into virtual or real array holding pointers to these buffers. This array is supposed to be //in the next state-layer above.// Thus, within the {{{process()}}} function, the buffer ~IDs are organized according to this node's output- and input ports (starting with the output at index 0), and are provided by the StateAdapter specifically created for this node, while in the next layer above, all the [[StateAdapter]]s deal with allocation and freeing of buffers via buffer IDs valid relative to the "current state", i.e. the shared StateProxy object used in this call stack. (And so on. Probably a render farm will add another layer)
          +
          +!Problem of multi-channel nodes
          +Some data processors simply require to work on multiple channels simultanously, while others work just on a single channel and will be replicated by the builder for each channel invoved. Thus, we are struck with the nasty situation that the node graph may go through some nodes spanning the chain of several channels. Now the decision is //not to care for this complexity within a single chain calculating a single channel.// We rely solely on the cache to avoid duplicated calculations. When a given node happens to produce multiple output buffers, we are bound to allocate them for the purpose of this nodes {{{process()}}} call, but we just "let go" the buffers not needed immediately for the channel acutally to be processed. For this to work, it is supposed that the builder has wired in a caching, and that the cache will hit when we touch the same node again for the other channels.
          +
          +!Configuration of the processing nodes
          +Every node is actually decomposed into three parts
          +* an interface container of a ProcNode subclass
          +* an {{{const}}} WiringDescriptor, which is actually parametrized to a subtype encoding details of the intended operation
          +* an StateAdapter object created on the stack for each {{{pull()}}} call and configured specifically for the intended operation
          +Thus, the outer container can be changed polymorphically to support the different kinds of nodes (large-scale view). The actual wiring of the nodes is contained in the WiringDescriptor, including the {{{process()}}} function pointer. Additionally, this WiringDescriptor knows the actual type of the StateAdapter to create, and this actual type has been chosen by the builder such as to select details of the desired operation of this mode, for example caching / no caching or maybe ~OpenGL rendering or the special case of a node pulling directly from a source reader. Most of this configuration is done by selecting the right template specialisation within the builder; thus in the critical path most of the calls can be inlined
          +
          +!Rules for buffer allocation and freeing
          +* only output buffers are allocated. It is //never necessary//&nbsp; to allocate input buffers!
          +* buffers are to be allocated as late as possible, typically just before invoking {{{process()}}}
          +* buffers are allways allocated by calling to the parent StateAdapter, because of the possibility to write to cache.
          +* after returing form a {{{pull()}}}, the buffer-ID of the single output requested by this call is returned. By using this ID, the caller can retrieve the actual buffer holding the result from the "current state" StaeProxy.
          +* any other buffers filled with results in the course of the same {{{process()}}} call can be released immediately before returning from the {{{pull()}}}
          +* similar, and input buffers are to be released immediately after the {{{process()}}} call, but before returing from this {{{pull()}}}
          +* buffers are allways released by calling to the "current state" (which is a StateProxy), providing the buffer-ID to be released
          +
          +
          +
          While the render process, with respect to the dependencies, the builder and the processing function is sufficiently characterized by referring to the ''pull principle'' and by defining a [[protocol|NodeOperationProtocol]] each node has to adhere to &mdash; for actually get it coded we have to care for some important details, especially //how to manage the buffers.// It may well be that the length of the code path necessary to invoke the individual processing functions is finally not so important, compared with the time spent at the inner pixel loop within these functions. But my guess is (as of 5/08), that the overall number of data moving and copying operations //will be//&nbsp; of importance.
           
          -!reguirements
          +!requirements
           * operations should be "in place" as much as possible
           * because caching necessitates a copy, the points where this happens should be controllable.
           * buffers should accommodate automatically to provide the necessary space without clipping the image.
          @@ -3054,8 +3087,9 @@ Not everything can be preconfigured though. The pull principle opens the possibi
           !buffer management
           Besides the StateProxy representing the actual render process and holding a couple of buffer (refs), we employ a lightweight adapter object in between. It is used //for a single {{{pull()}}}-call// &mdash; mapping the actual buffers to the input and output port numbers of the processing node and for dealing with the cache calls. While the StateProxy manages a pool of frame buffers, this interspersed adapter allows us to either use a buffer retrieved from the cache as an input, possibly use a new buffer located within the cache as output, or (in case no caching happens) to just use the same buffer as input and output for "in-place"-processing. The idea is that most of the configuration of this adapter object is prepared in the wiring step while building the node network.
           
          -The usage patern of the buffers can be stack-like when processing nodes requiring multiple input buffers. In the standard case, which also is the simplest case, a pair of buffers (or a single buffer for "in-place" capable nodes) suffices to calculate a whole chain of nodes. But &mdash; as the recursive descent means depth-first processing &mdash; in case multiple input buffers are needed, we may encounter a situation where some of these input buffers already contain processed data, while we have to descend into yet another predecessor node chain to pull the data for the remaining buffers. Care has to be taken //to allocate the buffers as late as possible,// otherwise we could end up holding onto a buffer almost for each node in the network. Effectively this translates into the rule to allocate output buffers only after all input buffers are ready and filled with data; thus we shouldn't allocate buffers when //entering// the recursive call to the predecessor(s), rather we have to wait until we are about to return from the downcall chain.
          +The usage patern of the buffers can be stack-like when processing nodes require multiple input buffers. In the standard case, which also is the simplest case, a pair of buffers (or a single buffer for "in-place" capable nodes) suffices to calculate a whole chain of nodes. But &mdash; as the recursive descent means depth-first processing &mdash; in case multiple input buffers are needed, we may encounter a situation where some of these input buffers already contain processed data, while we have to descend into yet another predecessor node chain to pull the data for the remaining buffers. Care has to be taken //to allocate the buffers as late as possible,// otherwise we could end up holding onto a buffer almost for each node in the network. Effectively this translates into the rule to allocate output buffers only after all input buffers are ready and filled with data; thus we shouldn't allocate buffers when //entering// the recursive call to the predecessor(s), rather we have to wait until we are about to return from the downcall chain.
           Besides, these considerations also show we need a means of passing on the current buffer usage pattern while calling down. This usage pattern not only includes a record of what buffers are occupied, but also the intended use of these occupied buffers, especially if they can be modified in-place, and at which point they may be released and reused.
          +__note__: this process outlined here and below is still an simplification. The actual implementation has some additional [[details to care for|RenderImplDetails]]
           
           !!Example: calculating a 3 node chain
           # Caller invokes calculation by pulling from exit node, providing the top-level StateProxy
          @@ -3083,6 +3117,7 @@ Besides, these considerations also show we need a means of passing on the curren
           @@clear(right):display(block):@@
           __see also__
           &rarr; the [[Entities involved in Rendering|RenderEntities]]
          +&rarr; additional [[implementation details|RenderImplDetails]]
           &rarr; [[Memory management for render nodes|ManagementRenderNodes]]
           &rarr; the protocol [[how to operate the nodes|NodeOperationProtocol]]
           
          From 1d37bf88d8a0d5f8f08873ea9a1172452da7f499 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 29 Jun 2008 15:32:19 +0200 Subject: [PATCH 08/12] WIP preliminary draft of node operation (cant work, now needs to be decomposed) --- src/proc/engine/nodeoperation.hpp | 88 ++++++++++++++++++++++++++++++- src/proc/engine/nodewiring.cpp | 2 +- src/proc/engine/nodewiring.hpp | 8 +-- src/proc/engine/procnode.hpp | 15 ++++-- src/proc/state.hpp | 28 +++++++++- wiki/renderengine.html | 41 +++++++++++--- 6 files changed, 162 insertions(+), 20 deletions(-) diff --git a/src/proc/engine/nodeoperation.hpp b/src/proc/engine/nodeoperation.hpp index 6c8378cc5..55450fba7 100644 --- a/src/proc/engine/nodeoperation.hpp +++ b/src/proc/engine/nodeoperation.hpp @@ -47,6 +47,7 @@ namespace engine { { State& parent_; State& current_; + WiringDescriptor const& wiring_; protected: StateAdapter (State& callingProcess, WiringDescriptor const&) @@ -54,7 +55,7 @@ namespace engine { current_(callingProcess.getCurrentImplementation()) { } - friend class ProcNode; // both are sharing implementation details... + friend class NodeWiring; // both are sharing implementation details... virtual State& getCurrentImplementation () { return current_; } @@ -63,7 +64,90 @@ namespace engine { * to the predecessor node(s), eventually followed by the * ProcNode::process() callback */ - void retrieve(); + BuffHandle retrieve (uint requiredOutputNr) + { + return retrieveResult (requiredOutputNr); + } + }; + + struct Caching + { + void retrieveResult (uint requiredOutputNr) + { + BuffHandle fetched = current_.fetch (genFrameID (requiredOutputNr)); + if (fetched) + return fetched; + + // Cache miss, need to calculate + BuffHandle calculated[NrO]; + calculateResult (&calculated); + + // commit result to Cache + current_.isCalculated (NrO, calculated, requiredOutputNr); + + return calculated[requiredOutputNr]; + } + }; + + struct NoCaching + { + void retrieveResult (BuffHandle requiredOutputNr) + { + return calculateResult (0); + } + }; + + struct Process + { + BuffHandle calculateResult(BuffHandle* calculated) + { + uint nrI = this->getNrI(); + for (uint i = 0; iinBuff[i] = current_.getBuffer(inID); + // now Input #i is ready... + } + uint nrO = this->getNrO(); + for (uint i = 0; iallocateBuffer(this->getBuferType(i)); ///TODO: Null pointer when no caching!!!!! + this->outBuff[i] = current_.getBuffer(calculated[i]); + // now Output buffer for channel #i is available... + } + // + // Invoke our own process() function + this->wiring_.process (this->outBuff); + + this->feedCache(); + // Inputs no longer needed + for (uint i = 0; igetNrO(); + for (uint i = 0; iretrieveInput(i); ///TODO: Null pointer when no caching!!!!! + this->outBuff[i] = current_.getBuffer(calculated[i]); + // now Buffer containing Output channel #i is available... + } + + this->feedCache(); + for (uint i=0; i < nrO; ++i) + if (i!=requiredOutputNr) + current_.releaseBuffer(i); + + return calculated[requiredOutputNr]; + }; + }; diff --git a/src/proc/engine/nodewiring.cpp b/src/proc/engine/nodewiring.cpp index 02930604b..e05a2c4e0 100644 --- a/src/proc/engine/nodewiring.cpp +++ b/src/proc/engine/nodewiring.cpp @@ -34,7 +34,7 @@ namespace engine { * control templates (policy classes). Compiling this operator function * actually drives the necessary template instantiations for all cases * encountered while building the node network. - * The created WiringDescriptor objects are bulk allocated similar to the ProcNode + * The created WiringDescriptor object is bulk allocated similar to the ProcNode * objects for a given segment of ther Timeline. It should be further configured * with the actual predecessor nodes pointers and can then be used to create * the new processing node to be wired up. diff --git a/src/proc/engine/nodewiring.hpp b/src/proc/engine/nodewiring.hpp index 3a157fb47..ee62d7956 100644 --- a/src/proc/engine/nodewiring.hpp +++ b/src/proc/engine/nodewiring.hpp @@ -39,8 +39,8 @@ namespace engine { /** * Actual implementation of the link between nodes - * and also the track switch for the execution path - * while operating the node network for rendering. + * and also the "track switch" for the execution path + * choosen while operating the node network for rendering. * @param STATE StateAdapter object controlling the * behaviour of callDown() while rendering. * @see NodeFactory @@ -53,8 +53,8 @@ namespace engine { friend class WiringFactory; protected: - virtual BufferID - callDown (State& currentProcess, BufferID requiredOutputNr) const + virtual BuffHandle + callDown (State& currentProcess, uint requiredOutputNr) const { STATE thisStep (currentProcess, *this); return thisStep.retrieve (requiredOutputNr); // fetch or calculate results diff --git a/src/proc/engine/procnode.hpp b/src/proc/engine/procnode.hpp index e85f45fae..b41405434 100644 --- a/src/proc/engine/procnode.hpp +++ b/src/proc/engine/procnode.hpp @@ -62,8 +62,8 @@ namespace engine { /** - * Description of the input and output ports and the - * predecessor nodes for a given ProcNode. + * Interface: Description of the input and output ports, + * processing function and predecessor nodes for a given ProcNode. */ class WiringDescriptor { @@ -71,6 +71,11 @@ namespace engine { virtual ~WiringDescriptor() {} protected: + /** the wiring-dependent part of the node operation. + * Includes the creation of a one-way state object on the stack + * holding the actual buffer pointers and issuing the recrusive pull() calls + * @see NodeWiring#callDown default implementation + */ virtual BufferID callDown (State& currentProcess, BufferID requiredOutputNr) const =0; friend class ProcNode; @@ -102,10 +107,10 @@ namespace engine { public: - static NodeFactory create; + static NodeFactory create; ///////TODO: really? probably we'll rather have a NodeFactory object in the builder... /** Engine Core operation: render and pull output from this node. - * On return, currentProcess will hold onto output buffer + * On return, currentProcess will hold onto output buffer(s) * containing the calculated result frames. * @param currentProcess the current processing state for * managing buffers and accessing current parameter values @@ -114,7 +119,7 @@ namespace engine { * @return ID of the result buffer (accessible via currentProcess) */ BufferID - pull (State& currentProcess, BufferID requiredOutputNr=0) + pull (State& currentProcess, BufferID requiredOutputNr=0) const { return this->wiringConfig_.callDown (currentProcess, requiredOutputNr); } diff --git a/src/proc/state.hpp b/src/proc/state.hpp index 307c66714..6ef1e863f 100644 --- a/src/proc/state.hpp +++ b/src/proc/state.hpp @@ -36,7 +36,33 @@ namespace engine { class StateAdapter; - typedef std::size_t BufferID; + class BuffHandle + { + protected: + typedef float Buff; + typedef Buff* PBuff;//////TODO define the Buffer type(s) + + PBuff pBuffer_; + long sourceID_; + + BuffHandle (PBuff pb, long id) + : pBuffer_(pb), + sourceID_(id) + { } + + public: + PBuff + operator->() const + { + return pBuffer_; + } + Buff& + operator* () const + { + ENSURE (pBuffer_); + return *pBuffer_; + } + }; class State diff --git a/wiki/renderengine.html b/wiki/renderengine.html index 8afd00705..674a5d2a2 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -3041,14 +3041,14 @@ At first sight the link between asset and clip-MO is a simple logical relation b [img[Entities comprising the Render Engine|uml/fig128389.png]]
          -
          +
          Below are some notes regarding details of the actual implementation of the render process and processing node operation. In the description of the [[render node operation protocol|NodeOperationProtocol]] and the [[mechanics of the render process|RenderMechanics]], these details were left out deliberately.
           
           !Layered structure of State
           State can be seen as structured like an onion. All the [[StateAdapter]]s in one call stack are supposed to be within one layer: they all know of a "current state", which in turn is a StateProxy (and thus may refer yet to another state, maybe accros the network or in the backend or whatever). The actual {{{process()}}} function "within" the individual nodes just sees a single StateAdapter and thus can be thought to be a layer below.
           
           !Buffer identification
          -Buffers are identified by a //handle-id,// which actually is an int index into virtual or real array holding pointers to these buffers. This array is supposed to be //in the next state-layer above.// Thus, within the {{{process()}}} function, the buffer ~IDs are organized according to this node's output- and input ports (starting with the output at index 0), and are provided by the StateAdapter specifically created for this node, while in the next layer above, all the [[StateAdapter]]s deal with allocation and freeing of buffers via buffer IDs valid relative to the "current state", i.e. the shared StateProxy object used in this call stack. (And so on. Probably a render farm will add another layer)
          +For the purpose of node operation, Buffers are identified by a //Buffer-handle,// which contains both the actual buffer pointer and an internal indes and classification of the source providing the buffer; the latter information is used for deallocation. Especially for calling the {{{process()}}} function (which is supposed to be plain C) the respective StateAdapter provides an array containing just the output and input buffer pointers
           
           !Problem of multi-channel nodes
           Some data processors simply require to work on multiple channels simultanously, while others work just on a single channel and will be replicated by the builder for each channel invoved. Thus, we are struck with the nasty situation that the node graph may go through some nodes spanning the chain of several channels. Now the decision is //not to care for this complexity within a single chain calculating a single channel.// We rely solely on the cache to avoid duplicated calculations. When a given node happens to produce multiple output buffers, we are bound to allocate them for the purpose of this nodes {{{process()}}} call, but we just "let go" the buffers not needed immediately for the channel acutally to be processed. For this to work, it is supposed that the builder has wired in a caching, and that the cache will hit when we touch the same node again for the other channels.
          @@ -3063,14 +3063,14 @@ Thus, the outer container can be changed polymorphically to support the differen
           !Rules for buffer allocation and freeing
           * only output buffers are allocated. It is //never necessary//&nbsp; to allocate input buffers!
           * buffers are to be allocated as late as possible, typically just before invoking {{{process()}}}
          -* buffers are allways allocated by calling to the parent StateAdapter, because of the possibility to write to cache.
          -* after returing form a {{{pull()}}}, the buffer-ID of the single output requested by this call is returned. By using this ID, the caller can retrieve the actual buffer holding the result from the "current state" StaeProxy.
          +* buffers are allways allocated by calling to the preceeding StateAdapter in the callstack ("parent stae"), because of the possibility to write to cache.
          +* {{{pull()}}} returns the buffer-ID of the single output requested by this call. Using this ID, the caller may retrieve the actual buffer holding the result from the "current state" StaeProxy.
           * any other buffers filled with results in the course of the same {{{process()}}} call can be released immediately before returning from the {{{pull()}}}
           * similar, and input buffers are to be released immediately after the {{{process()}}} call, but before returing from this {{{pull()}}}
           * buffers are allways released by calling to the "current state" (which is a StateProxy), providing the buffer-ID to be released
           
          -
          +
          While the render process, with respect to the dependencies, the builder and the processing function is sufficiently characterized by referring to the ''pull principle'' and by defining a [[protocol|NodeOperationProtocol]] each node has to adhere to &mdash; for actually get it coded we have to care for some important details, especially //how to manage the buffers.// It may well be that the length of the code path necessary to invoke the individual processing functions is finally not so important, compared with the time spent at the inner pixel loop within these functions. But my guess is (as of 5/08), that the overall number of data moving and copying operations //will be//&nbsp; of importance.
           
           !requirements
          @@ -3097,12 +3097,12 @@ __note__: this process outlined here and below is still an simplification. The a
           # this StateAdapter (ad1) knows he could get the result from Cache, so he tries, but it's a miss
           # thus he pulls from the predecessor node2 according to the [[input descriptor|ProcNodeInputDescriptor]] of node1
           # node2 builds its StateAdapter and calls retrieve()
          -# but because StateAdapter (ad2) is configured to directly forward the call down, it pulls from node3
          +# but because StateAdapter (ad2) is configured to directly forward the call down (no caching), it pulls from node3
           # node3 builds its StateAdapter and calls retrieve()
           # this StateAdapter (ad3) is configured to look into the Cache...
           # this time producing a Cache hit
           # now StateAdapter ad2 has input data, but needs a output buffer location, which re requests from its //parent state// (ad1)
          -# and, because ad1 is configured for Caching, it's clear that this output buffer will be located within the cache
          +# and, because ad1 is configured for Caching and is "in-place" capable, it's clear that this output buffer will be located within the cache
           # thus the allocation request is forwarded to the cache, which provides a new "slot"
           # now node2 has both a valid input and a usable output buffer, thus the process function can be invoked
           # and after the result has been rendered into the output buffer, the input is no longer needed
          @@ -3238,6 +3238,33 @@ if (oldText.indexOf("SplashScreen")==-1)
           }
           //}}}
          +
          +
          A small (in terms of storage) and specifically configured StateProxy object which is created on the stack for each individual {{{pull()}}} call. The actual type of this object is composed out of several building blocks (policy classes) and placed by the builder as a template parameter on the WiringDescriptor of the individual ProcNode. This happens in the WiringFactory in file {{{nodewiring.cpp}}}, which consequently contains all the possible combinations (pre)generated at compile time.
          +
          +!building blocks
          +* ''Caching'': whether the result frames of this processing step will be communicated to the Cache and thus could be fetched from there instead of actually calculating them.
          +* ''Process'': whether this node does any calculations on it's own or just pulls from a source
          +* ''Inplace'': whether this node is capable of processing the result "in-place", thereby overwriting the input buffer
          +* ''Multiout'': whether this node produces multiple output channels/frames in one processing step
          +
          +!!implementation
          +!!!!Caching
          +When a node participates in ''caching'', a result frame may be pulled immediately from cache instead of calculating it. Moreover, //any output buffer//&nbsp; of this node will be allocated //within the cache.// Consequently, caching interferes with the ability of the next node to calculate "in-Place". In the other case, when ''not using the cache'', the {{{pull()}}} call immediately starts out with calling down to the predecessor nodes, and the allocation of output buffer(s) is always delegated to the parent state (i.e. the StateProxy pulling results from this node). 
          +
          +Generally, buffer allocation requests from predecessor nodes (while being pulled by this node) will either be satisfied by using the "current state", or treated as if they were our own output buffers when this node is in-Place capable.
          +
          +!!!!Multiple Outputs
          +Some simplifications are possible in the default case of a node producing just ''one single output'' stream. Otherwise, we'd have to allocate multiple output buffers, and then, after processing, select the one needed as a result and deallocate the superfluous further buffers.
          +
          +!!!!in-Place capability
          +If a node is capable of calculating the result by ''modifying it's input'' buffer(s), an important performance optimization is possible, because in a chain of in-place capable nodes, we don't need any buffer allocations. But, on the other hand, this optimization may collide with the caching, because a frame retrieved from cache must not be modified.
          +Without this optimization, in the base case each processing needs an input and an output. Exceptionally, we could think of special nodes which //require// to process in-place, in which case we'd need to provide a copy of the input buffer to work on under certain circumstances. 
          +
          +!!!!Processing
          +If ''not processing'' we don't have any input buffers, instead we get our output buffers from an external source.
          +Otherwise, in the default case of actually ''processing'' out output, we have to organize input buffers, allocate output buffers, call the {{{process()}}} function of the WiringDescriptor and finally release the input buffers.
          +
          +
          An Object representing a //Render Process// and containing associated state information.
           * it is created in the Controller subsystem while initiating the BuildProcess
          
          From 5f39f843c381157752fdf5038ef86a56045f03a5 Mon Sep 17 00:00:00 2001
          From: Ichthyostega 
          Date: Sun, 29 Jun 2008 18:45:35 +0200
          Subject: [PATCH 09/12] WIP considering how to compose the actual StateProxy
          
          ---
           doc/devel/uml/class131717.html   |   4 +-
           doc/devel/uml/class131973.html   |   3 +-
           doc/devel/uml/class132101.html   |  23 ---
           doc/devel/uml/class132613.html   |  23 ---
           doc/devel/uml/class132741.html   |   2 +-
           doc/devel/uml/class132869.html   |  23 ---
           doc/devel/uml/class132997.html   |  23 ---
           doc/devel/uml/class133125.html   |  23 ---
           doc/devel/uml/class142469.html   |   5 +-
           doc/devel/uml/class142725.html   |   7 +-
           doc/devel/uml/classdiagrams.html |   1 +
           doc/devel/uml/classes.html       |  14 +-
           doc/devel/uml/classes_list.html  |  14 +-
           doc/devel/uml/fig128389.png      | Bin 31223 -> 33051 bytes
           doc/devel/uml/fig129157.png      | Bin 34995 -> 35457 bytes
           doc/devel/uml/fig131973.png      | Bin 19757 -> 24696 bytes
           doc/devel/uml/fig132357.png      | Bin 0 -> 18575 bytes
           doc/devel/uml/index.html         |  44 +++--
           doc/devel/uml/index_60.html      |   4 +-
           doc/devel/uml/index_65.html      |   3 +-
           doc/devel/uml/index_66.html      |   1 +
           doc/devel/uml/index_67.html      |  49 ++---
           doc/devel/uml/index_69.html      |   2 +-
           doc/devel/uml/index_70.html      |   2 +-
           doc/devel/uml/index_71.html      |   2 -
           doc/devel/uml/index_72.html      |   1 -
           doc/devel/uml/index_73.html      |   5 +-
           doc/devel/uml/index_78.html      |   1 +
           doc/devel/uml/index_79.html      |   2 +-
           doc/devel/uml/index_80.html      |   1 +
           doc/devel/uml/index_82.html      |   2 +-
           doc/devel/uml/index_83.html      |   1 +
           doc/devel/uml/index_84.html      |   8 +-
           doc/devel/uml/index_86.html      |  18 +-
           doc/devel/uml/index_87.html      |   3 +
           uml/lumiera/128389               | 297 ++++++++++++++++++++-----------
           uml/lumiera/128389.diagram       |  74 ++------
           uml/lumiera/129029.diagram       |  40 ++---
           uml/lumiera/129157.diagram       |  84 ++++-----
           uml/lumiera/129285               |  48 ++---
           uml/lumiera/130309               |   7 +-
           uml/lumiera/131973.diagram       |  42 +++--
           uml/lumiera/5.session            |   9 +-
           uml/lumiera/lumiera.prj          |   2 +-
           wiki/renderengine.html           |  14 +-
           45 files changed, 429 insertions(+), 502 deletions(-)
           delete mode 100644 doc/devel/uml/class132101.html
           delete mode 100644 doc/devel/uml/class132613.html
           delete mode 100644 doc/devel/uml/class132869.html
           delete mode 100644 doc/devel/uml/class132997.html
           delete mode 100644 doc/devel/uml/class133125.html
           create mode 100644 doc/devel/uml/fig132357.png
          
          diff --git a/doc/devel/uml/class131717.html b/doc/devel/uml/class131717.html
          index 93a92a0b1..2a2783381 100644
          --- a/doc/devel/uml/class131717.html
          +++ b/doc/devel/uml/class131717.html
          @@ -16,12 +16,12 @@
           
           
           
          -

          Declaration :

          • C++ : class ProcNode
          • Java : public interface ProcNode

          Directly inherited by : ExitNode Hub Link Source Trafo

          +

          Declaration :

          • C++ : class ProcNode
          • Java : public interface ProcNode

          Directly inherited by : ExitNode Link Source Trafo

          Key abstraction of the Render Engine: A Data processing Node

          Artifact : procnode

          OperationClassDescription
          allocateBufferState
          applyBuildable
          applyVisitable
          buildAssembler
          currEDLSessionThe EDL currently in focus. In most cases, Session and EDL are almost the same, just EDL emphasizes the collection aspect. But generally (for larger editing projects) one Session can contain several EDLs, which may even be nested. At any given time, only one of these EDLs has focus and recieves the editing commands.
          dispatchOpVisitable
          enableAssetchange the enabled status of this asset. Note the corresponding #isActive predicate may depend on the enablement status of parent assets as well
          fetchState
          findTypeHandler
          getAppconfigaccess the configuation value for a given key.
          @return empty string for unknown keys, else the corresponding configuration value
          get_reprAllocation
          getValueParamProvider
          howtoProcMedia@return descriptor how to build a render pipeline corresponding to this media
          isActiveAssetweather this asset is swithced on and consequently included in the fixture and participates in rendering
          isCalculatedState
          knownAssetManager@return true if the given id is registered in the internal asset DB
          loadSessManagerreplace the current session by a new
          session loaded from serialized state.
          makeTypeHandler
          playRenderEngineTODO: will probably be handled differently (see Cehteh)
          pullProcNodetrigger data processing by "pulling" results from the node's output
          pullStateAdaptertrigger data processing by "pulling" results from the node's output
          processProcNode
          pullProcNode
          releaseBufferState
          removeAssetManagerremove the given asset <i>together with all its dependants</i> from the internal DB
          resetSessManagerreset all session config and
          start with a pristine default session.
          resolvePlacementcreate an actual (explicit) placement while trying to satisfy the network of adjacent objects and placements.
          resolveQueryHandler
          resolveQueryHandlerImpl
          retrieveBuffersStateAdapterinvoked from within the pull() - call of a node to set up the data buffers.
          @param requiredSource descriptor denoting the predecessors and the frames required from them
          retrieveStateAdapter
          rootCauseErrorIf this exception was caused by a chain of further exceptions,
          return the first one registered in this throw sequence.
          This works only, if every exceptions thrown as a consequence
          of another exception is propperly constructed by passing
          the original exception to the constructor
          saveSessManagercreate a complete, serialized representation
          of the current session config and contents.
          @todo how to serialize, prameters, return value?
          treatApplicable
          treatBuilderToolThis operation is to be overloaded for the specific MObject subclasses to be treated.
          treatNodeCreatorTool
          treatNodeCreatorTool
          treatNodeCreatorTool
          treatNodeCreatorTool
          treatNodeCreatorTool
          treatSegmentationTool
          treatSegmentationTool
          treatSegmentationTool
          treatSegmentationTool
          useFileFileProviderAnnounces that the application intends to use this file with mode (READ|WRITE|READWRITE)
          useTemporaryStorageFileProviderProvides a pool for interminate frames
          whatError
          Relation datasrc (<unidirectional association>)

          Declaration :

          The predecessor in a processing pipeline, i.e. a source to get data to be processed

          Relation params (<directional aggregation by value>)

          Declaration :

          -
          Relation predecessors (<directional aggregation by value>)

          Declaration :

          +
          Relation predecessors (<directional aggregation by value>)

          Declaration :

          Operation pull

          Declaration :

          • Uml : + pull() :
          • C++ : public: pull ()
          Operation process

          Declaration :

          • Uml : + process() :
          • C++ : public: process ()

          All public operations : process , pull

          diff --git a/doc/devel/uml/class131973.html b/doc/devel/uml/class131973.html index 0ed7acaef..5e99f1b3d 100644 --- a/doc/devel/uml/class131973.html +++ b/doc/devel/uml/class131973.html @@ -16,8 +16,7 @@ -

          Declaration :

          Directly inherited by : GLPipe

          -

          Artifact : link

          +

          Declaration :

          Artifact : link

          All public operations : process , pull

          diff --git a/doc/devel/uml/class132101.html b/doc/devel/uml/class132101.html deleted file mode 100644 index f385d98c0..000000000 --- a/doc/devel/uml/class132101.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - -Class Hub - - - - - -
          Class Hub
          -

          - - - - -

          Declaration :

          Artifact : hub

          -
          -

          All public operations : process , pull

          - - diff --git a/doc/devel/uml/class132613.html b/doc/devel/uml/class132613.html deleted file mode 100644 index 90fc0acbb..000000000 --- a/doc/devel/uml/class132613.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - -Class GLPipe - - - - - -
          Class GLPipe
          -

          - - - - -

          Declaration :

          • C++ : class GLPipe : public Link

          specialized connection node used to handle the transfer of OpenGL data from a image bitmap into texture form

          Artifact : glpipe

          -
          -

          All public operations : process , pull

          - - diff --git a/doc/devel/uml/class132741.html b/doc/devel/uml/class132741.html index 1efbe8fa1..a9dd11ca8 100644 --- a/doc/devel/uml/class132741.html +++ b/doc/devel/uml/class132741.html @@ -16,7 +16,7 @@ -

          Declaration :

          • C++ : class State
          • Java : public interface State

          Directly inherited by : ARender GLRender StateAdapter StateProxy VRender

          +

          Declaration :

          • C++ : class State
          • Java : public interface State

          Directly inherited by : InvocationStateBase StateAdapter StateProxy

          Artifact : stateproxy, Component(s) : Builder

          Relation currFrame (<unidirectional association>)

          Declaration :

          • Uml : # currFrame : Frame
          • C++ : protected: Frame * currFrame
          diff --git a/doc/devel/uml/class132869.html b/doc/devel/uml/class132869.html deleted file mode 100644 index a9d6b46c3..000000000 --- a/doc/devel/uml/class132869.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - -Class ARender - - - - - -
          Class ARender
          -

          - - - - -

          Declaration :

          • C++ : class ARender : public State

          Representation of a Audio render process

          Artifact : arender

          -
          -

          All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer

          - - diff --git a/doc/devel/uml/class132997.html b/doc/devel/uml/class132997.html deleted file mode 100644 index e59220a95..000000000 --- a/doc/devel/uml/class132997.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - -Class VRender - - - - - -
          Class VRender
          -

          - - - - -

          Declaration :

          • C++ : class VRender : public State

          Representation of a Video render process. (Encapsulates the video buffers for the actual calculations)

          Artifact : vrender

          -
          -

          All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer

          - - diff --git a/doc/devel/uml/class133125.html b/doc/devel/uml/class133125.html deleted file mode 100644 index 8c1acac1f..000000000 --- a/doc/devel/uml/class133125.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - -Class GLRender - - - - - -
          Class GLRender
          -

          - - - - -

          Declaration :

          • C++ : class GLRender : public State

          Representation of a OpenGL accelerated Video render process

          Artifact : glrender

          -
          -

          All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer

          - - diff --git a/doc/devel/uml/class142469.html b/doc/devel/uml/class142469.html index 58c82f008..31b631174 100644 --- a/doc/devel/uml/class142469.html +++ b/doc/devel/uml/class142469.html @@ -16,8 +16,9 @@ -

          Declaration :

          • C++ : class StateProxy : public State
          -
          +

          Declaration :

          • C++ : template<class WIRING, class POLICY> class StateProxy : public State, public InPlace
          + +
          Relation wiring (<unidirectional association>)

          Declaration :

          All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer

          diff --git a/doc/devel/uml/class142725.html b/doc/devel/uml/class142725.html index 2118cb163..13bdadf5b 100644 --- a/doc/devel/uml/class142725.html +++ b/doc/devel/uml/class142725.html @@ -4,17 +4,18 @@ -Class InputDescriptor +Class WiringDescriptor -
          Class InputDescriptor
          +
          Class WiringDescriptor

          -

          Declaration :

          • C++ : class InputDescriptor
          +

          Declaration :

          • C++ : class WiringDescriptor

          Directly inherited by : NodeWiring

          + diff --git a/doc/devel/uml/classdiagrams.html b/doc/devel/uml/classdiagrams.html index 1df0fcd1d..e1289d57d 100644 --- a/doc/devel/uml/classdiagrams.html +++ b/doc/devel/uml/classdiagrams.html @@ -30,6 +30,7 @@ Render Mechanics Rules access Session structure +StateAdapter composition Struct-Asset Relations diff --git a/doc/devel/uml/classes.html b/doc/devel/uml/classes.html index 9375f3648..7992c89cf 100644 --- a/doc/devel/uml/classes.html +++ b/doc/devel/uml/classes.html @@ -21,16 +21,17 @@ Allocationa directive to place a MObject in a specific way AppconfigsingletonSingleton to hold inevitable global flags and constants and for performing erarly (static) global initialization tasks. Applicable -ARenderRepresentation of a Audio render process AssemblerThis is the actual building facility: provided the correct tools and associations, it serves to build and connect the individual ProcNode objects AssetinterfaceSuperinterface describing especially the bookeeping properties of Assets AssetManagerboundaryFacade for the Asset subsystem AutoAutomation data for some parameter (i.e. a time varying function) BackendCache +BuffHandle Buildableinterface BuilderFacadeboundaryProvides unified access to the builder functionality. While individual components of the builder subsystem may be called if necessary or suitable, it is usually better to do all extern invocations via the high level methods of this Facade BuilderToolinterfaceUsed according to the visitor pattern: each Tool contains the concrete implementation for one task to be done to the various MObject classes BuildInstruct(Interface) building instructions to be executed by the Builder on the render node network under construction. +Caching Caller Categorytree like classification of Assets Clipbookkeeping (asset) view of a media clip. @@ -73,12 +74,10 @@ FrameDescriptorinterfaceA FrameDescriptor implements the higher level interfaces for frames. Further refinements are made by subclassing and policy classes FrameReference GLBuf -GLPipespecialized connection node used to handle the transfer of OpenGL data from a image bitmap into texture form -GLRenderRepresentation of a OpenGL accelerated Video render process -Hub -InputDescriptor +InPlace InterpolatorProvides the implementation for getting the acutal value of a time varying or automated effect/plugin parameter Invalid +InvocationStateBase Label Link LocatingPinAn element with value semantics, which actually implements the placement of some MObject by positioning it in some way. @@ -94,6 +93,7 @@ MObjectinterface MutexI provided a reworked Mutex class in my Cinelerra2 repository NodeCreatorToolThis Tool implementation plays the central role in the buld process: given a MObject from Session, it is able to attach ProcNodes to the render engine under construction such as to reflect the properties of the MObject in the actual render. +NodeWiring ParameterDescriptor and access object for a plugin parameter. Parameters may be provided with values from the session, and this values may be automated. ParamProviderinterfaceA facility to get the actual value of a plugin/effect parameter PathManagerWhile building a render engine, this Strategy class decides on the actual render strategy in accordance to the current controller settings (system state) @@ -105,6 +105,7 @@ Previewalternative version of the media data, probably with lower resolution Prockey abstraction: data processing asset ProcDispatcher +Process Processor ProcNodeinterfaceKey abstraction of the Render Engine: A Data processing Node ProcPattspecial type of structural Asset representing information how to build some part of the render engine's processing nodes network. @@ -145,7 +146,8 @@ Useractor VFrame Visitable -VRenderRepresentation of a Video render process. (Encapsulates the video buffers for the actual calculations) +WiringDescriptor +WiringTable Wish WriteBuffer WriteBufferPool diff --git a/doc/devel/uml/classes_list.html b/doc/devel/uml/classes_list.html index 38b7af7d1..f89fb300a 100644 --- a/doc/devel/uml/classes_list.html +++ b/doc/devel/uml/classes_list.html @@ -22,16 +22,17 @@ Allocation
          Appconfig
          Applicable
          -ARender
          Assembler
          Asset
          AssetManager
          Auto
          BackendCache
          +BuffHandle
          Buildable
          BuilderFacade
          BuilderTool
          BuildInstruct
          +Caching
          Caller
          Category
          Clip
          @@ -74,12 +75,10 @@ FrameDescriptor
          FrameReference
          GLBuf
          -GLPipe
          -GLRender
          -Hub
          -InputDescriptor
          +InPlace
          Interpolator
          Invalid
          +InvocationStateBase
          Label
          Link
          LocatingPin
          @@ -95,6 +94,7 @@ MObject
          Mutex
          NodeCreatorTool
          +NodeWiring
          Parameter
          ParamProvider
          PathManager
          @@ -106,6 +106,7 @@ Preview
          Proc
          ProcDispatcher
          +Process
          Processor
          ProcNode
          ProcPatt
          @@ -146,7 +147,8 @@ User
          VFrame
          Visitable
          -VRender
          +WiringDescriptor
          +WiringTable
          Wish
          WriteBuffer
          WriteBufferPool
          diff --git a/doc/devel/uml/fig128389.png b/doc/devel/uml/fig128389.png index adc3952e4ac393a8b720975eb6ea80813e91c328..fa8dcdc956afe8eb24d2de7d8219adc18572c478 100644 GIT binary patch literal 33051 zcmeFZbySq?+BZB{AR&l^fPg4S4Iu~!NH~;)g5=OjN;gQOl1eDjDIne5pwcZMozjhT z!+UVwdwK8Qh^%Nv#XLuOdVXAX7?t{#E%WC- zr`RZ0xJF#h1&ugi&SD}_#RuV+xZ3Fkeu}z=Y|{^aCYL3@z*?R{@}9%S-F-A_?&XzB zRqYqz_u9g9+ajI21ok-UT;^jq_oNDtIPlhKt&O92@GrxgW;Fb>bXOMxei`I{8G-mB z$U%ZYcpU!k6aPCT|2rA}|GW(NZFmrQ%E7del~=`R+6u~}5s2gqWH=0bs)D9#_lN>% z4B%VCUO45zQ#6Lyn>onE-S=g?x5#OqMF)vdyAd6`Lx zX{=&Lz1a9shWF1%Sv4Gw_gkFT#i;mf#Z_eIJ6T4@GIOdsfF98^v=w1QQYxS~&)qE_mpO36Xrch95-k zyo=1s|FrZgU8^MPojf`{_%rL&!i0!gW}k7fb<-f-<5ce7l179@wsulTN7LJy=uke z#V_klYg~nH@>;(fDS0Zm|KbS@fJ*K-2lBpJxnB?^;)Smp^2^}Uc)^8@Y5Gi+_3`{^ zbhet(T>Dk0_3CdcEA*un6B9*?lNEN(C&yK!$eY=?AB7!a>?$x1Tv;VK1 z^teBDuzh`Gd zgM$;DZO5w|b8>RlYmRaVraEK!F)%RtGL&p=Y@)eL!U*o35!9X@F1NAOA|->f zvsV|olbZa=bjw<1+rq1>svbRhB)C6$QF9`KR&u@e%q?53xY3_%t6$v$j$?AXzj3hg zyf*gDn>Q#d3ybx#va)+mqsl5P2eQ>2I-B0X8EIr_NZ)2HEc`9vzHUKbVf-UU4y!3q8c{8EM!VL6TV!Oa zsn23PJUob*l{IQyRKxV^o*ti^2pz3(s)mKLY3Dd!z@Z7G5^&mCQqrfndsoCrO&ncG_E7ex#KQ)2F9T_4mgmB_*Y)kL7pBP)wK4(cn#j6Jwf{jTaPfJ>33X z=QEI_$^ZJ#q_3~9M)X5o-jl=STo^(3{XZ`o-V=w?=g~^4WkZcUxtxsGWtzIb#e{o) zwPTeI&M*Kqu1EdZ>OwXb$e{2bX5N{6OtcJP|Jr95r}UO=XAff($dn}u8o$%p-aujGPG+?PmcCF`UvL$+ireG(`2=; zja8DeX~o3Go*c}_J3Bf?R`MbcHzgY1hF-eM{Um47|U6i-s!9*aYVIgwB zGCDimtF^JVmY0_gVGdU-pb?qNEF(vJd;c-t!;rbTgCte6%b~)`2+I^_w^EdH&g@sx%)PciOo!kbYzG_w};Z8zlO!lAEeU z44u6;W#+{?f>;O-$xrzn7aR@R$?xlY52QS+u%=u4nLsyELU|ok-{6Hs^DM?!t-^L> zwEXen;)X;JYcwyXT4_sfYE*Bk%91kk++74Bf(U9iwv?Z$qvl$DSC{k3pse$r`9zIt zp=PCEzx%?`dQuSenXF8EPDn_6ykJLnsBFx>_q%tl8{FiG7x%VxF}yy?S}41?ywaNq zkqV8ubEjsdci#2H=Ws8+*r@mWaB=3dXp%JTwHd{dnV*`-TVqL}DVOu5pkc zpM9#WH%jwf4zM0nW!zDARGyTP?B3Rb7ZL`}8h)*Q;0 z+HL>kHxG>T^z`z6$HVPK3X7`eDKe3=LMKJfV)?p^S6_|=J$qJNP;k0(v#_|hrA3km z^(0u<5-Z@m^O;`O#`?j_m&@2nLWpk_AM@qjSM5)I5IQ@aH{F&FXYI>YS7~TXN=z{w zKhBOG`R41(7S0;`$~LySnQwT}Y)$Hp$dD4t8bUeAZ$msc#g-9;v0ImGy0F8LTv8|gx6bbutY^>&VBh*22 zjS|x#_tUL-lrIc0W6%=t^4D(djuMRWFzyi%5gJ~#C%fu7K-%M|PyRcPhr%aDFDW=@ zegW|f1rt26u+fC)e}MG=SEdgerJSt>HU{D&DJ&Gx0_1X7-H#vbgM#&A1(B1jMWnN2A^Z_l*YJmAsD+EtB>J9c78PqbD^XPJ$I-uJd{AbVEReN^77@7Zw?Z{{@2-hlS;@1hm{XsMC38( zA%*pg8<51y3CuVM8IU=MF01TcLd?K-Aui_!T!aInIG@s!q+=nn$bkdhVy2|~dj4Xd zC4ZA2IjoeGdU;og^OrMP)uIp#_H=?{YSRclxzT2{@MG0Q8KkR}N?0+qS7`8T-JChf z>Ju%s4G%`1s6X)ql8pL27ld$&I9&PHdfPMh^JBluM@e!cywwtF*x0-s24E4PNvdSl8-N&V6nOE~dG zF%@M&85;vVRYAKY`Xsu*z+7w^+7`p{s-2u1i<+Y~LzM5gZ|pRlrF(d#zUn(u$(?d+^X+AAR`oEs;tZQyEi?P|Q-^^ZHo&x&%^w|WkFCcV zlBc4$I01gz9&8qCC}nGu+w85~P)NaD=}Gn?WX6*|-CF?3!+#Q=8R<(`)vJ!8Ai8Jn zH+!pWNMK8mfhI{Vwe3}-{LIX&l@-%1w)^=%xc&Su-)s;_z`zlk%15{6reI07G1RT- zjC<%8VHj8tz6bzrc%1!UZ441#eL)+ zGZ7i38Upt|H4Z}Y%Ni{Uf(~(l_8Qo@}g!B#3-@0EL9)J&!@}V40P!)%sfk z{E%mQ$Va4fm=Vc7!o;>Zv&omXYevg$=x^WtqE>8dZf*`Rh7gsdUJ7i~$!_V_#-Bgv zs@M4hci7qGuzs(uW}kg5aMaMy_Mji`o348arts6%|l=%AbTb$~pm04=j!_*r5$V%sMOtZaL+7qHjf)>d0{ zGZsF6`~#z4-avehDoGX^pn#IzZ`ARaFIKQE1q84I3L9 z7uP>1$YP{ql~mj1d9~AyR4CITx9roW9ZHFltj%GK8M2=~e^w9|_x|wV!(Z%LDMJxx zB(K}?e!~Y+1$p^9ckkM%6b0+6CUws^G2FgA3D~UqZ}bf#W2aeCdv;n0hX9HL#9k`_ zby+ox`qAqb`+A*p@y@7l#OMuj_V;ecnR$SW`T6ZRwSu0@AkhksH*^>%xEdv|pN zX7NE!vUF>!H(iQh-y+841fl+Pv# z7)V*E*AlGleqslA{}6v?p?i8|sF0G+77H8O>11c1_Gpd2jN7Itffq5i?)VP~Ac zQOjp~US8gpFJGd3-(li=dwId{Q&Li}tJ4?Mvitueq&$sQPLq4N|K~R~@Xb$mC9IX! zrl)V*xN+C>iHr;`Hnx27_m&n?PlEMo(wjFpU8m}K+)fXcii|#q!Bsw zy4~H~B#9tyH61DCZa@9%-;F3yadE9m`;NZ8Vz@)FOi;eSo|UuJ9334gd9A;SeIQXt zeMbCG?s|xSl_mwSoNlAP{pzse>(|?>BRnd(*#tTu7L1gbWolOLhA=8vyN)vye5Pl^ zf)`WX1dZ_eeKo94VfG@yF5|9yg>xM~Fo<)@xk1(2@*iV0OAmK2*N1H6hm4y7g>Xy; z+_o}v14k=%MnJZ-_|$SCMt=$;OpKxbr=;-tZ^In4f^WM*|rL~nq?at{E?yH`!EilFO zR8JRE<3l8wq{_vUKItDEt=GEG$2trbn*al^fQpzzS1~N}jVbORtoKQqk)IJ!(*`z; z-ht)mSygqka^~(^WoHI@daIV;t0><%0rjgiQCwRQ4;DMJ)#slCZ#PoJ@|Z^Go0upR z8tAJEx*YFYQ&2>M8d!61FHy77Ae32Uw3t}~E8lK8ra+%Ej4l2aH8qpxLpPU$8dn@V z9$6U;5VuMldMWu&`zq{oY3dJm3U^mjZ+q@9Bsp+foIb(o&QF@>RA=?XI{C1adM!^2 zR-U6Vlq^%z6+qyykWWrdU~=I}+cGm#A9@k!w}th=lyJfV1YQ6V4x>Vf?P8DEVzg?x zwSEqvLc#lI$PjK=ngTX+wL?R)W~LR`G%KsCf`#jSY$Tgehh(jV8Cz^7D`M zWg0%@4?p`;$2E{UaUInjd*nr+Ggh%@(wEVbmjF+fUZZ-%;<+$>5;~y0USvL2!>XwU z6Y_lKs^pS+M|VXQb~cI+SJ(w+nuOZSv$~$0G?bV{``^qLc6?%leiqoMF@Gt~9;&-Y z06EuOd*tWOpLL5w`rue^y`+|m^0GD?3EbHLEl+frkJHYu`|q35E+lk_R zBx9f%My5j16Q|7?M;gy~?UBZSWd=GJcm;VkDxRG9&1oDq#V4|7c3X4xW+OFiE#2)= zJ0%1^hRTm&l9rnCx}3VGp$9AKe8OqzwO4vms|gY%@N+?B@9A~l+1u+h*#f$moO)LA zvhGd1o74mp#A>JFPqgXcc;TRF#t0nQxE%jpuaV|;whwTczrvsyu@xxq*%@)?bM^s_ zcZ!NXO~tZ9~~=QzmXh{BYgc&*hL)qQL^R=j(3(h8DAXhe7nvN3-IO(fz(J=)*XeM%`A0p3tdFS z|7Zhoj(i%Ti@a2$Vgt^gLnc&IRIvbpT@=%U^*rw|9K1{`eH>{^Ler0pd2b z9+HSZsaN?uaV*g3LR~?U_p#kZ%nW1^p-Pq-lL!Vg_!A?kc6GOwhwlk8XWXe@&(+xaXBHrfu-{ML4qon|(Trvi?;hg4vkJ-eRzZ|4$ ztD}0MqChcK7+}d@|6(SzW$dB8Jmx+Fa~H|B-B^h%zv+O zZK33MvR~Tn;hBgjbKZMXu6}8f42~cD_EJ*Mt+=dwS>K$jx1VX_@r5*2mk#Ho*)D5V zMX+ukX8LROaB|xR#ZSbS%KX{egZ(boj~x3;8vJqU@m~D-GW>&-G)x)`H7d)w=38qnEtU%2f8{wvc3SqyM7w_5yyF z#=**v^v-f6QyYAV6L3zCP{*8fgi&3(2A_N)Xs|aN@`|ASV3w+eE0r!9k5$xA~t5 zL`lpl*-I{9PPJ}UJL6|6*>G!$U=Up;!wEzADPP7%(^cMR8}1HOA^;ODUCHE|Hy&mf zOEl8+CRavj_&}O&lYbCJiBa$V@d0z|=E0Vc+3RQqsPVy}R1{8qa9Oh>$7t#S3}W`<9=P4{4AB}N|7 z>o7^19;!9WTx3;3wyI*+`NCd?lO};B_A4?>p`v+bJTy&MD{#UvJ z6y`@SzIk*Boju~@+*&Q2IGqjGW>U$i0!t-~MSaO4%{gw_UA)@$Xt&I2I*?k3)$!A^D{vt7YwP*Sy24$N%jop>*7-jYQQd= zAmT%AR>v7c>i7~Qr}o>7i$en@KUGrvPqr7|1%GCXdF1FeT=e+bwcUnac|DA*tk19# zE+J{^GjnU4K&1pcN>lH7^~R67y56219bH{;C?ZYjuHLu@ZUr^4nhK|#j2uf){QPnSpih(Y;Uh}IoPc8!QT=Zhc|Hf^Bog_ z0vV@)On0Y^QC+Icafju@qz4~qskJUQ_~anPTHLHctMY#Ujslw}x&GX#TJEy28Xg{= zo0(a#*y-SzFa@Izt`asJ=m&6~2GeFMGfM`a zzD2eHE9>fG4-o(S>C^A2DG+yT=AVHWi#zfqvliSV99Sxa1_7m|d*Jze_#H0S1Hl1+ z!|eLsohGOdY0cliKQ7JsH*ZTkhwE(p>@*i7axi9qq6Fu#56oi+i1&g!3T%u@(4`D8 z0f4TtD#t>2xP5Ci(Pm|3WdrUmFW&6g;kcn zQ7|20ge4o9uo|&3i0;mreS5#4ohFkCJf*w48|CZi={Y$$sS#9BUhd`NBjmU_1GA=w z_z5qln`nbYMeVx%yv`dB9InIm z-I=bumo+staPDrKGm=o0HjOyr4`GpIb-yxbkJ#93V=fd z6B+dW{V)tpbhNstXg%;j8-c@4{&hgl;MFcVxMrjCr^2<};Lz~sYHpUBv)ftflMbeJ zaM%N5SR2U8t45BBTrd^s=;@hn^u!Ov9g}e*IXE@}#)J6R&aF?h-rF&?z-+2L-aMZmfcw=B_@gsv2L>A2!r9yba9+V92Ug!uS0@rS z3zi&k-y^e;5&;l=e6QcFIXiVeu>-Zc6u>kPzGqPn(qS&$pnsO7k{d_xBd@*+_TB<* z4LaD2zwm+0SEixz;8lP7T~^j2RnDLv{k>%yBSI%3&p$eZYdC|83%&z#KajR1_4(b> z52OR61#cQ==Q^T4efl&~YOy|1dj?l+(w}97)+q~(kDq{b{kIeAoILaG%|&3V#RaA& zCebFbnw9ofX~3f1YL3!TO?1oiIqSd0Y4NX8(Pk*Tw@PkO_Y;0_R zrvf_02VY;mxWl|`B`o|Zl0(3GJ0dDHH2YWBKuG|3wE(1PENTuunFqDjUcY<1m2up`BgCYT zV))_(`sDDPUA4AuBN7`=)5P{hQYEW7+^Er7cXzlp@PUE%0?EHyN4PQ1vXn#3XZvI* z0}3NClj2P%@lDk3SuQ@!mZ#~z`B1*FtijrWG=&=|BZ3ZVG2P%QFn-Gan7Xo(3IeHi zRRk5aI~r@_a5)ydN1(Hn`};rfC=ASow^xr3+_e%O-knySsG-zTjT3UOCYaJb8!ppt z`%NR_WWO*O`N>K_l|I*uO|!yju?M*MFgA_bAtMmz5ciX#E)F%v*ZV0zU~nl9jmIju z;AJT$+2TokuO5i=w3rMuWCL*r;f3E}O-5E$g)bRb8nPO*v$M$>pXIRb|0{iWfc5cX z@K~YFP8nn<%f=oqmQL8ij+^7O zGhi`x_|&M-TrlkSJ#mL@hhHfXInh7`4GqKHC0Q?1YcQi`4W38&;IJ5X9!)iJ+=qn&FdJ*enid&I1!}(|X^_uzwhV#&EQI(25-xs2_4! zU7do)6O^TDqSleL9-{>2c9RkCk4;TaS7ccf8X?iZS042#b2H{vz?#G?jYv5+40wuO z#B0TN;Rdzx_YtA`SHT_3v(VlQVZ7)?U^DM_-*zFBm6f<-jNywO_)cB7CFOfls8GJZ zzxIzxj}GQD4Lgtbjt`2Iv&GE@^ClMVLCAyD$>f!7hTwmc^ON(QMU3wi`MX@&&J+$E42x87W=I zyyV%Ra{>Uz;>sn@@fz2&;o_08N?AJ_iiJhqN4y7s1UR>p2Xa0OJi1U_C7%5C80qQz zLE5xOFRjw~#aP7|x^Rvni4NsEI4I!eHr`rLTe~-0?A&2dU4j$&8;)1Z?#eGv$-z4d%kYx}<-4=rU2` zh4M|65H@W_AFSkDevO_N|=J|GLjqOo6jxI1LH&V;w{YcUyo zdf8a=7oCNO5RK#fx(TE)Y#cx8c#@OHu&_7ntkMS)8++w8<>AaipmS3_mt@u~=<&XIWb* zP3~FPEGB*dlajTy^-^f)4mw?`JVHZQcwwv(AFPJ+5JZ1Ag>*8`ae013t(t{@r*Oe+W9Q z3=^Bf+rQptm*%1CZfV*0{tl@?$so4`hN*IjLTdQ4crDOs_V+j5OgDv>nvK+tvM{mI z?Mq>5G(EmfQ7I8NyRZ=3iWH&Lp5We^&mDMGL>^!drrqi3xS$}5t`2Nogg3e_T^7Tl z;d3y*PFbyh_37hBqFYsRSlva7{4l5#f}?xWK@wEF)}62X2ojBz=E2)h30og?MrTJA zUJbg*pb0iCVyg@$RkqqiNNvyv3M$sRG`!zy^jDo(qq==g1soNB{hDxhf1uY~B`Y|z zG9_=-5fzE@O-o~ZhuNiB#E|p1A47ry^b=&i+IW?wHOvlO?d07}NFy4}9nckDoA|W? zQhdWjjQR2Mh{B{MD)++o2k4B#!E{Mw#xTlwvq)<;txTp{&^k4JgW6AMpM zy|!lgBaJ|O;j<5}*D>ZA&_H&jWKTU9FJG~TfM+VMC?vyJZ+~lo?5Py85qm?(T63I| zK`_~6(^G|qcS?N4hVK&)j`1M;uuHO}p;k8MDm>^IXGN2!Favy(ZA?vbx zdV2xY>;R>H7V|J4WNH*v9bsEj+5@@aa{)#F`Hg6BHX)@@4jc~v+WKhud1l3%t~Cly z)5g;B=c@-meE_%ZZ%p66f1i<&5$X~#YX9IMfReuiD9`Fh=|pkcK8pr!=@P^UhYAgE z5E8z9`xa2aJ=r)@G@w#ag;@W@pJ!$u=tt($A!NMsQHU-Q$kq`P6H`%95fUcWGu9D$ zy?gi0yxjfl6u?9VXyHXhy&=K-`}@t!&0xZaiHd@?Bf;3t#oT7eOye0FI|hgi5T~() z1=xbGz&?EO9KsB7W?&EF03yx06TPfU+QL}ij*SAGTQcr9GbvL7 zr_6qRTmbGIq(K?FdVnF$F}^Ey4sc%ln2!zWcvEL5>sj!R*7?^TbRFp8 ztOZ#PR4;|RKK^t;?v?jJO0%CtEvZy#3^PeuS*1LRG}~9zgKWbAJ5Mfo#`XCbyX3`; zW;=2}RgZG^c}kDu$%6H+u2(Tr^%o2tH(u}{yc2)Qq(kz;>934}ZQwe4o|2xFXRFW? zD{~A5NInTmzPK6pMA5_XzOwHR#$N&hBy8i>pw~!B&W9m~)J$1Wl67e$9>H(?y{4?^ zJKwn;1%uSG0!81VhSzFu?V?R-b8E;P6_yT(2cd_**YT6!E+6U~2+V9Hhreajl2O6_ z@3Dc`^RYoZW_%2upxBw4U(D62X7Th57@MA-&o-S}U$3@b)#9YQgg_VwH~!!RV~df~ zrfu@Oz`du38jPy{8H~f~F17H1ts094)B>m1zbx&t?|2SE{1@`jAy4`2oQ#?Rbq)9~ zpy?_K5NLi5k~kWMX4&Ac_jL~;wDnGY^JK3Z#BCiNd)MQQ##C7wPlDW<;iaDmoV>hI zpef^EEo5Zb@2(^RdJCO}FI{ofdSScjY=l=3Xf6&C?E1e1t5)l?(?V`DK6IshpHc6H z&|qxh)?!oDv;B=T(+M}*ZyudekfBsP$54yl;&b%yurNR-wO0U zhX&{6{mxbk*xe+zn`s^*VOe?_TcLr~oho|-L=7M7Pq*1%%F}7sUKrZuyHX+dS3hG` zYMy-H?8OH;m^>|wcSKzT#9UlV#u;l8s)9(*2#D^r25rq_GUITWR48Wd{-Ch1?a$`5 z{L=OPU25ofZhbu`Fq(*r7KkW9Xi4tzv%on>3OtSa1&&)m4m*3Ex_l3BfOuy2EAV_% zCmJpj-O^M=WD%X9n`NPBUsg3cIXqEFK^`q-mLGaScpQom1K=-YTW<=UwPhY#9CsLc z6zeh~D@u}6IsJs)xOzRL!g1{YwmXM?OYOQ%sN-p4cS6KR8OS}jIP8SNIHFS(8GqrO zLZGSTn+t?*y3LY;RN+mpZRP(FTClr_5GK|`Dq!K@D3Cy6wtXb{c+nwdVHg*UWdNhV zdcJnvC)`Km8ABXO`Q7oWg=^ z+5@B-(flH>hHAEm&&G29YPO1nWh@^C71f&$q!!mv8kP2y&U@*w!~_I<=;^fyP&buB zqoSOru1IB3zm2k=BspX>YnPz~!kDd`>0hgNrt ze|XaU{+-m@Go_(KDGyeJf7yPVcDjrOmwAWMaxTU2xGcZz0zq3AJw7nq6WunZDynaq^ zkQ~8NfJZebO!@p`i%Mi4dk)sa^e4LjUYgU=~Kst-M?Sy zN#N&a`1b7`PXh5wKD(vVmvujmcB1<#9l#~%zsZ83D2jgxO3sIy%)iR5rp@(c!18u~ zBBNo7PNZP|MSX_|RdsCrXSzw&e*GGR7S_O`1hcZhYI+4q-_Afc3mf{+EDW1cCg0vt zpTXXmyTj_?=1j{)AKb{jHnstXf99xi76M}dB-f_Y*BZ(X?(}{A)^Ff!GEm3jNpA`o zH)6k;`eBI{e8}tJsH*(0`I>nnNVPEt*893xS|hd!eDi;3;1+&xycpJfC8AoAVI#s+ zkpQfi7x~Eh=ds=MdX88YhgH@l+IRs;#A$^1mI19wXo2$~h5YZ|4H_O^iMlCrV7a_7 zT4^6cAo2t&9vSBM&V`VWED@@PxyvzNxdk1tZ?w?pVldEz7XL zJGu7?9M*5B4YFTM=#|`btoVV&GX}DKfw{W+^3M?Nl)Co0qg8&q8hIcfb1I#{eLc+e zUk~|r?9j@bX&o@ z`{|}TQQoBrHm}G^8fCwT%ijpmu8rh8<}LH_?p&|rO7|w*mut_e`CML?5$KGR+=Zr> z9F6kCzy6M$O)|I{6Crm2eX@r=Jw*tDSk>!|OORJH?u!8eFbISf>}paJE;&(&`4}b$ z->N!OXJfTz5NT%JnhStdoV2y>cbGz&wQgs}2g@K^WCld8Y}^%aTvmW7q&(9!UrT!2LVqHrqO*OZEw(Rz6Yv?@ zRj5BfMCKO`1W&9f=E@PkUPhr!oje&|BuZ*)jef=4~<>aqy^;#Gm5&f_}XgAV!JIE$TlnRxCsAAaXq{X4a zzTDbzI8lCnesx&JP`sa05u<*A0tACpXy_goBy>FHz-ZW&bASCe#Fx{M)aU2jTrsaJ zCjM-(e>Idv{hDk%)ea~I%2^TQw^l&-Rgw(8bB7y`Vh*y2_Rw+#n)-Bi(h8||mTCfu zcPt6z%VlCvQLaS6p?4ZU;jp)QRNq(pz8oJbEYo8v4ch!7wr|AIN*1^b>Qxp(3i1Xy zc?QzQ(=(!&r8&sW2b1TRN%DO z&vrq?7cPGlYD~pFn3YoW%pmk{tGURIbC@sJGqV(u7=(>@L86C5^VEszzrHWa`2dH+ zo9*TWb^#8OEbrfsYzc`G-*h7RbR~m>{PwVzLzkJZ{y@9kd7dzNzMgebI?>5n!+3M% zZ|&HfO!N={C17vHXAQpA3jy16$?*j?+zVkNk;b=&PZaae0BqRF04kCCVfTB%vU<>r zeqC~GG1KG>y#wB5;n%F0o6QWHmGVd+^$7MrIrfM3H9iq5|hh`W^& zq_nbGE*R#gePy&6KRKYX@(4&5@CcKAxtE6e&@ki-W)fIZq^Kf`2|*4H`GsoFP_J*_ zgdv|>y61O;o>nqSz>{tkD*@56^1s09uMaCta5IlwH&yE_gQN9aWB7&?V+Y04mx*uC|cv!pGC7 z3Q=MT3g$LzTU%Su+T+XNC_euB#$C8*M>-}H@e6Tg<*a@1J|Vsc4^9q_#Kc5Tf+X>P z&CN|d`;`duVz5KGP5Nb2Yrt88JQO!DMBsXV4aZAC<@`1-YH1-|qhd96b#?tntjiJ7 z-HmHo6RlG8^=PBQPdK$rE)knE5#`h--#miIAG~f`5E1ci?=oRdQW1eHWm|WW5G`G- zdV${8<7sFm{QGkOGSxa1Vte?LkEuyXQ*n8IN?b;Nk#`mlLKxq-X*^uYyi3ZK!*lqv zF#r==s|#91c2}j>2D=MEKdL#Hs|USH(fCVi2r~H?;(6yXh#WH9RTiAWQWQeDDTa)h zom~d2JE3m>Ka$;rYcv+?`7m48#$7X_M}%d&e#6dVJMt{HqDna%;|4velAHhEgbaCf z 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 literal 31223 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 R(AF!&11W`j1xSPE{{vQ1H~jzr literal 34995 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 rhmsc2#V7f4Q|x< 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 literal 19757 zcmch<1z42ry7xUQAky6k(nxogjvye7gp^3vATe|!T>=6E(o#~=9nvWc($d}C@5S>x zYpuQ4TKhfryT9*!=fH#UW@he~`#P`l{QrOF6{ILHg^ogk0)ar#rC&moA&`4c5XgNf z@_n!+x+tdx0-=ORLnTz5zHH67YQH+aeYkhJF8Q>)VA}kfPPO$r+42I}F(bw}hg{}j z8NBL>{PJHY1-6=T<>hJb9{KfMHw5j;m38mXRc9(cq53q^dwy-Rb!D8$m@6PRT$hZA z88N)-w!)P{+}E>e_cOjH^^O8u4W^|U4MKOaHDo7^4Y;sB}lR*ywpjxfoE!sAQ=AfHftvede}<-3_9f&^YC z2Hf6UR`>R9+iqifaY_taiNzWfX;(ifg=)DXV{?Qq9xP9Vg?02MlzRtG&-ey*&U(Dj zoz1xSVC8dSt(KO8oNR5INUT2Dcz#fM+0oKB_lw-Q3abtwdmSlS=?Fsi5pF{!H}tElh=fh7U;@YwwFWy{v?^uvd<-sEd8Y-zrj=)-{@KdgU#39GbTwd<3KgK*o12D=gZ z>l4N6NjRN-=V#t(y1ABSWp#IVlPt41ZLog?t^jop9cQS4^Eo36i`)ccQiGL!$`*mz3%5;1k&-IymC78{)m<0 zKIgg&^nN*C?uyPcFu=96a<8-$P*zi8 z)ls%XrHaha6Uz$>d=ABqHrO`e< zK%u3Im(!`XH5mH(Q7MA}o#Lje+(L;{7DB@HIz=!DpFs2x>XhfrmENOA7MZfGD)e2% zxY)-V%hwyDo77Uz+QYOQZatJPPYT|>Bhb8_%oku14@a5Cv+q49E0PbOF~>Uz|M9#5A100X7z zO-6}wPFk9-o%Dk|g*YtkftNWKBe^K+nBU*2NE$!Ho2B(~^!uL=)!bTe2b3CHna)hU z(77&U)uC(cpvP8{>4sbHzUG51b-TUnbG?`F6hUrAE~Q~-HN}%c=%mySwPUW%d2X2N zL*U7_5FxSi()Fp<-(EWHTD$Yk0C%$7)pL827~ES0TBLY{ViW=gm(K%OaRz@COH5U` zi&>2MfA}DlBH}txQ80h79DTYg#y0DEailO+nSzEf>v6bp&8qXN5_Vk(hEK4E1jOw} zVAhW4O_hqo4+Ah%_$tL?jaGlc(b12U)YVCOdtsL+FL3E^oOZNbpsjqhj<<@6duMTa zC$c*t9>PWotrRmeVpG+2Hj%`_*nw=?IX(RVq4F&&P2IAzO znw#L6NSA)tVyMlg{yRQb=$zEnOD&AbpDcTq(WHbd`~=t~|9QKe!-`@8@@) zJa-8>#Tm?$9hZ}v`oh0&e7+ycqQ$UR4%tJOP?37{$TL|GzC4(bP2o8mBy_;(Tyj{b z+6%`UWF3*KSG}oFdJegPg+sQ z%CB*){GOkG<%>DFzFv;COPdaE+4~X}m=V95o9XH0^Lcq;nQMdyP1MtfX^bs8SgDas z{}i_WHkV{S8y{p3%}B3>q^7Gfn5rHgReA98Ua+zbx;3s<1$-QeAiEfvJotpQ*>~wYKq!LwxPKck-hRNgWZg@?T!A4|kMU&pnokpc8Xe zrpm^+&rSZ6gnPQ6NbGuqjcs?(>z-Y2-%LS4c2?#L&TdI%N^FWA_xsdF@!#fV>s>Qq ziHp0pvX>_rCO@_NuZhUrd%L=lryLwA=4y_eo;MPCNh-YXrQ_xG3XFPP*Sfl#-HwEH#cPN1H`+TT_l>t%kkR)ub&g*LfB{#wuhb+eKhP)YMaB6&BBrNX2t=c1D7< zcotePr|9Ve)FuQvGQ+Qpys ziTw4=hbg_LpO`M?`nUNXAH$PHMGlVEBcq}+l$222+&!Z-k|Te5j#6nZVqCDcbx5gEZ=k1;*TzV z46y_flE&%=XhbP8xSVWdiob>8WYEK&|M|&wF@L5yUmf*|KgW2rdi%G0L!x>&0o_m0 ztru)>Wj3B@1(S0^0*UsM>)NxH&m7m+*E3I_-sI%J+B_*vdjF8w|lkk4CFmDUaU0%-C;4KCtO}z*<-wnd} z@vb%PIcE^Vo*qx5z_*i22>PoRjjGP)wykX;p4PK&{4CpQFJ2hM)OUpIboWfes7AU}S-ST?v~ZjH~m|QPL61vyhR>7N~r3iXYN;i#TtJ(HR+x)VDsIDJOR4haSJ$4JwGRGHyG4y2i<`CWy}e<9 zWMrZ!n5Ulm>Afum=NqH7=;&IKFIaL45n;vie5{%F_DyA z>WM1&{tdbP@k4BeP-amiGLA?_gWHCr>^|~~Ba{4o6i(qwgMhw=ipxZafX+>WW~WNv zgM{xi(Tmq&wA6pTx``K=lWl((Y=I?gle&aJVKr7O~qDa5N-ewNyR6}Ia2B` zWy*rzgwnB#>a=EX8i$sLHW517>Fl=!2YY+3TQD1gg9V=+Dn;SdzI`A4K|kC!XE`dR zJN%~B`1?|K?Px&{lMZXW{P%GA!~A@5=EToQu0OHVUO$*u&X$$;JoG3NyIM%8u~Wa|#RF`!tE#i(iDSyzcgUHVDRuiSf$U%o!Ba zss5567|dHC`4bw&&hOs?^&o9RYw5J?YiiQ8{qeg%D?+aZ?cHFnAoI(Tb%Al8e zbLThL^))qIR5wA+HW;} zX}h~84Gic|OETxD@yJu_v40-s_9zv&Jy(di4Z`m!Q7_bvWIew+?8hV*Y`y+fY|s%J z8d_IZckcnx=fp%UEv@X#Ol&0&kDDg%2Z;B*Gc%23WKgiHYin^M>+9W>lp+%o6NCPE zfLALiVPkWkl^XYv$jbKQ=jWUBCrgXw+6Oh~+7G<{rWL1NqwSLP8#dE0Hf%A!E@0Uf z%((hfCoheMBU6LDN;*oOOu+wVo_bMwMuzL@4mmL~qt3$03IPR$0@TdR3<(KorUstK zVIcYPR*Kn2`E;7Qz#Kh^& z40tk}t+1M$o}Ny{!^1;Q-|^#z{?9K0mDY{b5B=?f7I;R;p z%hIZLwvL#3mPzL^$p$r6+0EIa{G8{mzR@UnE63pATzq^v2baZgbtxq)>v#XLqht8p z&(RzEUD(a(oR%i<;JBkHku${c@voOMn@;fNRymA zDJlvl*60P*AULzOnMDVDLP9%Qg=FEu;o(JxdZ&FKru>|oz>tv5@uHNF5ZQO{(tB~* z%&EAVD$S!TkjCrYvhUX!zsFTs%@7c~y*fNt?y0nzIyqlWu?u?{hZR{`dRXUtn5B^7 zu`?||O-*fOwN0;(Y-(Xq%B-cK@vBfr2y6kDlboD9)(DjJ)*y|!I3)@T5C3_6d5VsP z7MN32^{cgYX}KqED8Tx$h|ALIs^j)#d2es;h72B}3O#LB6QXZo^6k~>B`a=TJeNtb zurntJ7-M4&J+UlCMn*%l(501?lNL-d5S_X@I|BnRjyDOhu_d7U`}?!Av(TlrwJPUB zV=9@KFZT`(a4Okwg8b1*3CPHp@lgDpfpVoMDJgH3cdgvWejZ@vYjn{=hn zV)k?;SVu(m+UDkWW-Vpqr}bI%lHA8f^6C!=2nhWB{F1~xMV~y8s99Pc&bFE?o2a&1 zT^q~@TKkzKwAdb2>v`(|5GavnMA|E6#N1_!Eqw5*oohmQIPoS(mV@bCf^p)fW!nUQh4y7_6yJ-e@3 zzsHa&DpTm{dG{7OXhGC0(5gj7C=4O6nt#)T@jo9 zb+_WVHbK4Hfq!#6J~LY{6ta1=X~N@T-*~)v%A&Or6OHS5bJdQBO4aIm{hu@XRgz@c z8o&QS{J|bPTDO?de|VN%avx&UNu$HzJXC^iXP(v7HgDb}K=H8H*FkYlpMG>SML^K5&4Y@% zcyuIL>O|5sm1959+JLSL#u-*}?w-~1YU;D_= z5IYA4iNL|Igl~RJ^GS#n7Rn2Ab8AUI0Rc>A7BRftZzV+ELwcybOh@z6Z+d*nO3A z9>-nu!$CRDb_JcC*452yja#Q%6FrgCjdvw|L&MKdV!cobF$S^5&i3|>&d#@Midsy0 z7&kYK`8qol;L5Ch31&Z2#CU0!1$#;kSHhNm zO5bBZLrbm zUg)nJ?(I#{w3~zzYh+1obni=YbDB!6ho(-*B(p)c+0Vwjx}Oc~<#js|X+HS&NTP*0 zz7%GNo&!=fJ#+qwfc$%}GoBJ|@vyT>naf9KxyRlU$MNwe9D3xVaqqQ1DDMAVUH@-N z{r}%LsT61}1Y7&hG&yGD&jo9}*a^5d`glr1X{z`}0f zXVtFCb-x^JXb=mdXsiRzfL>jdfVNm=DE$@0|HmSAoLqKQ&2@EB50H8}_#7)Mk`rPb zWVKa{sYhSyHn`P-7ipIAVnx=vVqs5ADNI#tI|X1YzLJ{(g3EZ}40UzLrj^nl7ts4~ zqdDm445p{=1657BGBzgWa%)1iYn(~ve%SrIcM0vXbX2i&pRQEY95|nvdzZuM_2wcu zW!L6Hg8EbDoNjM)Vbpw%5&r&y>M4O^1&L2^k~E9oZG3!EUmc~CAu1=2VKUKrbo7!m z@#jJUCuwfs!Tw_2!NG})D0UCs$;K!LoiRrb-O9?&;K<0w={BoS;^Dcuxq|eCi0*C# zPftE|b*c3+`J^|)1&QZd69%xE$u1Ga8t4HgHsX!!;I02_p0K&z4fgzC_hVoEgl1V| zBFQWK4*{4VEzKBPb16#;L*pGLP>|Ni#@$`m5=*KU{$QvHk$>d$?}T?m9Y7m!abZao zb=S8PURmy0L|goo{^Ahmx6`<}d3m64dCz0So1Vd?YP@`KpaPZ z*$oZB{QS1#z=5x=argI3S-ee^g|@Zz_w`Q8%7n{Qs%bKYMkq{Ham)@VTK^;)zqu~> zDoZoV_lKTeTdX4m5`3;aU(}ONx|Un>tCqN@#LrK`9QL)Q8ywD1|H48^C(!qoIu#zGmtdeyvFW6B2gozvby>NBZ%M%NvyPhDV`;bC zH(zZ2EY1m0UOY=P{j)yjOsuh8ZvQI%Btw#gMD!}!Vm#e2)~i_`I*g~G2@edvDg3@C zt?|plWOWw@XG|t;Br9oie7D?MtOmY$y0CD+I%;pPda<2FtCX(7{ZfsCBgDePiG}HO z%WSaz@@p!k0x2oQpH4tQzTnyAZHdD+8f^S{vk`mnUkds-nE7zlbE$Be{-n*x#zuU; ziYQj^_Ebg%R3mc|F8wY8?$@enC_LOF7Oc5ha#EREE(zj z;|hh&&gK!Yh3D@m@$4EAN$o@=OnOC#CLA^1Ubo1OOH5Fjs>Y?v)quh?f_T`oBmBkV z$G(o+7Y0Xb6oCw!2c5I^L8BtyR_dW6S$(dFeEoWLPR(MshK=w7W<_jdlF^vRNIB@7 zJKs)T5fUg046ZNYsig#u*13EGVbh)DqF1#eBh0RsW_^j6urbT;<;Np-t3$M>AS}2# z`)#bFTTBd@fjM^peuai+4+QQw)?-dCi|CjbStuAe)rTL1|^GV@WGzs+>*=~k|aI#IjLU^+{Rr|4W$Q+0ZJRG`bz-o;jFb+Ai_xbFAn zsRKS z8*YW;uJZmYD4|_Xlfyz#K}mJBk!NHzNyMrrsyXch+i8)CNQUn)|MmbuwINfX7%nupn1*53~^LpHuRItGc{;+Loi_{xeDT_OL&ZUO^WFQw)pLb*0JsEtUD$D-}vp_m$on zkYuYUbKagUDp0xH)Q$A!hdJ$5+pYJf#0d(p{C*=VQ`2rWT@~3gV=~kv?%3k5shtM2 zs{KW#?JZz-#Inp)m}goW44*f7qk_`|6_2Ii(tXmz+-GSFjO(i_edP^j=|#!9A=j7v zT5miC^5a+52Cqpk3hp^SAIK?;VRBqv71OOAGMTQDc$OAXyuW79!78n`x37td59em+ zw3~0H9P(Ggyts$%d;Zi?Hwunm7>b2BHmK0aH$ z+U7p?YgJWS$J_ZVS(Z24j&S&NquBaveKR&S8K|z8ZWq$@=ZV5Lz>vPVICgEkacKiq z3j&g)n3Ljkts@~!U0QlQN$5N`moKohx%sR$sE5Yp78h1jdPooS!A6&3W8f@>^^K4V z%}%#gXma%d`$`Co6R08?N}Bj8zGUN9u`F;^sHoJ{JI0Hcz>uo3=P0k-<#j&jj$_lq z9&8OtnQPRuUwV0P_UYaui@&h|`@W>V3m^^p(2Sa~{P@DcLIR2uJi@rMS=Smpcb@m7 z-^`%g`pqAcgcR5`u!^1bTi1ujFD`CCQ9J~u2QcqOJQl&iJKC@^yKQB+jpq(&y2etE|4-!cd0ZYP6Rq;$~YYvdK{F;Jv?0p;t+t@Ewm?yp+WU81m@cToT1zn*8rgq4}eVlIHj~id4uXMt+;78<6#U zhR=Whyno|6eVJ8L<5xkIL6FG!M6=t2jfeNODH$??^dFMuIWmQ;EO)Uc$@|u}v_x%Wk6j7^A z6R80&x6WQXL%GGYqN2H`d8$V$^dEgmh7jx+oV)t_Dfr)~ic@|sD|;m^J&)41Td>rg zz+=J8!jfm%LsR(OYN`T*T<~*30K<)Rh$6$*Y<;bL^^w+_M4X(30_(_-kRG5aXvT`ToqY%5 zTa1)6EMKEIy{=B%MT?n|GF4_-x89|#we>qQ5asf6a~Wq{Z?4WSPj~G|tE;O?NJyA_ z!by0Z3JAm-O&lHBlaeM*)(OUtj=iJN<0~#M)~bYwcw9MI&5G1@!S}}a_E&MargIH!wJuTVe&&WDz)yIu?o_A)7AHbY98IqN1YW^3mc1-K9cr zHPxh~vdhXoSxD&U)R&YT6ck~o(C6TDadE+Zp#@Xnp^T2qy1litwWV>a_qcv@AjPWr zwbE$eX;oF#)^zo7YpdaGopY3HX0|bu1}8{HR#r0>KL`p=qg&C;b4%?F~nk65;VvMOy zjE#>M%}YOj{v7fCj}8jYJ5@(ZQ?oCgE1+Nng4I(}X+2j_TFS-2QCwbL4-_gZ-K6fm zOq;V*QS>+$PvY)@hndnIyd>W` zTltp$4|6E<_ffoaqh*?Uk?~OVBuq<)9!1IWjl~B9NRd0-!}9UBmbf+lZt@9(&^hcK zcx-%^g{$(ZoB$)Z4@{#sX$Bqp2V05;KB;CXOQKFeVPQZn%!`ko2%zvF!pDCB-PzfJ z8d_VkxywG^FRYnv`u>QKNrQz{3%FF*eKU^hb)}XAmXb&ZR^5h9nj0Xn?RkB`1$|{hM z{y&G4g8fpJIIsLdXz1y)&4#mpCBE~+_hA4gMeH>E{J_Xt{JZnv3OtEBYHBimVitx!JqF3nbVbd@?d?M`pzwf#XMuuEFTBcWe;1^v z*_kuna&l})j4>{iWiaWk9`r>k+&6lrYeryq{;WTvI4Yx@X5n{^geI+(zBsN=j@CCq923u6Kc#Rqj@}I^I9kXJBz( zULp9EKk-|__exfFPBj|#C6K6n-xsqTJU47me3G4^zI{?AeVRu%9fdS}#?UR!i)75t1w!gW#ShLrjV>nPMY}EVzbt$ClVaxdQ^fIRuJ_1Lh}Wbj4J)? zj0WISqoaUE-~rj{FZSB}d||40nqz~-Ao&dlVt6wDEl!;QyUTI|NGZ{DexW4gre}K! zg*qWon&~gCYh!5j0t1b3HF<3o+b6)Z17tssi*>2ttgzr9O>JF|r$R!pfxUfGD@(05 zEp4ND+1s<%53nbG*~dtys5BjP8%%%1oY?tV14tbTV&~XOE-o}Z zbgXZWhOBQ-32krHBzz{Cm~^Oj z=E{;G-*+(0i4Y&SSd0*IzpW35c^x2N*KTOiak6e;W;xwGbkG9yYYkqdn%uxZYsv7d zquzKp)gW;p&pJ+*Sou}oCu+Zf@)q{cGwP(c)3xd9BeB~$=Yyr?#+w>0+of!9rd)U5 zwGW^_V`7^Bs$Q*F) zx9E9g6AY5~k&*m`g%-d!-UX69eW3TKjXOf4@-djgAL4l zisu=+GFEU2GXLv~O?(hLu!)GSe@ocx&gxX@0Fu*jXDK^tmXZp{{kZh3xRGazUE6Sn znVv+}64p ziUSn@BhscG<hvUjvd1 z$Vi}wVP|Fi7)bYu=wMHO-v<#J@EzQooO{RD(hPVNrh~$OzsitOXmibeMJ(!G(=(Er zCnEBkUcn(*%#-=FD}~?YWgKgkPR-|V3bDXI2Ou$k@~|bqvjo1m55jF=KVGNhm%GtI zM{fdR?<2xEQB=b4xUGmIuCWy(DsAx?o?rv+u&}fDudb)ee#f(S${O5U=QsM__NiV0 zqAfxA4<2pbB#9)APS_Yp5jpg4q;wKhwtU$8ZJ45j+@)?=7{ZQE6E#h)^4r7<_af2< z034b%3`=(%`~+m(z>hq_z(T8g(viP^d>y1u*5)}fg2ep|-;MNfVaB~P&jUf-=qTHn zk+ME8uBs`@%gaGox-la}>z`^yNfgTz>2hNb6WdVZuw9Y8%5H6KVlxk>Hl3PRp9Kzk z07}_-33GFEQ-0Q*(w|(vM3BzP!~`(oYreTE>j~Sc*G$(hLg+qx*s8OmpBuLO1qh57jG_Uf*Gf>e>RXGnoqzI*@ z+L31jSRw|AVX1yg15jM3sTwBgF9UphIvTG^#As=w^@&u5$D-+l<{FYHaP2_oS_g!| zR7DbHI-n@&|1JJY2-2kA$4uJv7kcqH8xJLKL`7v9T0b zgArmol<9YP=C*ouqmObEoLl%=)Kfxd9l7YJsELxypI-MwXw|h}Nq3c1>=+svem7BA zsIut+@lZ1KJp-$U$9(gggTo9jER=#POAK45#vY*0FHUzTfaY;|81=cElr4t$xG?Lc>^O62%Exj6&5WN z_m1mkWfH~z60tAGtvrUFGz zgS#u4NW#^Uw6uuJLkN!V;&*)p5oc?^XD z=>QOtZKF3AOmDPYU&3~hpT>yYy4~Dab42q^C6?LpkMHI+%UqRA4D1(D6n3^HtI3lS z6CRsmi#Ip0V7Kdm&fhMw0_ISO=TLn7=8+LO;O{3#*)) zSV}GzR;Z{3u&L%|K<4u56`_bP^Ax7eH+az96`~5JfBB)(@KOGu7{GJgnGTHWlQ-9^ z{Yg`bI=(=EGq>Qotd!V}ic)USBlqey4}Iu+d0ZMC$PWeVf;5n1TbDup78^4&P3C#_ z!H!b~@4L{CoU1Gd{b+}jFuXOuG&oV036yuD%0=eH>saTBR| zd5d6_PREVm;1t%>2#%HBLKKtQ`P0pac6L%|X>~xG0Wc@7&MjatU{_&_M~?;q6EYtt zXF!|E`l@ZB=`dSYyfCZ*A=8$kmik7@4du4aDFAwQ7-3;XB=u;L;5~6)i92feJs|>U zBWd=LwACz4O{IJRe*htY{6n=-`Z5dabwvKCOQjcHx#HE1)`7L0ql6$wtxl_{0puEP zXMTSMz0ZR6FW}zI?5`f2B8WTdLk}H>G=1mMnuLDfK>&H2t5W~=KB6Kia>8U(Jma+Y zy#Fqmm#xIW2mvQz>Q5~0V?SSQh_#>Z4`8r{nl2&XGI?!Kn$Bv%y?uQ7A)^ulbzBH2 zO|{PkI&m?a?sb0n>xE9<)%adCfUh6@NXH-kfD+iOguT-DTCup{0s5%oEKf`~mJ3=4 zXs{tqOwat4Fu|{-`%3o}xe(BI->VWqB&Z*LrnonPCP7V6PFz75DsJ?|lmr7wG_~Z< z5gaC54{!2$(2|<)xBriNH2L`Qq=FG1>86i9(Y`v? zV^L-dRH5&lo>3vPdK4+xpx=N^=NT|4I!l7k7BzG|fIby{sigfE0XUvoQ`uu!2_ z$6uH+tgS7_fTvS;=4fmz|7Nn_`}b?+#GE{#vee&>BJ~8!J+YrY0Rddq>{|(^cOXbf zL4+XXYbPby=!;(j-cpQxP-~vuAGxayIeI4|z?ASwUFn3c#6fS8c+1QXE4TD6P?ng3Fz$trV=^xXM*?4e5)<|xtj7(uo$ce7d~Mr9 z1B!PddoABf6_u6_lk#31$PK0GhQVf@AKEZCl9od4q%?JImN6vdsOm3p66-8{ zwwfX^HX)Qxu8Ru1Ic@Z8ID03Z$h%7}Sk?@ZYfwD^Yb%I>-zhkOq!dUBd^I5bayeKs zS`SDOup4bNDh4RfZX;W*4RvMNQB0Cf<-f^W(>wVPRb%|qg$B6mJ#=i2H~Q}6oAP_m zuerJVEtq;@9@@4imKOjR12Zr1PYTk~9uuDzczf?e(JCP#Mg*Bol*|R1PF36~_ZuV9 z?{9B1hO^(orhY(G zW6$`U($wm0>gCaT$nuHfT};(5cy613tEhn+7vhnY?uMY;`GU<#SwU?GHe| z1ejJ(%7Nr zsFQfQV>qFBxOYep-m9e43YzH5d&>Ss6HMxbFXP;9&Q}94$QL}e0OTzxDXFVF>viuz zZ(m=j2cH&`?c5w;#Es?GoWgB z7Zw&47l#3oupR}#WjD~7ARr(h8_Ntv&vkD+7u?<+Oxo21Bcr2COiXY%9GDtMM@Jg5 zER2kUfxy=GcK?8YfDa!K5D>~N#^sHJ($e&cbn5{U3=U7sVM~Jw zCkUFEnaSJ}3{9V&)&{LHz`L^csJt`9QqpBuk^KO(*^-HdZDwj(RZ{~nV|5jk;f@X| z<41K&pbvwJ%jBo9^MRqIWqv`yHt0y~?(Y678wkFyZQz)!jpRm0Mq*Ge5ru1AwNRf!ie{B&5FH62qiUCzrr& zK9V!v5};S>Aa}P@w5yH#D)bHb|F;S0ey{&bNDKAQ=>YpR`%UwdDj^(|#NWnn0=i>O z^`_QA0cd0zv2t>K30x+j(?XgiVNXo?V`5@}-^mlla6*jDUH&0A`kgR{^b1fKK-hx% zkl%&-yek^##c2*l)Xj&(1WpuZNqq0rNKAhl?Gl=yUrw(g9_z-(3((k1B=&C3rDsHd zzCXJu5Yn_NA6ut}-)Fe*BMEy`J_PtIF4%PHM5(8TH#uh}1cEkww=RIi@;`CG!lxMG zkyzZei_6Qc?4d=workNpE*8swQoPd@ettGCf~-isS)e>HF*gr=NrQ8Hb^-V6HUG1e zT&#fGm&wY=kfz%~P<&D&6W7)Zn0q9lWE;aBQGq}WML~I-A`neiS_1HnQWLhSZQ!wh zeqL^Ese2@3;7|+o8pj*1*T{wBt)}?{0<+}FL3V!Jj5smOpf$xxOnh3k{TJUluH=Oj zkO$d#b|FZzKgv;l^zYhBs%&y*(%dr6D;op~vkcjsjQEoJ}_1B*&z8d#& z1BxLr$~MVp!uhb>+|2A?gu|;H6h;)&_kKHa+UKxPh}<*%01~tR4$*nXw`J(K5{aWx zlPvp}2S_kdnl3$GN%&zg*81j+%fB|-X?l1JHhJIN_s+}AGyz?NRNXzU+;5x6?CcyZ zHgkcRa92pAS&Ro68}CqfoV`{ZQHrPi06th6e6XZT-|t`)ee;bhKqKKGzcDfCn5`wG z$0`GAbHRTsCbXA{xyJlHoB`2XQi|;}rx8B3Tyot305o=ILPYG0XBymB4P&v!9wX6u zk8*E3TXEs0rIk89dL!(9(frG)wEPhANa#E1BV3^ga2GI ztgWH3u(-GJWEK{xX~zFvApkjB*WNq^2F46mf>H$uJs104b_M(=P)-bt!P-kK z_2+S^fv3u5 zo@uxeb(orCf`5SS`13}3yFo*-TVwpa?(Md|A_^!zb6OI99Qc$6r0oOo@UP}({S8$q zw8fk?RtN(+f}GCF3LHrsd}|3kW#3_@ifL z25ZZPYDpD80s<(6^J>3?0=QTJK>@gf-Ab>Lz2m3HfCJ{do54X3RFaV6%|Q>_<^)~~ zJDANlczJh#>~3sKr(W`BVvsRlAp=}R zMOoQ!?4P}M+S0H8GV#AGu^u|!^h1PbqM)Kuh`1a9l!9bqWCa%r-5e{x4T3VMgz!dhkSsLURQf_E3{~%D5rKITj_{IkYJ_bG(^O*kj zIuBe7)!dA{JS|1V)a>kz5=&|6poWG9dm)gtfJQ1}QMW2z-{-rt^~C;>tb?PYeLX!~ z?Cg}lz<$TYRSK9Go4K!>latInpp$6GGvdZ}Y6$+} zSz4G(`KFN|^!gj}xocbrX?-LcZnmrchG7 zY4oUnNdx+3mVxa}L&0O%`LWz$yo9;ddQNoT-gvUiY?EX8Poln?gafMPug+$jBtd_^TCCEX)In~C< z<{)wFe(ys1$C&!9uB;pd0C^{(k$WTLSue^zV55s$jjp_jqC4ECIS0_o2tiK?&nhw! zKTzo)b-pAeNQ^2E5YU@yBjb5q#wP&xW>zyMU!uDXf0oiq5XS^v6l(1UK7>4o?U(vp z!Y#?2YWV)93MKOl*&rTSQ5489YpmP^-L{xc|L7hE!?&B|9}vFzzX)fkt)R72Htx}} zb;p$J=t5iM0&lh0#zqQ!V+r(6=3Z2?!K(ddWlqx8!C@*IE=AV6;tfp^c{}p z$Lne`f;A*MLI`hTdrB=qc|TFoRlfCHMWw&3?;Z&ecCjVZX+R(#Cf}198(Se^TvdVk zK8DG?&9$#@3M`G1otw+??!$ANef_QgdqAEhTpSHYRQ3Cmmew00f+lZQ2N7&%Cp1<+->BciR=I2e>D&RX`hJ zvPA*Vqd}4~m~jcrWxx}%mKsF4gLZOclmk5EHx{Njs0anVKEg~)xZk*G&oL10xOq;V zAAv{-fz#7K1NP`Hv3$ShV59HgkXB$d9)v3QI`@L|p;jv_)xCZyjbg)^-5v8u~nXhl0hj^ zj?Uuh&rC5--HoL(uS=lyzX8o_Y@mm=hn1HpVO=r<+uo{(_YtK3alFZ4Dh>+)vMpxFx zsTw212PpyhuJKD*C3-(bcE|Peg3fdt7U(0^nyPaXhz=CJSZe`bo8u1iuST)YOygrP zIxM2|b9WnHwd2w&^ID4nzWHI{gQ2N5p5WzGaopkuM9wJyW`TiraeexjMQdZa@z!*J(t;{M>~8+9hhTk| zMwO0McOsD*F>JX%A=_!n&e2h&S?gE6Dn}AjUXIU4${SP7WOy!2Kx{ z1{1Bn-&(V<^np9KDhNm2uKB|g(C%;0eiV15%iqFIE|dUDT0mhiJ-q=ItE`R=sD$8P zD%8>S*ytDIyX!}+tBwU6X6AALSPsSI{GbXLvp{(5OSEu5H)`yNz*G|`W1i4j4-dLj z)Qrc%V()5g1#^ZRrD?r=Zrs`1?^TSMLPVj*rs7@fXevEMRABtunMfFCZ5cG7&~$`z z{MlO{wkvqgOXiQ|QQnU|O30V2#nQ{zCh}xY|JxE>p9Q@Slw$F#B|vX{w-jQ8jjEI; zCm~p1>%U&hYj`Tv?bGrX*1#vG;^&~rp2Mh1`ya9D->d*8Z|w{AVOK-xpL&m$+SxZ1 z7%hk=2>~KV|q!|S1Tr1+8o&Amo4ZQwzxr3EVYle+#>N OkMs+9XyLQBKK~0|cLhZN diff --git a/doc/devel/uml/fig132357.png b/doc/devel/uml/fig132357.png new file mode 100644 index 0000000000000000000000000000000000000000..e454c31e9260ad9bb2f9189843f9759158a0cf96 GIT binary patch literal 18575 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 WQDI1MrAYxO0m0u$i
          Artifact Lumiera

          Depends on common

          Depends on gui

          Depends on proc

          Depends on backend

          the main executable to be built

          -

          executable associated with : effect, buildertool, segmentationtool, aframe, assembler, trafo, explicitplacement, auto, glrender, link, parameter, renderengine, allocation, vframe, toolfactory, arender, renderstate, label, glbuf, procnode, stateproxy, hub, buildable, abstractmo, nodecreatertool, projector, interpolator, edl, fixture, glpipe, vrender, exitnode, pathmanager, track, paramprovider, mask, main, conmanager, clip, meta, fixedlocation, relativelocation, mobject, source, frame, placement, sessionimpl, builderfacade, controllerfacade, processor, pluginadapter

          +

          executable associated with : mobject, source, frame, placement, sessionimpl, builderfacade, controllerfacade, processor, pluginadapter, effect, buildertool, segmentationtool, aframe, assembler, trafo, explicitplacement, auto, glrender, link, parameter, renderengine, allocation, vframe, toolfactory, arender, renderstate, label, glbuf, procnode, stateproxy, hub, buildable, abstractmo, nodecreatertool, projector, interpolator, edl, fixture, glpipe, vrender, exitnode, pathmanager, track, paramprovider, mask, main, conmanager, clip, meta, fixedlocation, relativelocation

          Artifact main

          Artifact source

          @@ -521,7 +521,7 @@ Documentation
          Artifact hub

          special ProcNode used to build data distributing connections

          -

          Artifact source associated with : Hub

          +

          Artifact source

          Artifact projector

          video ProcNode for scaling and translating image data

          @@ -541,19 +541,19 @@ Documentation
          Artifact glpipe

          specialized connection element for handling OpenGL implementation details

          -

          Artifact source associated with : GLPipe

          +

          Artifact source

          Artifact arender

          Representation of a Audio Render process

          -

          Artifact source associated with : ARender

          +

          Artifact source

          Artifact vrender

          Representation of a Video render process

          -

          Artifact source associated with : VRender

          +

          Artifact source

          Artifact glrender

          Representation of a OpenGL accellerated Video render process

          -

          Artifact source associated with : GLRender

          +

          Artifact source

          Artifact aframe

          a buffer and render process holding a Audio frame

          @@ -880,21 +880,19 @@ reuse exiting Engine

          Selection :

            Transformation

            Render Mechanics



            + +

            +

            StateAdapter composition



            Class Processor
            Class ExitNode
            Class ProcNode
            Class Trafo
            Class Link
            -
            Class Hub
            Class Projector
            Class Mask
            -
            Class GLPipe
            -
            Class ARender
            -
            Class VRender
            -
            Class GLRender
            Class Frame
            Class AFrame
            Class VFrame
            @@ -902,7 +900,14 @@ reuse exiting Engine

            Selection :

              Transformation
              Class Source
              -
              +
              +
              +
              +
              Class Caching
              +
              Class Process
              +
              Class InPlace
              +
              +

              @@ -1016,13 +1021,7 @@ reuse exiting Engine

              Selection :

                Transformation

              • datasrc = input
              • Class instance vid_a

                type :Source

                -
                Class instance aud_a

                type :Source

                -
                Class instance vid1

                type :VRender

                relations :

                -
                Class instance au1

                type :ARender

                relations :

                +
                Class instance aud_a

                type :Source

                Class instance

                type :VFrame

                Class instance

                type :AFrame

                Class instance

                type :RenderEngine

                relations :

                  @@ -1046,9 +1045,6 @@ reuse exiting Engine

                Selection :

                  Transformation

                  Class instance HUE

                  type :PluginAdapter

                  relations :

                  -
                  Class instance vid1

                  type :VRender

                  relations :

                  Class instance

                  type :VFrame

                  Class instance video1

                  type :Processor

                  attributes :

                    @@ -1090,7 +1086,9 @@ reuse exiting Engine

                  Selection :

                    Transformation
                    Class Caller
                    Class instance node3

                    type :ProcNode

                    -
                    Class instance ad3

                    type :StateAdapter

                    +
                    Class instance ad3

                    type :StateAdapter

                    +
                    Class instance vid1

                    type :StateProxy

                    +
                    Class instance au1

                    type :StateProxy

                    3 Package BackendLayer

                    diff --git a/doc/devel/uml/index_60.html b/doc/devel/uml/index_60.html index cc286ecf2..8712d7074 100644 --- a/doc/devel/uml/index_60.html +++ b/doc/devel/uml/index_60.html @@ -28,10 +28,10 @@ <flow>transition <flow>transition <flow>transition -<flow>transition <flow>transition -<flow>transition +<flow>transition <flow>transition +<flow>transition <flow>transition <flow>transition <flow>transition diff --git a/doc/devel/uml/index_65.html b/doc/devel/uml/index_65.html index 8bc6b2fca..ab57596c5 100644 --- a/doc/devel/uml/index_65.html +++ b/doc/devel/uml/index_65.html @@ -40,7 +40,6 @@ applyoperation applyoperation Architecturecomponent viewThe various Components comprising the Lumiera Video editing Application -ARenderclassRepresentation of a Audio render process arenderartifactRepresentation of a Audio Render process AssemblerclassThis is the actual building facility: provided the correct tools and associations, it serves to build and connect the individual ProcNode objects assemblerartifactbuilding facility (implementation of the build process) @@ -55,7 +54,7 @@ assetmanagerartifactFacade for the Asset subsystem Assetsclass view ATTACHattributeattach subject to anchor (e.g. an effect to a clip) -au1class instance +au1class instance aud_aclass instance aud_Aclass instance audioclass instance diff --git a/doc/devel/uml/index_66.html b/doc/devel/uml/index_66.html index f37527c49..db64b33db 100644 --- a/doc/devel/uml/index_66.html +++ b/doc/devel/uml/index_66.html @@ -23,6 +23,7 @@ backend-componentscomponent diagram BackendCacheclass BackendLayerpackage +BuffHandleclass buildoperation build flowactivity diagram build necessary?decision activity node diff --git a/doc/devel/uml/index_67.html b/doc/devel/uml/index_67.html index 2b841a011..1612ca9ea 100644 --- a/doc/devel/uml/index_67.html +++ b/doc/devel/uml/index_67.html @@ -19,43 +19,44 @@ NameKindDescription Cachecomponent Cachecomponent view +Cachingclass Callerclass categoryrelationprimary tree like classification of the asset Categoryclasstree like classification of Assets categoryartifacttree like classification of Assets causeattributea copy of the first exception encountered in this exception chain -chainrelationChain of additional Placements further constraining the position of this MObject chainoperationcreate and add another Placement for this media object, thus increasingly constraining the (possible) position of this object. +chainrelationChain of additional Placements further constraining the position of this MObject checked_inrelationchecked_in objects are subject of cache aging and must be not in use checked_outrelationthis list keeps all mappings which are in use, and thus prevents them from Cache aging -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance -class instanceclass instance class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance class instanceclass instance class instanceclass instance -class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance +class instanceclass instance clearoperationclear current session contents
                    without resetting overall session config.
                    Afterwards, the session will contain only one
                    empty EDL, while all Assets are retained.
                    client codecomponent Clipclassbookkeeping (asset) view of a media clip. @@ -95,8 +96,8 @@ constraintartifactLocatingPin representing an directive by the user that
                    must not be violated Constraintclass Controllercomponent -controllerpackagesourcecode package

                    The Processing and Render Controller,
                    located within the MObject Subsystem Controllerpackage +controllerpackagesourcecode package

                    The Processing and Render Controller,
                    located within the MObject Subsystem Controller Entitiesclass diagram Controller Workingsclass view ControllerFacadeclassProvides unified access to the Proc-Subsystem Controller. Especially, this Facade class provides the functions to get a render engine to carry out actual renderings. diff --git a/doc/devel/uml/index_69.html b/doc/devel/uml/index_69.html index 6c17d406d..1f6fd3f19 100644 --- a/doc/devel/uml/index_69.html +++ b/doc/devel/uml/index_69.html @@ -24,8 +24,8 @@ EDL Example2object diagramMore complex example showing the Object graph in the EDL and how it is linked into the Fixture to yield the actual locations. In this example, an HUE Effect is applied on a part of the Clip edlsrelation EffectclassEffect or media processing component -effectartifactEDL representation of a pluggable and automatable effect. effectartifactEffect or media processing component +effectartifactEDL representation of a pluggable and automatable effect. Effectclass elementsrelationrelevant MObjects comprising this segment. TODO: actually necessary?? enableoperationchange the enabled status of this asset. Note the corresponding #isActive predicate may depend on the enablement status of parent assets as well diff --git a/doc/devel/uml/index_70.html b/doc/devel/uml/index_70.html index 3d833b61f..5e1189dd5 100644 --- a/doc/devel/uml/index_70.html +++ b/doc/devel/uml/index_70.html @@ -35,8 +35,8 @@ FixedLocationclass Fixtureactivity object fixtureartifactthe (low level) representation of the EDL with concrete placement data -Fixtureclass Fixturecomponent +Fixtureclass fork activity nodefork activity node FrameclassFrames are just a low level lump of continous memory, most parts are opaque. Frames are memory sensitive, they will be small constant sized structures which can be efficently managed in a pool. Framenode diff --git a/doc/devel/uml/index_71.html b/doc/devel/uml/index_71.html index 82430e314..f4ad7d96d 100644 --- a/doc/devel/uml/index_71.html +++ b/doc/devel/uml/index_71.html @@ -46,9 +46,7 @@ getValueoperation GLBufclass glbufartifacta buffer and render process holding a Video frame for OpenGL rendering -GLPipeclassspecialized connection node used to handle the transfer of OpenGL data from a image bitmap into texture form glpipeartifactspecialized connection element for handling OpenGL implementation details -GLRenderclassRepresentation of a OpenGL accelerated Video render process glrenderartifactRepresentation of a OpenGL accellerated Video render process groupsattributeadditional classification, selections or departments this asset belongs to. Groups are optional, non-exclusive and may be overlapping. guipackagesourcecode package

                    User Interface classes go here diff --git a/doc/devel/uml/index_72.html b/doc/devel/uml/index_72.html index 0abaaac68..3547e6f3e 100644 --- a/doc/devel/uml/index_72.html +++ b/doc/devel/uml/index_72.html @@ -22,7 +22,6 @@ handles_availableattributeinitialized to the maximum number of filehandles the backend may use for mapped files. When no handles are available, the handle which is last in the handles list is closed and (re-)used.
                    Else this number is decremented for each new filehandle used and incremented for any one explicitly freed. Hierarchyclass diagramLumiera Exception hierarchy howtoProcoperation@return descriptor how to build a render pipeline corresponding to this media -Hubclass hubartifactspecial ProcNode used to build data distributing connections HUEclass instance HUEclass instance diff --git a/doc/devel/uml/index_73.html b/doc/devel/uml/index_73.html index 12fe67359..9a0a77429 100644 --- a/doc/devel/uml/index_73.html +++ b/doc/devel/uml/index_73.html @@ -20,10 +20,10 @@ idattributeAsset primary key. In Memory Databaseclass diagram inFixtureactivity action pin +InPlaceclass inputclass instance -inputclass instance inputclass instance -InputDescriptorclass +inputclass instance instanceoperation instructionsrelation Interfaceclass view @@ -32,6 +32,7 @@ interpolatorartifactdenotes a facility to get (continuously interpolated) parameter values InterpolatorclassProvides the implementation for getting the acutal value of a time varying or automated effect/plugin parameter Invalidclass +InvocationStateBaseclass iporelation isActiveoperationweather this asset is swithced on and consequently included in the fixture and participates in rendering isCalculatedoperation diff --git a/doc/devel/uml/index_78.html b/doc/devel/uml/index_78.html index d0f7bd42e..74fa8a9d8 100644 --- a/doc/devel/uml/index_78.html +++ b/doc/devel/uml/index_78.html @@ -26,6 +26,7 @@ nodecreatertoolartifactcentral Tool implementing the Renderengine building NodeCreatorToolclassThis Tool implementation plays the central role in the buld process: given a MObject from Session, it is able to attach ProcNodes to the render engine under construction such as to reflect the properties of the MObject in the actual render. nodesrelation +NodeWiringclass diff --git a/doc/devel/uml/index_79.html b/doc/devel/uml/index_79.html index bfec5f683..d1fdc83c0 100644 --- a/doc/devel/uml/index_79.html +++ b/doc/devel/uml/index_79.html @@ -19,9 +19,9 @@ NameKindDescription offsetattributeOffset the actual position by this (time) value relative to the anchor point. TODO: Representation? orgattributeorigin or authorship id. Can be a project abbreviation, a package id or just the authors nickname or UID. This allows for the compnent name to be more generic (e.g. "blur"). Default for all assets provided by the core Lumiera codebase is "lumi". -ouputclass instance ouputclass instance ouputclass instance +ouputclass instance outPortrelationthe Port this MObject wants to be conected to outputrelation Overviewcomponent diagramThis drawing shows the top level compoents and relations diff --git a/doc/devel/uml/index_80.html b/doc/devel/uml/index_80.html index 0cff29b1c..a3268b59b 100644 --- a/doc/devel/uml/index_80.html +++ b/doc/devel/uml/index_80.html @@ -53,6 +53,7 @@ Proc-Asset Relationsclass diagram proc-componentscomponent diagram ProcDispatcherclass +Processclass processoperation ProcessingLayerpackage Processorclass diff --git a/doc/devel/uml/index_82.html b/doc/devel/uml/index_82.html index 7f2b69c16..b5b305e10 100644 --- a/doc/devel/uml/index_82.html +++ b/doc/devel/uml/index_82.html @@ -23,8 +23,8 @@ relativelocationartifactPlacement implemnetaion providing various ways of attaching a MObject to another one RelativeLocationclass releaseBufferoperation -RelTypeclassthe possible kinds of RelativePlacements relTypeattributethe kind of relation denoted by this Placement +RelTypeclassthe possible kinds of RelativePlacements removeoperationremove the given asset <i>together with all its dependants</i> from the internal DB Render Entitiesclass diagram Render Mechanicsclass diagram diff --git a/doc/devel/uml/index_83.html b/doc/devel/uml/index_83.html index c7b3fed84..5dd747140 100644 --- a/doc/devel/uml/index_83.html +++ b/doc/devel/uml/index_83.html @@ -60,6 +60,7 @@ Stateclass staterelation StateAdapterclass +StateAdapter compositionclass diagram StateProxyclass stateproxyartifactKey Interface representing a render process and encapsulating state std::exceptionclass diff --git a/doc/devel/uml/index_84.html b/doc/devel/uml/index_84.html index 78e737858..b0541e88b 100644 --- a/doc/devel/uml/index_84.html +++ b/doc/devel/uml/index_84.html @@ -34,21 +34,21 @@ trackrelation trackattribute trackrelation -trackartifactstructural asset holding the configuration of a track in the EDL trackartifactA grouping device within the EDL. The corresponding Placement
                    by which this Track object is refered defines fallback placing
                    properties to be used by all objects placed on this track in
                    case they don't specify more concrete placements.
                    Typically, tracks are used do make default Port connections,
                    define a layer or pan for sound and for for disabling groups
                    of clips. Note tracks are grouped in a tree like fashion.
                    +trackartifactstructural asset holding the configuration of a track in the EDL Trackclass tracksrelationelementary media assets comprising this compound Trafoclass trafoartifacttransforming processing Node treatoperation treatoperationThis operation is to be overloaded for the specific MObject subclasses to be treated. -treatoperation -treatoperation treatoperation treatoperation +treatoperation +treatoperation +treatoperation treatoperation treatoperation -treatoperation TypeHandlerclass TypeHandler<Pipe>class diff --git a/doc/devel/uml/index_86.html b/doc/devel/uml/index_86.html index c2ce0bff8..cda6a585e 100644 --- a/doc/devel/uml/index_86.html +++ b/doc/devel/uml/index_86.html @@ -20,27 +20,25 @@ versionattributeversion number of the thing or concept represented by this asset. Of each unique tuple (name, category, org) there will be only one version in the whole system. Version 0 is reserved for internal purposes. Versions are considered to be ordered, and any higher version is supposed to be fully backwards compatible to all previous versions. VFrameclass vframeartifacta buffer and render process holding a Video frame -vid1class instance -vid1class instance -vid_Aclass instance -vid_aclass instance +vid1class instance vid_Aclass instance -vid_Aclass instance vid_aclass instance -videoclass instance -videoclass instance +vid_Aclass instance +vid_Aclass instance +vid_aclass instance videoclass instance videoclass instance -video1class instance +videoclass instance +videoclass instance video1class instance +video1class instance video1class instance +video1class instance video1class instance video1class instance -video1class instance Visitableclass visitorpackagesub-namespace for visitor library implementation visitorartifactAcyclic Visitor library -VRenderclassRepresentation of a Video render process. (Encapsulates the video buffers for the actual calculations) vrenderartifactRepresentation of a Video render process diff --git a/doc/devel/uml/index_87.html b/doc/devel/uml/index_87.html index bd2bf3399..7e2b7e31f 100644 --- a/doc/devel/uml/index_87.html +++ b/doc/devel/uml/index_87.html @@ -20,6 +20,9 @@ whatoperation whatoperationthe base class of all exceptions thrown by the standard library when to queryuse case diagram +wiringrelation +WiringDescriptorclass +WiringTableclass wiringTemplaterelation wishartifactLocatingPin representing a low-priority directive by the user,
                    to be fulfilled only if possible (and after satisfying the
                    more important LocatingPins) Wishclass diff --git a/uml/lumiera/128389 b/uml/lumiera/128389 index 20d07a18b..2a8c1a7c0 100644 --- a/uml/lumiera/128389 +++ b/uml/lumiera/128389 @@ -1,6 +1,6 @@ format 40 "RenderEngine" // ProcessingLayer::RenderEngine - revision 15 + revision 16 modified_by 5 "hiv" // class settings //class diagram settings @@ -87,6 +87,11 @@ format 40 size A4 end + classdiagram 132357 "StateAdapter composition" + draw_all_relations no hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + size A4 + end + class 131333 "RenderEngine" visibility package cpp_decl "${comment}${template}class ${name}${inherit} @@ -241,12 +246,12 @@ ${members}}; classrelation 152581 // predecessors () relation 149125 *--> - stereotype "vector" + stereotype "array" a role_name "predecessors" multiplicity "*" protected cpp default " ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value}; " classrelation_ref 152581 // predecessors () - b multiplicity "" parent class_ref 142725 // InputDescriptor + b multiplicity "" parent class_ref 142725 // WiringDescriptor end operation 135685 "pull" @@ -320,26 +325,6 @@ ${inlines} end end - class 132101 "Hub" - visibility package - cpp_decl "${comment}${template}class ${name}${inherit} - { -${members} }; -${inlines} -" - java_decl "" - idl_decl "" - explicit_switch_type "" - - classrelation 133125 // - relation 132357 ---|> - a public - cpp default "${type}" - classrelation_ref 133125 // - b multiplicity "" parent class_ref 131717 // ProcNode - end - end - class 132229 "Projector" visibility package cpp_decl "${comment}${template}class ${name}${inherit} @@ -422,90 +407,6 @@ ${inlines} end end - class 132613 "GLPipe" - visibility package - cpp_decl "${comment}${template}class ${name}${inherit} - { -${members} }; -${inlines} -" - java_decl "" - idl_decl "" - explicit_switch_type "" - - comment "specialized connection node used to handle the transfer of OpenGL data from a image bitmap into texture form" - classrelation 133381 // - relation 132613 ---|> - a public - cpp default "${type}" - classrelation_ref 133381 // - b multiplicity "" parent class_ref 131973 // Link - end - end - - class 132869 "ARender" - visibility package - cpp_decl "${comment}${template}class ${name}${inherit} - { -${members} }; -${inlines} -" - java_decl "" - idl_decl "" - explicit_switch_type "" - - comment "Representation of a Audio render process" - classrelation 134661 // - relation 133509 ---|> - a public - cpp default "${type}" - classrelation_ref 134661 // - b multiplicity "" parent class_ref 132741 // State - end - end - - class 132997 "VRender" - visibility package - cpp_decl "${comment}${template}class ${name}${inherit} - { -${members} }; -${inlines} -" - java_decl "" - idl_decl "" - explicit_switch_type "" - - comment "Representation of a Video render process. (Encapsulates the video buffers for the actual calculations)" - classrelation 134789 // - relation 133637 ---|> - a public - cpp default "${type}" - classrelation_ref 134789 // - b multiplicity "" parent class_ref 132741 // State - end - end - - class 133125 "GLRender" - visibility package - cpp_decl "${comment}${template}class ${name}${inherit} - { -${members} }; -${inlines} -" - java_decl "" - idl_decl "" - explicit_switch_type "" - - comment "Representation of a OpenGL accelerated Video render process" - classrelation 134917 // - relation 133765 ---|> - a public - cpp default "${type}" - classrelation_ref 134917 // - b multiplicity "" parent class_ref 132741 // State - end - end - class 133253 "Frame" abstract visibility public stereotype "interface" cpp_decl "${comment}${template}class ${name}${inherit} @@ -616,6 +517,11 @@ ${inlines} class 142469 "StateProxy" visibility package stereotype "implementation" + nformals 2 + formal name "WIRING" type "class" explicit_default_value "" + explicit_extends "" + formal name "POLICY" type "class" explicit_default_value "" + explicit_extends "" cpp_decl "${comment}${template}class ${name}${inherit} { ${members} }; @@ -632,6 +538,23 @@ ${inlines} classrelation_ref 152453 // b multiplicity "" parent class_ref 132741 // State end + + classrelation 153221 // + relation 149765 ---|> + a public + cpp default "${type}" + classrelation_ref 153221 // + b multiplicity "" parent class_ref 143877 // InPlace + end + + classrelation 154117 // wiring () + relation 150661 ---> + a role_name "wiring" multiplicity "1" const_relation protected + cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; +" + classrelation_ref 154117 // wiring () + b multiplicity "" parent class_ref 144005 // WiringTable + end end class 142597 "StateAdapter" @@ -687,7 +610,165 @@ ${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl} end end - class 142725 "InputDescriptor" + class 142725 "WiringDescriptor" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + end + + class 143365 "NodeWiring" + visibility package + nformals 1 + formal name "STATE" type "class" explicit_default_value "" + explicit_extends "" + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + classrelation 152965 // + relation 149509 ---|> + a public + cpp default "${type}" + classrelation_ref 152965 // + b multiplicity "" parent class_ref 142725 // WiringDescriptor + end + + classrelation 153093 // + relation 149637 -_-> + a default + cpp default "Generated" + classrelation_ref 153093 // + b multiplicity "" parent class_ref 142597 // StateAdapter + end + end + + class 143493 "InvocationStateBase" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + classrelation 153733 // + relation 150277 ---|> + a public + cpp default "${type}" + classrelation_ref 153733 // + b multiplicity "" parent class_ref 132741 // State + end + end + + class 143621 "Caching" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + classrelation 153605 // + relation 150149 ---|> + a public + cpp default "${type}" + classrelation_ref 153605 // + b multiplicity "" parent class_ref 143493 // InvocationStateBase + end + end + + class 143749 "Process" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + classrelation 153477 // + relation 150021 ---|> + a public + cpp default "${type}" + classrelation_ref 153477 // + b multiplicity "" parent class_ref 143621 // Caching + end + end + + class 143877 "InPlace" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + classrelation 153349 // + relation 149893 ---|> + a public + cpp default "${type}" + classrelation_ref 153349 // + b multiplicity "" parent class_ref 143749 // Process + end + end + + class 144005 "WiringTable" + visibility package + nformals 1 + formal name "SIZ" type "int" explicit_default_value "" + explicit_extends "" + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + classrelation 153861 // + relation 150405 *--> + stereotype "array" + a role_name "" multiplicity "SIZ" protected + cpp default " ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value}; +" + classrelation_ref 153861 // + b multiplicity "" parent class_ref 144133 // BuffHandle + end + + classrelation 153989 // + relation 150533 ---> + a role_name "" multiplicity "" protected + cpp default " ${comment}${static}${mutable}${volatile}${const}${type}* ${name}${value}; +" + classrelation_ref 153989 // + b multiplicity "" parent class_ref 142725 // WiringDescriptor + end + end + + class 144133 "BuffHandle" visibility package cpp_decl "${comment}${template}class ${name}${inherit} { diff --git a/uml/lumiera/128389.diagram b/uml/lumiera/128389.diagram index 741cf9ff5..da7bca1cb 100644 --- a/uml/lumiera/128389.diagram +++ b/uml/lumiera/128389.diagram @@ -24,10 +24,6 @@ classcanvas 129157 class_ref 131973 // Link draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default xyz 648 444 2000 end -classcanvas 129285 class_ref 132101 // Hub - draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 593 444 2000 - end classcanvas 129413 class_ref 132229 // Projector draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default xyz 417 561 2000 @@ -40,26 +36,10 @@ classcanvas 129669 class_ref 132485 // PluginAdapter draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default xyz 506 621 2000 end -classcanvas 129797 class_ref 132613 // GLPipe - draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 699 531 2000 - end classcanvas 132229 class_ref 132741 // State draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default xyz 36 374 2000 end -classcanvas 132997 class_ref 132869 // ARender - draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 31 511 2000 - end -classcanvas 133125 class_ref 132997 // VRender - draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 110 511 2000 - end -classcanvas 133253 class_ref 133125 // GLRender - draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 175 511 2000 - end classcanvas 133765 class_ref 133253 // Frame draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default xyz 269 612 2000 @@ -97,36 +77,25 @@ relationcanvas 128901 relation_ref 131973 // multiplicity_a_pos 414 419 3000 no_multiplicity_b relationcanvas 129925 relation_ref 132101 // geometry VHV - from ref 128389 z 1999 to point 445 387 - line 130693 z 1999 to point 499 387 + from ref 128389 z 1999 to point 445 397 + line 130693 z 1999 to point 499 397 line 130821 z 1999 to ref 128517 no_role_a no_role_b no_multiplicity_a no_multiplicity_b relationcanvas 130053 relation_ref 132229 // geometry VHV - from ref 129029 z 1999 to point 516 387 - line 130949 z 1999 to point 499 387 + from ref 129029 z 1999 to point 516 397 + line 130949 z 1999 to point 499 397 line 131077 z 1999 to ref 128517 no_role_a no_role_b no_multiplicity_a no_multiplicity_b -relationcanvas 130181 relation_ref 132357 // - geometry VHV - from ref 129285 z 1999 to point 613 387 - line 131205 z 1999 to point 499 387 - line 131333 z 1999 to ref 128517 - no_role_a no_role_b - no_multiplicity_a no_multiplicity_b relationcanvas 130309 relation_ref 132485 // geometry VHV - from ref 129157 z 1999 to point 668 387 - line 131461 z 1999 to point 499 387 + from ref 129157 z 1999 to point 668 397 + line 131461 z 1999 to point 499 397 line 131589 z 1999 to ref 128517 no_role_a no_role_b no_multiplicity_a no_multiplicity_b -relationcanvas 131717 relation_ref 132613 // - from ref 129797 z 1999 to ref 129157 - no_role_a no_role_b - no_multiplicity_a no_multiplicity_b relationcanvas 131845 relation_ref 132741 // from ref 129413 z 1999 to ref 129029 no_role_a no_role_b @@ -139,27 +108,6 @@ relationcanvas 132101 relation_ref 132997 // from ref 129669 z 1999 to ref 129029 no_role_a no_role_b no_multiplicity_a no_multiplicity_b -relationcanvas 133381 relation_ref 133509 // - geometry VHV - from ref 132997 z 1999 to point 58 472 - line 134277 z 1999 to point 73 472 - line 134405 z 1999 to ref 132229 - no_role_a no_role_b - no_multiplicity_a no_multiplicity_b -relationcanvas 133509 relation_ref 133637 // - geometry VHV - from ref 133125 z 1999 to point 136 472 - line 134533 z 1999 to point 73 472 - line 134661 z 1999 to ref 132229 - no_role_a no_role_b - no_multiplicity_a no_multiplicity_b -relationcanvas 133637 relation_ref 133765 // - geometry VHV - from ref 133253 z 1999 to point 206 472 - line 134789 z 1999 to point 73 472 - line 134917 z 1999 to ref 132229 - no_role_a no_role_b - no_multiplicity_a no_multiplicity_b relationcanvas 135045 relation_ref 133893 // geometry VHV from ref 133893 z 1999 to point 252 704 @@ -182,11 +130,11 @@ relationcanvas 136965 relation_ref 134533 // from ref 132229 z 1999 stereotype "<>" xyz 279 441 3000 to point 306 465 line 137093 z 1999 to ref 133765 role_a_pos 318 587 3000 no_role_b - multiplicity_a_pos 282 587 3000 multiplicity_b_pos 124 427 3000 + no_multiplicity_a multiplicity_b_pos 124 427 3000 relationcanvas 137349 relation_ref 134661 // geometry VHV - from ref 137221 z 1999 to point 763 387 - line 137477 z 1999 to point 499 387 + from ref 137221 z 1999 to point 763 397 + line 137477 z 1999 to point 499 397 line 137605 z 1999 to ref 128517 no_role_a no_role_b no_multiplicity_a no_multiplicity_b @@ -203,8 +151,8 @@ relationcanvas 139397 relation_ref 135429 // from ref 128517 z 1999 to point 432 264 line 139525 z 1999 to point 432 294 line 139653 z 1999 to ref 128517 - role_a_pos 414 272 3000 no_role_b - no_multiplicity_a multiplicity_b_pos 445 291 3000 + role_a_pos 414 276 3000 no_role_b + no_multiplicity_a multiplicity_b_pos 445 296 3000 relationcanvas 139909 relation_ref 136965 // from ref 139781 z 1999 to ref 129029 no_role_a no_role_b diff --git a/uml/lumiera/129029.diagram b/uml/lumiera/129029.diagram index 9892c6c73..7ca7da511 100644 --- a/uml/lumiera/129029.diagram +++ b/uml/lumiera/129029.diagram @@ -33,12 +33,6 @@ classinstancecanvas 129797 classinstance_ref 131717 // vid_a classinstancecanvas 129925 classinstance_ref 131845 // aud_a xyz 444 398 2000 end -classinstancecanvas 131717 classinstance_ref 131973 // vid1 - xyz 188 427 2000 - end -classinstancecanvas 131845 classinstance_ref 132101 // au1 - xyz 554 289 2000 - end classinstancecanvas 131973 classinstance_ref 132229 // xyz 117 492 2000 end @@ -49,9 +43,15 @@ note 133125 "render state proxy passed on" xyzwh 123 355 2000 104 53 textcanvas 133253 "Video and Audio Clip of length = 5 frames positioned at frame 2, producing two output streams (frame sequence)." xyzwh 445 507 2000 175 83 +classinstancecanvas 133381 classinstance_ref 137093 // vid1 + xyz 172 431 2000 + end +classinstancecanvas 133893 classinstance_ref 137221 // au1 + xyz 556 289 2000 + end objectlinkcanvas 128389 rel relation_ref 131845 // geometry VH - from ref 128005 z 1999 to point 117 205 + from ref 128005 z 1999 stereotype "<>" xyz 101 154 3000 to point 117 205 line 81 z 1999 to ref 128261 role_a_pos 188 183 3000 no_role_b objectlinkcanvas 128901 rel relation_ref 131973 // @@ -75,20 +75,18 @@ objectlinkcanvas 131461 rel relation_ref 135429 // objectlinkcanvas 131589 rel relation_ref 135429 // from ref 128773 z 1999 to ref 129925 role_a_pos 494 373 3000 no_role_b -objectlinkcanvas 132229 rel relation_ref 134533 // +objectlinkcanvas 133509 norel geometry VHr - from ref 131717 z 1999 to point 140 438 - line 1 z 1999 to ref 131973 - role_a_pos 152 467 3000 no_role_b -objectlinkcanvas 132485 rel relation_ref 134533 // + from ref 133381 z 1999 to point 140 442 + line 133637 z 1999 to ref 131973 + no_role_a no_role_b +objectlinkcanvas 134021 norel geometry HV - from ref 131845 z 1999 to point 676 300 - line 1 z 1999 to ref 132101 - role_a_pos 688 328 3000 no_role_b -line 132613 -_-_ - from ref 128261 z 1999 to point 244 320 - line 132741 z 1999 to ref 131717 -line 132869 -_-_ - from ref 128133 z 1999 to point 583 259 - line 132997 z 1999 to ref 131845 + from ref 133893 z 1999 to point 676 300 + line 134149 z 1999 to ref 132101 + no_role_a no_role_b +line 133765 -_-_ + from ref 128261 z 1999 to ref 133381 +line 134277 -_-_ + from ref 128133 z 1999 to ref 133893 end diff --git a/uml/lumiera/129157.diagram b/uml/lumiera/129157.diagram index f63b08370..81552e7a1 100644 --- a/uml/lumiera/129157.diagram +++ b/uml/lumiera/129157.diagram @@ -26,11 +26,8 @@ end classinstancecanvas 129157 classinstance_ref 133253 // HUE xyz 477 444 2000 end -classinstancecanvas 129541 classinstance_ref 133381 // vid1 - xyz 409 293 2000 - end classinstancecanvas 129669 classinstance_ref 133509 // - xyz 138 498 2000 + xyz 151 399 2000 end classinstancecanvas 129797 classinstance_ref 133637 // video1 xyz 478 172 2000 @@ -60,6 +57,9 @@ note 134661 "Note: because the Engine Components are stateless, various calculat xyzwh 569 45 2000 240 75 textcanvas 134789 "Video Clip from 2 to 7, with an attached HUE effect starting 3 frames after begin and overlapping by 1 frame beyond the end" xyzwh 145 553 2000 175 87 +classinstancecanvas 134917 classinstance_ref 137093 // vid1 + xyz 410 291 3005 + end objectlinkcanvas 130053 rel relation_ref 135429 // from ref 129925 z 1999 to ref 128901 role_a_pos 537 361 3000 no_role_b @@ -67,46 +67,46 @@ objectlinkcanvas 130437 rel relation_ref 135429 // from ref 129157 z 1999 to ref 128645 role_a_pos 539 472 3000 no_role_b objectlinkcanvas 130565 rel relation_ref 131973 // - from ref 128773 z 1999 stereotype "<>" xyz 624 285 3000 to ref 128517 + from ref 128773 z 1999 stereotype "<>" xyz 656 263 3000 to ref 128517 role_a_pos 661 304 3000 no_role_b -objectlinkcanvas 130693 rel relation_ref 134533 // - geometry VHr - from ref 129541 z 1999 to point 161 304 - line 130821 z 1999 to ref 129669 - role_a_pos 173 473 3000 no_role_b -objectlinkcanvas 130949 rel relation_ref 135429 // - from ref 128901 z 1999 to ref 129157 - role_a_pos 538 419 3000 no_role_b -objectlinkcanvas 131589 rel relation_ref 131973 // - from ref 129797 z 1999 stereotype "<>" xyz 499 284 3000 to ref 129925 - role_a_pos 537 304 3000 no_role_b -objectlinkcanvas 132613 rel relation_ref 135429 // - from ref 128517 z 1999 to ref 132229 - role_a_pos 662 419 3000 no_role_b -objectlinkcanvas 132869 rel relation_ref 135429 // - from ref 132229 z 1999 to ref 128389 - role_a_pos 662 533 3000 no_role_b -objectlinkcanvas 133637 rel relation_ref 135429 // - from ref 133509 z 1999 to ref 133381 - role_a_pos 348 361 3000 no_role_b -objectlinkcanvas 133765 rel relation_ref 135429 // - from ref 133125 z 1999 to ref 132997 - role_a_pos 416 577 3000 no_role_b -objectlinkcanvas 133893 rel relation_ref 131973 // - from ref 133253 z 1999 stereotype "<>" xyz 291 273 3000 to ref 133509 - role_a_pos 348 304 3000 no_role_b -objectlinkcanvas 134277 rel relation_ref 135429 // - from ref 133381 z 1999 to ref 133125 - role_a_pos 349 473 3000 no_role_b -objectlinkcanvas 134405 rel relation_ref 135429 // +objectlinkcanvas 135045 rel relation_ref 135429 // from ref 128645 z 1999 to ref 132997 role_a_pos 446 567 3000 no_role_b -objectlinkcanvas 134533 rel relation_ref 131845 // +objectlinkcanvas 135173 rel relation_ref 131845 // geometry VH - from ref 128005 z 1999 to point 123 205 - line 6 z 1999 to ref 133253 - role_a_pos 197 183 3000 no_role_b -line 131973 -_-_ - from ref 129797 z 1999 to point 445 243 - line 132101 z 1999 to ref 129541 + from ref 128005 z 1999 stereotype "<>" xyz 127 141 3000 to point 123 205 + line 136965 z 1999 to ref 133253 + role_a_pos 152 186 3000 no_role_b +objectlinkcanvas 135301 rel relation_ref 135429 // + from ref 128901 z 1999 to ref 129157 + role_a_pos 538 419 3000 no_role_b +objectlinkcanvas 135429 rel relation_ref 131973 // + from ref 133253 z 1999 stereotype "<>" xyz 282 261 3000 to ref 133509 + role_a_pos 348 304 3000 no_role_b +objectlinkcanvas 135557 rel relation_ref 135429 // + from ref 128517 z 1999 to ref 132229 + role_a_pos 662 419 3000 no_role_b +objectlinkcanvas 135685 rel relation_ref 135429 // + from ref 133125 z 1999 to ref 132997 + role_a_pos 416 577 3000 no_role_b +objectlinkcanvas 135813 rel relation_ref 135429 // + from ref 132229 z 1999 to ref 128389 + role_a_pos 662 533 3000 no_role_b +objectlinkcanvas 135941 rel relation_ref 131973 // + from ref 129797 z 1999 stereotype "<>" xyz 529 262 3000 to ref 129925 + role_a_pos 537 304 3000 no_role_b +objectlinkcanvas 136069 rel relation_ref 135429 // + from ref 133509 z 1999 to ref 133381 + role_a_pos 348 361 3000 no_role_b +objectlinkcanvas 136197 rel relation_ref 135429 // + from ref 133381 z 1999 to ref 133125 + role_a_pos 349 473 3000 no_role_b +objectlinkcanvas 136325 norel + geometry VHr + from ref 134917 z 1999 to point 174 302 + line 136453 z 1999 to ref 129669 + no_role_a no_role_b +line 136581 -_-_ + from ref 129797 z 1999 to point 451 237 + line 136709 z 1999 to ref 134917 end diff --git a/uml/lumiera/129285 b/uml/lumiera/129285 index 72c222be4..246c9e4d6 100644 --- a/uml/lumiera/129285 +++ b/uml/lumiera/129285 @@ -1,6 +1,6 @@ format 40 "ProcessingLayer" // ProcessingLayer - revision 19 + revision 21 modified_by 5 "hiv" // class settings //class diagram settings @@ -391,26 +391,6 @@ format 40 end end - classinstance 131973 "vid1" - type class_ref 132997 // VRender - attributes - end - relations - relation_ref 134533 // - classinstance_ref 132229 // - end - end - - classinstance 132101 "au1" - type class_ref 132869 // ARender - attributes - end - relations - relation_ref 134533 // - classinstance_ref 132357 // - end - end - classinstance 132229 "" type class_ref 133509 // VFrame attributes @@ -499,16 +479,6 @@ format 40 end end - classinstance 133381 "vid1" - type class_ref 132997 // VRender - attributes - end - relations - relation_ref 134533 // - classinstance_ref 133509 // - end - end - classinstance 133509 "" type class_ref 133509 // VFrame attributes @@ -689,5 +659,21 @@ ${inlines} relations end end + + classinstance 137093 "vid1" + type class_ref 142469 // StateProxy + attributes + end + relations + end + end + + classinstance 137221 "au1" + type class_ref 142469 // StateProxy + attributes + end + relations + end + end end end diff --git a/uml/lumiera/130309 b/uml/lumiera/130309 index f5c27c9a0..e89c34727 100644 --- a/uml/lumiera/130309 +++ b/uml/lumiera/130309 @@ -1,6 +1,6 @@ format 40 "engine" // design::codegen::proc::engine - revision 8 + revision 9 modified_by 5 "hiv" // class settings //class diagram settings @@ -306,7 +306,6 @@ ${namespace_start} ${members} ${namespace_end}" associated_classes - class_ref 132101 // Hub end comment "special ProcNode used to build data distributing connections" end @@ -501,7 +500,6 @@ ${namespace_start} ${members} ${namespace_end}" associated_classes - class_ref 132613 // GLPipe end comment "specialized connection element for handling OpenGL implementation details" end @@ -540,7 +538,6 @@ ${namespace_start} ${members} ${namespace_end}" associated_classes - class_ref 132869 // ARender end comment "Representation of a Audio Render process" end @@ -579,7 +576,6 @@ ${namespace_start} ${members} ${namespace_end}" associated_classes - class_ref 132997 // VRender end comment "Representation of a Video render process" end @@ -618,7 +614,6 @@ ${namespace_start} ${members} ${namespace_end}" associated_classes - class_ref 133125 // GLRender end comment "Representation of a OpenGL accellerated Video render process" end diff --git a/uml/lumiera/131973.diagram b/uml/lumiera/131973.diagram index 42c38a979..4b7003a43 100644 --- a/uml/lumiera/131973.diagram +++ b/uml/lumiera/131973.diagram @@ -14,16 +14,22 @@ classcanvas 129669 class_ref 133253 // Frame end classcanvas 131845 class_ref 142469 // StateProxy draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 146 227 2000 + xyz 126 211 2000 end classcanvas 131973 class_ref 142597 // StateAdapter draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default xyz 40 317 3010 end -classcanvas 132357 class_ref 142725 // InputDescriptor +classcanvas 132357 class_ref 142725 // WiringDescriptor draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default - xyz 230 526 2000 + xyz 229 497 2000 end +classcanvas 135045 class_ref 143365 // NodeWiring + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 241 568 2000 + end +textcanvas 135685 "determines concrete Type" + xyzwh 100 594 2004 130 18 relationcanvas 129797 relation_ref 134533 // from ref 128517 z 1999 stereotype "<>" xyz 277 115 3000 to point 300 136 line 130053 z 1999 to ref 129669 @@ -31,33 +37,43 @@ relationcanvas 129797 relation_ref 134533 // no_multiplicity_a multiplicity_b_pos 173 109 3000 relationcanvas 132101 relation_ref 148869 // geometry VHV unfixed - from ref 131973 z 1999 to point 78 189 - line 134021 z 1999 to point 118 189 + from ref 131973 z 1999 to point 78 181 + line 134021 z 1999 to point 118 181 line 134149 z 1999 to ref 128517 no_role_a no_role_b no_multiplicity_a no_multiplicity_b relationcanvas 132229 relation_ref 148997 // geometry VHV - from ref 131845 z 1999 to point 198 189 - line 134277 z 1999 to point 118 189 + from ref 131845 z 1999 to point 178 181 + line 134277 z 1999 to point 118 181 line 134405 z 1999 to ref 128517 no_role_a no_role_b no_multiplicity_a no_multiplicity_b relationcanvas 132485 relation_ref 149125 // geometry HV - from ref 128005 z 1999 stereotype "<>" xyz 217 451 3000 to point 275 452 + from ref 128005 z 1999 stereotype "<>" xyz 205 454 3000 to point 277 452 line 133381 z 1999 to ref 132357 - role_a_pos 287 501 3000 no_role_b - multiplicity_a_pos 263 501 3000 no_multiplicity_b + role_a_pos 289 472 3000 no_role_b + multiplicity_a_pos 265 472 3000 no_multiplicity_b relationcanvas 133509 relation_ref 149253 // - from ref 131973 z 1999 to point 197 307 + from ref 131973 z 1999 to point 178 312 line 133637 z 1999 to ref 131845 - role_a_pos 177 314 3000 no_role_b - multiplicity_a_pos 182 291 3000 no_multiplicity_b + role_a_pos 190 302 3000 no_role_b + multiplicity_a_pos 164 302 3000 no_multiplicity_b relationcanvas 134533 relation_ref 149381 // from ref 131973 z 3004 to ref 129669 no_role_a no_role_b no_multiplicity_a no_multiplicity_b +relationcanvas 135173 relation_ref 149509 // + from ref 135045 z 1999 to ref 132357 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 135301 relation_ref 149637 // + geometry VHr + from ref 135045 z 1999 to point 78 596 + line 135557 z 1999 to ref 131973 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b line 134661 -_-_ from ref 131973 z 2003 to ref 128005 line 134789 -_-_ diff --git a/uml/lumiera/5.session b/uml/lumiera/5.session index dc8936ef6..1a789da17 100644 --- a/uml/lumiera/5.session +++ b/uml/lumiera/5.session @@ -2,17 +2,20 @@ window_sizes 1140 830 270 860 680 71 diagrams classdiagram_ref 131973 // Render Mechanics 428 623 100 4 2 0 - active collaborationdiagram_ref 132229 // Render Process + collaborationdiagram_ref 132229 // Render Process 817 644 100 4 0 0 + active classdiagram_ref 132357 // StateAdapter composition + 418 520 100 4 0 0 end show_stereotypes selected - package_ref 129 // lumiera +package_ref 129 // lumiera open class_ref 132741 // State - package_ref 129029 // Controller +package_ref 129029 // Controller class_ref 131717 // ProcNode + class_ref 142469 // StateProxy class_ref 142597 // StateAdapter usecaseview_ref 128005 // Renderengine Use class_ref 140677 // QueryHandler diff --git a/uml/lumiera/lumiera.prj b/uml/lumiera/lumiera.prj index 2b3a34ea7..2238424c2 100644 --- a/uml/lumiera/lumiera.prj +++ b/uml/lumiera/lumiera.prj @@ -1,6 +1,6 @@ format 40 "lumiera" - revision 46 + revision 47 modified_by 5 "hiv" cpp_root_dir "../../src/" diff --git a/wiki/renderengine.html b/wiki/renderengine.html index 674a5d2a2..6384ef114 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -1127,16 +1127,17 @@ Basically, each elementary operation has to record the informations necessary to {{red{to be defined in more detail later...}}}
                    -
                    +
                    The &raquo;Timeline&laquo; is a sequence of ~MObjects -- here clips -- together with an ExplicitPlacement, locating each clip at a given time and track. (Note: I simplified the time format and wrote frame numbers to make it more clear)
                     [img[Example1: Objects in the EDL/Fixture|uml/fig128773.png]]
                     
                     ----
                     After beeing processed by the Builder, we get the following Render Engine configuration
                    +{{red{note: please take this only as a "big picture", the implementation details got a lot more complicated as of 6/08}}}
                     [img[Example1: generated Render Engine|uml/fig129029.png]]
                     
                    -
                    +
                    {{red{TODO: seemingly this example is slightly outdated, as the implementation of placements is now indirect via LocatingPin objects}}}
                     This Example showes the //high level// EDL as well. This needs to be transformed into a Fixture by some facility still to be designed. Basically, each [[Placement]] needs to be queried for this to get the corresponding ExplicitPlacement. The difficult part is to handle possible Placement constraints, e.g. one clip can't be placed at a timespan covered by another clip on the same track. In the current Cinelerra2, all of this is done directly by the GUI actions.
                     
                    @@ -1146,6 +1147,7 @@ The &raquo;Timeline&laquo; is a sequence of ~MObjects -- note: using the
                     ----
                     After beeing processed by the Builder, we get a Render Engine configuration.<br>
                     It has to be segmented at least at every point with changes in the configuration, but some variations are possible, e.g. we could create a Render Engine for every Frame (as Cinelerra2 does) or we could optimize out some configurations (for example the effect extended beyond the end of the clip)
                    +{{red{note: as of 6/08 this can be taken only as the "big picture". Implementation will differ in details, and is more complicated than shown here}}}
                     [img[Example2: generated Render Engine|uml/fig129157.png]]
                     
                    @@ -3041,7 +3043,7 @@ At first sight the link between asset and clip-MO is a simple logical relation b [img[Entities comprising the Render Engine|uml/fig128389.png]]
                    -
                    +
                    Below are some notes regarding details of the actual implementation of the render process and processing node operation. In the description of the [[render node operation protocol|NodeOperationProtocol]] and the [[mechanics of the render process|RenderMechanics]], these details were left out deliberately.
                     
                     !Layered structure of State
                    @@ -3054,12 +3056,16 @@ For the purpose of node operation, Buffers are identified by a //Buffer-handle,/
                     Some data processors simply require to work on multiple channels simultanously, while others work just on a single channel and will be replicated by the builder for each channel invoved. Thus, we are struck with the nasty situation that the node graph may go through some nodes spanning the chain of several channels. Now the decision is //not to care for this complexity within a single chain calculating a single channel.// We rely solely on the cache to avoid duplicated calculations. When a given node happens to produce multiple output buffers, we are bound to allocate them for the purpose of this nodes {{{process()}}} call, but we just "let go" the buffers not needed immediately for the channel acutally to be processed. For this to work, it is supposed that the builder has wired in a caching, and that the cache will hit when we touch the same node again for the other channels.
                     
                     !Configuration of the processing nodes
                    +[>img[uml/fig132357.png]]
                     Every node is actually decomposed into three parts
                     * an interface container of a ProcNode subclass
                     * an {{{const}}} WiringDescriptor, which is actually parametrized to a subtype encoding details of the intended operation
                     * an StateAdapter object created on the stack for each {{{pull()}}} call and configured specifically for the intended operation
                     Thus, the outer container can be changed polymorphically to support the different kinds of nodes (large-scale view). The actual wiring of the nodes is contained in the WiringDescriptor, including the {{{process()}}} function pointer. Additionally, this WiringDescriptor knows the actual type of the StateAdapter to create, and this actual type has been chosen by the builder such as to select details of the desired operation of this mode, for example caching / no caching or maybe ~OpenGL rendering or the special case of a node pulling directly from a source reader. Most of this configuration is done by selecting the right template specialisation within the builder; thus in the critical path most of the calls can be inlined
                     
                    +!!!! composing the actual StateAdapter
                    +As shown in the class diagram to the right, the actual implementation is assembled by chaining together the various policy classes governing parts of the node operation, like Caching, in-Place calculation capability, etc. (&rarr; see [[here|StateAdapter]] for details). The rationale is that we can allocate at runtime a StateProxy object directly on the stack with the necessary buffer table size and an precisely tailored and mostly inlined implementation of the call sequence for "calculating the predecessor nodes". We //do employ//&nbsp; some virtual calls for the buffer management in order to avoid coupling the policy classes to the actual number of in/out buffers. (As of 6/2008, this is mainly a precaution to be able to control the number of generated template instances. If we ever get in the region of several hundred individual specialisations, we'd need to separate out the allocation of the "wiring table" into a hand-made stack-like buffer allocated from the heap.)
                    +
                     !Rules for buffer allocation and freeing
                     * only output buffers are allocated. It is //never necessary//&nbsp; to allocate input buffers!
                     * buffers are to be allocated as late as possible, typically just before invoking {{{process()}}}
                    @@ -3068,6 +3074,8 @@ Thus, the outer container can be changed polymorphically to support the differen
                     * any other buffers filled with results in the course of the same {{{process()}}} call can be released immediately before returning from the {{{pull()}}}
                     * similar, and input buffers are to be released immediately after the {{{process()}}} call, but before returing from this {{{pull()}}}
                     * buffers are allways released by calling to the "current state" (which is a StateProxy), providing the buffer-ID to be released
                    +
                    +@@clear(right):display(block):@@
                     
                    From 9389ce2d68d665ba12734b1c7d46447480c43d23 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 1 Jul 2008 04:53:23 +0200 Subject: [PATCH 10/12] WIP possible solution how the operation chunks could be assembled --- doc/devel/uml/class143365.html | 22 ++++ doc/devel/uml/class143493.html | 24 ++++ doc/devel/uml/class143621.html | 24 ++++ doc/devel/uml/class143749.html | 24 ++++ doc/devel/uml/class143877.html | 24 ++++ doc/devel/uml/class144005.html | 24 ++++ doc/devel/uml/class144133.html | 20 +++ src/proc/engine/nodeoperation.hpp | 194 +++++++++++++++++++++++------- src/proc/state.hpp | 16 +-- uml/lumiera/132357.diagram | 81 +++++++++++++ 10 files changed, 400 insertions(+), 53 deletions(-) create mode 100644 doc/devel/uml/class143365.html create mode 100644 doc/devel/uml/class143493.html create mode 100644 doc/devel/uml/class143621.html create mode 100644 doc/devel/uml/class143749.html create mode 100644 doc/devel/uml/class143877.html create mode 100644 doc/devel/uml/class144005.html create mode 100644 doc/devel/uml/class144133.html create mode 100644 uml/lumiera/132357.diagram diff --git a/doc/devel/uml/class143365.html b/doc/devel/uml/class143365.html new file mode 100644 index 000000000..8f96f6b27 --- /dev/null +++ b/doc/devel/uml/class143365.html @@ -0,0 +1,22 @@ + + + + + + +Class NodeWiring + + + + + +
                    Class NodeWiring
                    +

                    + + + + +

                    Declaration :

                    +
                    + + diff --git a/doc/devel/uml/class143493.html b/doc/devel/uml/class143493.html new file mode 100644 index 000000000..63ef30fb2 --- /dev/null +++ b/doc/devel/uml/class143493.html @@ -0,0 +1,24 @@ + + + + + + +Class InvocationStateBase + + + + + +
                    Class InvocationStateBase
                    +

                    + + + + +

                    Declaration :

                    • C++ : class InvocationStateBase : public State

                    Directly inherited by : Caching

                    +
                    +
                    +

                    All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer

                    + + diff --git a/doc/devel/uml/class143621.html b/doc/devel/uml/class143621.html new file mode 100644 index 000000000..39379446c --- /dev/null +++ b/doc/devel/uml/class143621.html @@ -0,0 +1,24 @@ + + + + + + +Class Caching + + + + + +
                    Class Caching
                    +

                    + + + + +

                    Declaration :

                    Directly inherited by : Process

                    +
                    +
                    +

                    All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer

                    + + diff --git a/doc/devel/uml/class143749.html b/doc/devel/uml/class143749.html new file mode 100644 index 000000000..2d3726110 --- /dev/null +++ b/doc/devel/uml/class143749.html @@ -0,0 +1,24 @@ + + + + + + +Class Process + + + + + +
                    Class Process
                    +

                    + + + + +

                    Declaration :

                    • C++ : class Process : public Caching

                    Directly inherited by : InPlace

                    +
                    +
                    +

                    All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer

                    + + diff --git a/doc/devel/uml/class143877.html b/doc/devel/uml/class143877.html new file mode 100644 index 000000000..b3164a70a --- /dev/null +++ b/doc/devel/uml/class143877.html @@ -0,0 +1,24 @@ + + + + + + +Class InPlace + + + + + +
                    Class InPlace
                    +

                    + + + + +

                    Declaration :

                    • C++ : class InPlace : public Process

                    Directly inherited by : StateProxy

                    +
                    +
                    +

                    All public operations : allocateBuffer , fetch , isCalculated , releaseBuffer

                    + + diff --git a/doc/devel/uml/class144005.html b/doc/devel/uml/class144005.html new file mode 100644 index 000000000..9fd2629bc --- /dev/null +++ b/doc/devel/uml/class144005.html @@ -0,0 +1,24 @@ + + + + + + +Class WiringTable + + + + + +
                    Class WiringTable
                    +

                    + + + + +

                    Declaration :

                    • C++ : template<int SIZ> class WiringTable
                    + +
                    Relation <directional aggregation by value>

                    Declaration :

                    +
                    Relation <unidirectional association>

                    Declaration :

                    + + diff --git a/doc/devel/uml/class144133.html b/doc/devel/uml/class144133.html new file mode 100644 index 000000000..995d09019 --- /dev/null +++ b/doc/devel/uml/class144133.html @@ -0,0 +1,20 @@ + + + + + + +Class BuffHandle + + + + + +
                    Class BuffHandle
                    +

                    + + + + +

                    Declaration :

                    • C++ : class BuffHandle
                    + diff --git a/src/proc/engine/nodeoperation.hpp b/src/proc/engine/nodeoperation.hpp index 55450fba7..05dc89992 100644 --- a/src/proc/engine/nodeoperation.hpp +++ b/src/proc/engine/nodeoperation.hpp @@ -20,6 +20,33 @@ */ +/** @file nodeoperation.hpp + ** Chunks of operation for invoking the rendernodes. + ** This header defines the "glue" which holds together the render node network + ** and enables to pull a result frames from the nodes. Especially, the aspect of + ** buffer management is covered here. Each node has been preconfigured by the builder + ** with a WiringDescriptor and a concrete type of a StateAdapter. These concrete + ** StateAdapter objects are assembled out of the building blocks defined in this header, + ** depending on the desired mode of operation. Any node can be built to + ** - participate in the Caching or ignore the cache + ** - actually process a result or just pull frames from a source + ** - employ in-Place calculations or use separate in/out buffers + ** Additionally, each node may have a given number of input/output pins, expecting to + ** be provided with buffers holding a specific kind of data. + ** + ** \par composition of the StateAdapter + ** For each individual ProcNode#pull() call, the WiringAdapter#callDown() builds an StateAdapter + ** instance directly on the stack, holding the actual buffer pointers and state references. Using this + ** StateAdapter, the predecessor nodes are pulled. The way these operations are carried out is encoded + ** in the actual StateAdapter type known to the NodeWiring (WiringAdapter) instance. All of these actual + ** StateAdapter types are built as implementing the engine::State interface, on top of the InvocationStateBase + ** and inheriting from a chain of strategy classes (single inheritance, mostly \em no virtual functions). + ** + ** @see engine::ProcNode + ** @see engine::StateProxy + ** @see nodewiring.hpp interface for building/wiring the nodes + ** + */ #ifndef ENGINE_NODEOPERATION_H #define ENGINE_NODEOPERATION_H @@ -33,6 +60,16 @@ namespace engine { + + /** + * (abstract) base class of all concrete StateAdapter types. + * Defines the skeleton for the node operation/calculation + */ + class InvocationStateBase + : public State + { + + }; /** * Adapter to shield the ProcNode from the actual buffer management, @@ -70,64 +107,108 @@ namespace engine { } }; - struct Caching + template + struct QueryCache : NEXT { - void retrieveResult (uint requiredOutputNr) + BuffHandle step () // brauche: current state { BuffHandle fetched = current_.fetch (genFrameID (requiredOutputNr)); if (fetched) return fetched; - - // Cache miss, need to calculate - BuffHandle calculated[NrO]; - calculateResult (&calculated); - - // commit result to Cache - current_.isCalculated (NrO, calculated, requiredOutputNr); - - return calculated[requiredOutputNr]; + else + return NEXT::step(); } }; + - struct NoCaching + template + struct PullInput : NEXT { - void retrieveResult (BuffHandle requiredOutputNr) + BuffHandle step () { - return calculateResult (0); - } - }; - - struct Process - { - BuffHandle calculateResult(BuffHandle* calculated) - { - uint nrI = this->getNrI(); - for (uint i = 0; icreateBuffTable(); + + ASSERT (this->buffTab); + ASSERT (0 < this->buffTabSize()); + ASSERT (this->nrO+this->nrI <= this->buffTabSize()); + ASSERT (this->buffTab->inHandles = &this->buffTab->handles[this->nrO]); + BuffHandle *inH = this->buffTab->inHandles; + BuffHandle::PBuff *inBuff = this->buffTab->inBuffs; + + for (uint i = 0; i < this->nrI; ++i ) { - BuffHandle inID = predNode.pull(inNo); // invoke predecessor - this->inBuff[i] = current_.getBuffer(inID); + inBuff[i] = + *(inH[i] = this->pullPredecessor(i)); // invoke predecessor // now Input #i is ready... } - uint nrO = this->getNrO(); - for (uint i = 0; iallocateBuffer(this->getBuferType(i)); ///TODO: Null pointer when no caching!!!!! - this->outBuff[i] = current_.getBuffer(calculated[i]); - // now Output buffer for channel #i is available... - } - // - // Invoke our own process() function - this->wiring_.process (this->outBuff); - - this->feedCache(); - // Inputs no longer needed - for (uint i = 0; i + struct AllocOutputFromCache + { + BuffHandle step () + { + ASSERT (this->buffTab); + ASSERT (this->nrO < this->buffTabSize()); + BuffHandle *outH = this->buffTab->handles; + BuffHandle::PBuff *outBuff = this->buffTab->buffers; + + for (uint i = 0; i < this->nrO; ++i ) + { + outBuff[i] = + *(outH[i] = this->allocateBuffer(i)); + // now Output buffer for channel #i is available... + } + return NEXT::step(); + } + }; + + template + struct ProcessData + { + BuffHandle step () + { + ASSERT (this->buffTab); + ASSERT (this->nrO+this->nrI <= this->buffTabSize()); + ASSERT (this->validateBuffers()); + + // Invoke our own process() function, providing the buffer array + this->wiring_.processFunction (this->buffTab->buffers); + + return NEXT::step(); + } + }; + + template + struct FeedCache + { + BuffHandle step () + { + // declare all Outputs as finished + this->current_.isCalculated(this->buffTab->handles, + this->nrO); + + return NEXT::step(); + } + }; + + template + struct ReleaseBuffers + { + BuffHandle step () + { + // all buffers besides the required Output no longer needed + this->current_.releaseBuffers(this->buffTab->handles, + this->buffTabSize(), + this->requiredOutputNr); + + return this->buffTab->outH[this->requiredOutputNr]; + } + }; + + template struct NoProcess { BuffHandle calculateResult(BuffHandle* calculated) @@ -150,6 +231,35 @@ namespace engine { }; + + + /* === declare the possible Assembly of these elementary steps === */ + + template + struct Strategy + { + BuffHandle step () { NOTREACHED; } + }; + + template<> + struct Strategy< Config > + : QueryCache < + PullInput< + AllocOutputFromCache< + ProcessData< + FeedCache< + ReleaseBuffers< + InvocationStateBase > > > > > > + { }; + + template<> + struct Strategy< Config > + : PullInput< + AllocOutputFromParent< + ProcessData< + ReleaseBuffers< + InvocationStateBase > > > > + { }; } // namespace engine diff --git a/src/proc/state.hpp b/src/proc/state.hpp index 6ef1e863f..7828398ed 100644 --- a/src/proc/state.hpp +++ b/src/proc/state.hpp @@ -36,21 +36,11 @@ namespace engine { class StateAdapter; - class BuffHandle + struct BuffHandle { - protected: typedef float Buff; typedef Buff* PBuff;//////TODO define the Buffer type(s) - PBuff pBuffer_; - long sourceID_; - - BuffHandle (PBuff pb, long id) - : pBuffer_(pb), - sourceID_(id) - { } - - public: PBuff operator->() const { @@ -62,6 +52,10 @@ namespace engine { ENSURE (pBuffer_); return *pBuffer_; } + + protected: + PBuff pBuffer_; + long sourceID_; }; diff --git a/uml/lumiera/132357.diagram b/uml/lumiera/132357.diagram new file mode 100644 index 000000000..a097c7137 --- /dev/null +++ b/uml/lumiera/132357.diagram @@ -0,0 +1,81 @@ +format 40 + +classcanvas 128005 class_ref 132741 // State + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 78 10 2000 + end +classcanvas 128133 class_ref 143493 // InvocationStateBase + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 203 104 2000 + end +classcanvas 128261 class_ref 143621 // Caching + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 235 157 2000 + end +classcanvas 128389 class_ref 143749 // Process + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 236 212 2000 + end +classcanvas 128517 class_ref 143877 // InPlace + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 238 268 2000 + end +classcanvas 128645 class_ref 142469 // StateProxy + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 209 332 2004 + end +classcanvas 130309 class_ref 144005 // WiringTable + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 101 298 2000 + end +classcanvas 130437 class_ref 142725 // WiringDescriptor + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 36 213 2005 + end +classcanvas 130565 class_ref 144133 // BuffHandle + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 36 379 2000 + end +textcanvas 131461 "const" + xyzwh 109 257 2010 29 18 +relationcanvas 128901 relation_ref 149765 // + from ref 128645 z 1999 to ref 128517 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 129029 relation_ref 149893 // + from ref 128517 z 1999 to ref 128389 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 129157 relation_ref 150021 // + from ref 128389 z 1999 to ref 128261 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 129285 relation_ref 150149 // + from ref 128261 z 1999 to ref 128133 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 129413 relation_ref 150277 // + from ref 128133 z 1999 to point 260 69 + line 129925 z 1999 to point 190 69 + line 130181 z 1999 to point 161 176 + line 130053 z 1999 to point 118 176 + line 129797 z 1999 to ref 128005 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 130693 relation_ref 150405 // + geometry VHr + from ref 130309 z 1999 stereotype "<>" xyz 43 309 3000 to point 70 326 + line 130821 z 1999 to ref 130565 + no_role_a no_role_b + multiplicity_a_pos 45 354 3000 no_multiplicity_b +relationcanvas 130949 relation_ref 150533 // + from ref 130309 z 1999 to ref 130437 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 131077 relation_ref 150661 // + geometry VHr + from ref 128645 z 1999 to point 136 371 + line 131333 z 1999 to ref 130309 + role_a_pos 148 367 3000 no_role_b + multiplicity_a_pos 122 359 3000 no_multiplicity_b +end From 98a542f920fb50526b52d9a3e8d9caa252b72c34 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 5 Jul 2008 18:50:54 +0200 Subject: [PATCH 11/12] WIP drafting how to build all possible operation configs --- src/common/error.hpp | 1 + src/lib/appconfig.hpp | 3 +- src/proc/engine/nodeoperation.hpp | 24 ++++++ src/proc/engine/nodewiring.cpp | 7 +- src/proc/engine/nodewiring.hpp | 4 +- src/proc/engine/nodewiringconfig.hpp | 121 +++++++++++++++++++++++++++ 6 files changed, 156 insertions(+), 4 deletions(-) create mode 100644 src/proc/engine/nodewiringconfig.hpp diff --git a/src/common/error.hpp b/src/common/error.hpp index 687425ec2..84140af80 100644 --- a/src/common/error.hpp +++ b/src/common/error.hpp @@ -152,6 +152,7 @@ namespace lumiera /** install our own handler for undeclared exceptions. Will be * called automatically ON_BASIC_INIT when including errror.hpp + * @note it's OK this is defined multiple times... * @see appconfig.hpp */ void install_unexpectedException_handler (); namespace { diff --git a/src/lib/appconfig.hpp b/src/lib/appconfig.hpp index b82c3fa2b..a69336d78 100644 --- a/src/lib/appconfig.hpp +++ b/src/lib/appconfig.hpp @@ -129,7 +129,8 @@ namespace lumiera * All other lables are just arbitrary (string) constants and it * is necessary that "someone" cares to fire off the lifcycle events * at the right place. For example, lumiera-main (and the test runner) - * calls \c Appconfig::instance().execute(ON_GLOBAL_INIT) (and..SHUTDOWN) + * calls \c Appconfig::instance().execute(ON_GLOBAL_INIT) (and..SHUTDOWN) + * @note duplicate or repeated calls with the same callback are a NOP */ class LifecycleHook : private noncopyable diff --git a/src/proc/engine/nodeoperation.hpp b/src/proc/engine/nodeoperation.hpp index 05dc89992..ea27c05e8 100644 --- a/src/proc/engine/nodeoperation.hpp +++ b/src/proc/engine/nodeoperation.hpp @@ -53,6 +53,8 @@ #include "proc/engine/procnode.hpp" +#include "proc/engine/nodewiringconfig.hpp" +#include "lib/appconfig.hpp" @@ -262,5 +264,27 @@ namespace engine { { }; + // At Application startup: build table of all possible operation configs + namespace { + + bool + determine_if_case_is_possible (Bits& caseFlags) + { + ////////////////////////////////////////////////TODO: Henne oder Ei? + } + + void + build_table_of_possible_configs () + { + registerPossibleCases (&determine_if_case_is_possible); + } + + + using namespace lumiera; + LifecycleHook schedule_ (ON_BASIC_INIT, &build_table_of_possible_configs); + + } + + } // namespace engine #endif diff --git a/src/proc/engine/nodewiring.cpp b/src/proc/engine/nodewiring.cpp index e05a2c4e0..023253a0e 100644 --- a/src/proc/engine/nodewiring.cpp +++ b/src/proc/engine/nodewiring.cpp @@ -24,6 +24,8 @@ #include "proc/engine/procnode.hpp" #include "proc/engine/nodewiring.hpp" #include "proc/engine/nodeoperation.hpp" +#include "proc/engine/nodewiringconfig.hpp" + namespace engine { @@ -35,7 +37,7 @@ namespace engine { * actually drives the necessary template instantiations for all cases * encountered while building the node network. * The created WiringDescriptor object is bulk allocated similar to the ProcNode - * objects for a given segment of ther Timeline. It should be further configured + * objects for a given segment of the Timeline. It should be further configured * with the actual predecessor nodes pointers and can then be used to create * the new processing node to be wired up. */ @@ -43,7 +45,10 @@ namespace engine { WiringFactory::operator() (uint nrOut, uint nrIn, bool cache) { UNIMPLEMENTED ("build the actual wiring descriptor based on given operation options"); + + return selectConfig(cache, process, inplace).fabricate(); } + // BlockAlloc > > >::fabricate(); } // namespace engine diff --git a/src/proc/engine/nodewiring.hpp b/src/proc/engine/nodewiring.hpp index ee62d7956..0f6cc9500 100644 --- a/src/proc/engine/nodewiring.hpp +++ b/src/proc/engine/nodewiring.hpp @@ -38,8 +38,8 @@ namespace engine { /** - * Actual implementation of the link between nodes - * and also the "track switch" for the execution path + * Actual implementation of the link between nodes, + * also acting as "track switch" for the execution path * choosen while operating the node network for rendering. * @param STATE StateAdapter object controlling the * behaviour of callDown() while rendering. diff --git a/src/proc/engine/nodewiringconfig.hpp b/src/proc/engine/nodewiringconfig.hpp new file mode 100644 index 000000000..4e23e7048 --- /dev/null +++ b/src/proc/engine/nodewiringconfig.hpp @@ -0,0 +1,121 @@ +/* + NODEWIRINGCONFIG.hpp - Helper for representing and selecting the wiring case + + Copyright (C) Lumiera.org + 2008, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +#ifndef ENGINE_NODEWIRINGCONFIG_H +#define ENGINE_NODEWIRINGCONFIG_H + + + +//#include +#include +#include +#include + + + +namespace engine { + + + class WiringFactory; + + enum Cases + { + CACHING, + PROCESS, + INPLACE, + + NUM_Cases + }; + typedef std::bitset Bits; + + Bits + getCaseRepresentation (bool caching, bool process, bool inplace) + { + Bits repr_as_bits; + repr_as_bits.set (CACHING, caching) + .set (PROCESS, process) + .set (INPLACE, inplace); + return repr_as_bits; + } + + const ulong numCases (Bits().flip().to_ulong()); + std::vector possibleConfigs; + + + void + registerPossibleCases(bool (*possible)(Bits&) ) + { + ulong numCases (Bits().flip().to_ulong()); + for (ulong combi=0; combi + struct Config + { + static Bits getRepr () { return getCaseRepresentation(caching,process,inplace); } + }; + + + + template class Factory> + class ConfigSelector + { + struct FacFunctor + { + virtual ~FacFunctor() {} + virtual RET operator() () =0; + }; + + typedef boost::scoped_ptr PFunc; + typedef std::map ConfigTable; + + ConfigTable possibleConfig_; + + void + createFactory (Bits config) + { + this->possibleConfig_[config].reset (new Factory); ////////////TODO: wie den richtigen Config-Typ bekommen?? + } + + public: + configSelector() + { + for_each (possibleConfigs, bind(&createFactory, this, _1)); + } + }; + + + +} // namespace engine +#endif From 39d321a4a58edae1e3b868390653dff27c9a6ad0 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 7 Jul 2008 05:40:53 +0200 Subject: [PATCH 12/12] WIP this approach is more likely to work actually... --- src/proc/engine/nodeoperation.hpp | 4 +- src/proc/engine/nodewiringconfig.hpp | 335 ++++++++++++++++++++++++--- 2 files changed, 306 insertions(+), 33 deletions(-) diff --git a/src/proc/engine/nodeoperation.hpp b/src/proc/engine/nodeoperation.hpp index ea27c05e8..8f3711dc8 100644 --- a/src/proc/engine/nodeoperation.hpp +++ b/src/proc/engine/nodeoperation.hpp @@ -244,7 +244,7 @@ namespace engine { }; template<> - struct Strategy< Config > + struct Strategy< Config > : QueryCache < PullInput< AllocOutputFromCache< @@ -255,7 +255,7 @@ namespace engine { { }; template<> - struct Strategy< Config > + struct Strategy< Config > : PullInput< AllocOutputFromParent< ProcessData< diff --git a/src/proc/engine/nodewiringconfig.hpp b/src/proc/engine/nodewiringconfig.hpp index 4e23e7048..4ee451072 100644 --- a/src/proc/engine/nodewiringconfig.hpp +++ b/src/proc/engine/nodewiringconfig.hpp @@ -31,6 +31,216 @@ #include #include + /////////////////TODO: library + +#include "common/typelistutil.hpp" +namespace lumiera { + namespace typelist { + + template + struct CondNode + : TAIL + { + typedef TAIL Next; + }; + template + struct CondNode + : Node + { + typedef Node Next; + }; + + template class _P_> + struct Filter; + + template class _P_> + struct Filter + : NullType + { + typedef NullType Next; + }; + template class _P_> + struct Filter,_P_> + : CondNode<_P_, TY, TYPES> + { + typedef CondNode<_P_, TY, TYPES> Next; + }; + + + template + struct Append : Types::List + { }; + template + struct Append + : Node + { }; + template + struct Append + : Node + { }; + template + struct Append > + : Node + { }; + template + struct Append, NullType> + : Node + { }; + template + struct Append, TAIL> + : Node > + { }; + + template + struct PrefixAll + : Append + { }; + template + struct PrefixAll + : NullType + { }; + template + struct PrefixAll > + : Node< Append + , PrefixAll + > + { }; + + template + struct Distribute : Append + { }; + template + struct Distribute, TAIL> + : Append< PrefixAll + , Distribute + > + { }; + template class _PERM_> + struct Combine : Distribute<_PERM_, NullType> + { }; + template class _PERM_> + struct Combine,_PERM_> + : Distribute<_PERM_, Combine > + { }; + + template + struct FlagOnOff : Types::List + { }; + + template + struct CombineFlags + : Combine + { }; + + + template struct Flag { }; + template<> struct Flag<0> : NullType { }; + template< char f1=0 + , char f2=0 + , char f3=0 + , char f4=0 + , char f5=0 + > + struct FlagTuple + : Types< Flag + , Flag + , Flag + , Flag + , Flag + >::List + { }; + + template< char f1=0 + , char f2=0 + , char f3=0 + , char f4=0 + , char f5=0 + > + struct Config + { + typedef FlagTuple Flags; + }; + + template + struct DefineConfigFlags; + + template< char f1=0 + , char f2=0 + , char f3=0 + , char f4=0 + , char f5=0 + > + struct DefineConfigFlags< FlagTuple > + : Config + { }; + + + /** + * Helper for calculating values and for + * invoking runtime code based on a given FlagTuple. + * Can also be used on a Typelist of several FlagTuples. + * The latter case is typically used to invoke an operation + * while ennumerating all Flag-Configurations defined in Code. + * An example would be to build (at runtime) an dispatcher table. + * Explanation: the supposed data structure is a list of lists, + * where "list" here refers to a Typelist (compile time). Each + * of the inner lists in this structure represents a single + * Flag-Configuration. For the Case covering the outer List, + * we provide a templated visitaion function, which can accept + * a functor object to be invoked on each Flag-Configuration. + */ + template + struct FlagInfo; + + template + struct FlagInfo, FLAGS> > + { + enum{ BITS = max(ff, FlagInfo::BITS) + , CODE = (1<::CODE + }; + }; + template<> + struct FlagInfo + { + enum{ BITS = 0 + , CODE = 0 + }; + + template + static FUNC::Ret + accept (FUNC& functor) + { + return functor.done(); + } + }; + template + struct FlagInfo, FLAGS> + , TAIL + > > + { + typedef Node, FLAGS> CurrConfig; + enum{ BITS = max(FlagInfo::BITS, FlagInfo::BITS) + }; + + template + static FUNC::Ret + accept (FUNC& functor) + { + functor.template visit(FlagInfo::CODE); + return FlagInfo::accept (functor); + } + }; + + + + + + } // namespace typelist + +} // namespace lumiera + + /////////////////TODO: library(end) + namespace engine { @@ -38,6 +248,12 @@ namespace engine { class WiringFactory; + ///////TODO + using lumiera::typelist::Config; + using lumiera::typelist::FlagInfo; + ///////TODO + + enum Cases { CACHING, @@ -47,30 +263,18 @@ namespace engine { NUM_Cases }; typedef std::bitset Bits; + + //////////////////////////////////TODO: noch nötig?? + template Bits - getCaseRepresentation (bool caching, bool process, bool inplace) + getCaseRepresentation (CONF config) { - Bits repr_as_bits; - repr_as_bits.set (CACHING, caching) - .set (PROCESS, process) - .set (INPLACE, inplace); - return repr_as_bits; + return Bits (FlagInfo::CODE); } - const ulong numCases (Bits().flip().to_ulong()); - std::vector possibleConfigs; - void - registerPossibleCases(bool (*possible)(Bits&) ) - { - ulong numCases (Bits().flip().to_ulong()); - for (ulong combi=0; combi - struct Config - { - static Bits getRepr () { return getCaseRepresentation(caching,process,inplace); } - }; +// template +// struct Config +// { +// static Bits getRepr () { return getCaseRepresentation(caching,process,inplace); } +// }; - - template class Factory> + /** + * Helper for fabricating ProcNode Wiring configurations. + * This object builds a table of factories, one for each + * possible node configuration. Provided with the desired + * configuration encoded as bits, the related factory can + * be invoked, thus producing a product object for the + * given configuration. + * \par implementation notes + * The actual factory class is templated, so it will be defined + * at the use site of ConfigSelecgtor. Moreover, this factory + * usually expects an ctor argument, which will be fed through + * when creating the ConfigSelector instance. This is one of + * the reasons why we go through all these complicated factory + * building: this ctor argument usually brings in a reference + * to the actual memory allocator. Thus we have to rebuild the + * ConfigSelector each time we switch and rebuild the ProcNode + * factories, which in turn happens each time we use a new + * bulk allocation memory block -- typically for each separate + * segment of the Timeline and processing node graph. + * The selection of the possible flag configurations, for which + * Factory instances are created in the table, is governed by + * the type parameter of the ConfigSelector ctor. This type + * parameter needs to be a Typelist of Typelists, each + * representing a flag configuration. The intention is to + * use template metaprogramming to extract all currently defined + * configurations for StateProxy objects to drive this selection. + */ + template class Factory> class ConfigSelector { + typedef typename Factory::Ret Ret; + typedef typename Factory::Param Param; + struct FacFunctor { virtual ~FacFunctor() {} - virtual RET operator() () =0; + virtual Ret invoke() =0; }; + template + struct FactoryHolder : FacFunctor + { + FAC factory_; + FactroyHolder(Param p) : factory_(p) {} + + virtual Ret invoke () { return factory_(); } + }; + typedef boost::scoped_ptr PFunc; typedef std::map ConfigTable; ConfigTable possibleConfig_; - void - createFactory (Bits config) + /** Helper: a visitor usable with FlagInfo */ + struct FactoryTableBuilder { - this->possibleConfig_[config].reset (new Factory); ////////////TODO: wie den richtigen Config-Typ bekommen?? - } + Param ctor_param_; + ConfigTable& factories_; + + FactoryTableBuilder (ConfigTable& tab, Param p) + : ctor_param_(p), + factories_(tab) { } + + + /* === visitation interface === */ + + typedef void Ret; + + template + void + visit (ulong code) + { + typedef typename DefineConfigFlags Config; + factories_[code].reset (new FactoryHolder > (ctor_param_)); + } + + void done() {} + }; public: - configSelector() + template + ConfigSelector(Param factory_ctor_param) { - for_each (possibleConfigs, bind(&createFactory, this, _1)); + FactoryTableBuilder buildTable(this->possibleConfig_, + factory_ctor_param ); + // store a new Factory instance + // for each possible Flag-Configuration + FlagInfo::accept (buildTable); + } + + Ret + operator() (Bits configFlags) ///< invoke the factory corresponding to the given config + { + return possibleConfig_[configFlags]->invoke(); } };