Lumiera  0.pre.03
»edit your freedom«
weaving-pattern-builder.hpp File Reference

Go to the source code of this file.

Description

Construction kit to establish an invocation scheme for media calculations.

Adapters and configuration is provided to invoke the actual media processing function in accordance to a fixed wiring scheme:

  • the function takes two arguments
  • these are an array of input and output buffer pointers
  • buffer sizes or types are assumed to be uniform over all »slots«
  • yet the input side my use another type than the output side
    Todo:
    as of 10/2024, this scheme is established as prototype to explore how processing nodes can be build, connected and invoked; the expectation is however that this simple scheme is suitable to adapt and handle many common cases of invoking media processing functions, because the given functor is constructed within a plug-in tailored to a specific media processing library (e.g. FFmpeg) and thus can be a lambda to forward to the actual function.
    Note
    steam::engine::Turnout mixes-in the steam::engine::SimpleWeavingPattern, which in turn inherits from an Invocation Adapter given as template parameter. So this constitutes an extension point where other, more elaborate invocation schemes could be integrated.

Interplay of NodeBuider, PortBuilder and WeavingBuilder

The steam::engine::WeavingBuilder defined here serves as the low-level builder and adapter to prepare the wiring and invocation. The builder-API allows to setup the wiring of input and output-»slots« and control some detail aspects like caching. However, without defining any connections explicitly, a simple 1:1 wiring scheme is employed

  • each input slot of the function gets an input buffer, which is filled by pulling (i.e. invoking) a predecessor node (a so called »lead«).
  • for each output slot a buffer is allocated for the processing function to drop off the calculated media data
  • only one of these output buffers is used as actual result, while the other buffers are just discarded (but may possibly be fed to the frame cache).

Each Processing Node represents one specific processing functionality on a logical level; yet such a node may be able to generate several „flavours“ of this processing, which are represented as ports on this node. Actually, each such port stands for one specific setup of a function invocation, with appropriate wiring of input and output connections. For example, an audio filtering function may be exposed on port-#1 for stereo sound, while port-#2 may process the left, and port-#3 the right channel in isolation. It is entirely up to the library-adapter-plug-in what processing functions to expose, and in which flavours. The WeavingBuilder is used to generate a single Turnout object, which corresponds to the invocation of a single port and thus one flavour of processing.

At one architectural level above, the NodeBuilder exposes the ability to set up a ProcNode, complete with several ports and connected to possibly several predecessor nodes. Using a sequence of NodeBuilder invocations, the processing node graph can be built gradually, starting from the source (predecessors) and moving up to the exit nodes, which produce the desired calculation results. The NodeBuilder offers a function to define the predecessor nodes (also designated as lead nodes), and it offers an entrance point to descend into a PortBuilder, allowing to add the port definitions for this node step by step.

On the implementation level, the PortBuilder inherits from the NodeBuilder and embeds a WeavingBuilder instance. Moreover, the actual parametrisations of the NodeBuilder template are chained to create a functional data structure. This intricate setup is necessary because the actual data structure of the node graph comprises several small descriptor arrays and interconnected pointers, which are all placed into consecutive chunks of memory, using a custom allocator, the AllocationCluster. The lib::Several is used as front-end to access these small collections of related objects, and the associated lib::SeveralBuilder provides the low-level memory allocation and object creation functionality. The purpose of this admittedly quite elaborate scheme is to generate a compact data structure, with high cache locality and without wasting too much memory. Since the exact number of elements and the size of those elements can be deduced only after the builder-API usage has been completed, the aforementioned functional datastructure is used to collect the parametrisation information for all ports, while delaying the actual object creation. With this technique, it is possible to generate all descriptors or entries of one kind in a single run, and placed optimally and compact into the memory allocation.

See also
turnout.hpp
node-builder.hpp
NodeLink_test
Todo:
WIP-WIP-WIP as of 10/2024 prototyping how to build and invoke render nodes /////////////////////////TICKET #1371

Definition in file weaving-pattern-builder.hpp.

#include "lib/error.hpp"
#include "lib/symbol.hpp"
#include "lib/several-builder.hpp"
#include "steam/engine/proc-id.hpp"
#include "steam/engine/turnout.hpp"
#include "steam/engine/engine-ctx.hpp"
#include "steam/engine/buffer-provider.hpp"
#include "steam/engine/buffhandle-attach.hpp"
#include "lib/test/test-helper.hpp"
#include "lib/format-string.hpp"
#include "lib/util.hpp"
#include <functional>
#include <vector>
#include <string>

Classes

struct  _ProcFun< FUN >
 Helper to pick up the parameter dimensions from the processing function. More...
 
struct  DirectFunctionInvocation< N, FUN >
 Typical base configuration for a Weaving-Pattern chain: More...
 
struct  _ProcFun< FUN >::MatchBuffArray< ARG >
 
struct  _ProcFun< FUN >::MatchBuffArray< std::array< BUF *, N > >
 
struct  PatternData< PAR, BUILD, siz >
 Recursive functional data structure to collect weaving pattern data and finally to emplace a Turnout instance into the data storage for each port, as specified by preceding builder-API invocations. More...
 
struct  PatternDataAnchor
 Data recursion end: prime the port data storage by reserving appropriate storage to hold all known Turnout elements. More...
 
struct  SimpleFunctionInvocationAdapter< MAN, FUN >
 Adapter to handle a simple yet common setup for media processing. More...
 
struct  WeavingBuilder< POL, N, FUN >
 A low-level Builder to prepare and adapt for a specific node invocation. More...
 

Typedefs

template<uint N, class FUN >
using SimpleDirectInvoke = SimpleWeavingPattern< DirectFunctionInvocation< N, FUN > >
 
template<uint siz>
using SizMark = std::integral_constant< uint, siz >
 

Functions

template<class FUN >
constexpr uint manifoldSiz ()
 Pick a suitable size for the FeedManifold to accommodate the given function. More...
 

Namespaces

 steam
 Steam-Layer implementation namespace root.
 
 steam::engine
 Lumiera's render engine core and operational control.
 

Class Documentation

◆ steam::engine::anonymous_namespace{weaving-pattern-builder.hpp}::_ProcFun::MatchBuffArray

struct steam::engine::anonymous_namespace{weaving-pattern-builder.hpp}::_ProcFun::MatchBuffArray
+ Collaboration diagram for _ProcFun< FUN >::MatchBuffArray< ARG >: