WIP working towards a solution for generating frame location sequences

..the Idea is to rely on some kind of service,
to break the cyclic dependency with the Dispatcher.
But I seem unable to find a natural location or
concept to house that service.
This commit is contained in:
Fischlurch 2012-10-06 02:29:19 +02:00
parent ce5b940d39
commit 3300d00cc8
5 changed files with 77 additions and 16 deletions

View file

@ -60,6 +60,8 @@ namespace engine {
ModelPort modelPort_;
uint channel_;
/////TODO need storage for the continuation
FrameCoord relativeFrameLocation (TimeAnchor refPoint, uint frameCountOffset);
JobBuilder& establishNextJobs (TimeAnchor refPoint);
@ -70,8 +72,9 @@ namespace engine {
{
UNIMPLEMENTED ("how to represent the closure for defining and scheduling jobs");
////////TODO: use a closure based on the JobTicket (which can be accessed through the dispatcher backlink)
//////////// Because this closure is what backs the IterSource, it needs to have a reliable storage though.
////////TODO: use a closure based on FrameCoord plus a back-reference to the Dispatcher.
//////////// Thus actually we need a *generator* for a sequence of FrameCoord
//////////// This generator is then wrapped up into an evaluation-Monad (IterExplorer)
}
};
@ -83,8 +86,9 @@ namespace engine {
JobTicket& accessJobTicket (FrameCoord const&);
protected:
virtual FrameCoord locateFrameNext (uint frameCountOffset, TimeAnchor refPoint) =0;
protected:
virtual FrameCoord locateRelative (FrameCoord, uint frameCountOffset) =0;
virtual FrameCoord locateRelative (TimeAnchor, uint frameCountOffset) =0;
};

View file

@ -90,5 +90,33 @@ namespace engine {
/**
* Facility for producing a sequence of FrameCoord.
* This interface describes the essence of generating
* a series of frame locations, which is necessary for
* planning render jobs. To implement it, actually some
* kind of \link lib::time::Quantiser frame grid \endlink
* is necessary -- in practice we use a Dispatcher, which is
* backed by the Segmentation (i.e. the render nodes network).
*/
class FrameSequencer
: boost::noncopyable
{
public:
virtual ~FrameSequencer(); ///< this is an interface
FrameCoord
getNextFrame (FrameCoord refPoint)
{
return locateRelative (refPoint, +1 );
}
protected:
virtual FrameCoord locateRelative (FrameCoord, uint frameCountOffset) =0;
};
}} // namespace proc::engine
#endif

View file

@ -240,7 +240,8 @@ namespace engine {
*/
class PlanningStepGenerator
{
engine::TimeAnchor anchor_;
engine::FrameSequencer* locationGenerator_;
engine::FrameCoord current_;
public:
typedef JobPlanning value_type;
@ -252,6 +253,12 @@ namespace engine {
PlanningStepGenerator(engine::TimeAnchor startPoint)
: anchor_(startPoint)
{ }
//////////////////////////////////////////////////////////////TODO actually we need two distinct services
//////////////////////////////////////////////////////////////TODO - getting the next FrameCoord
//////////////////////////////////////////////////////////////TODO - getting the JobTicket for this location
//////////////////////////////////////////////////////////////TODO Actually, the Dispatcher would provide exactly those services,
//////////////////////////////////////////////////////////////TODO but depending on the Dispatcher constitutes a cyclic dependency.
//////////////////////////////////////////////////////////////TODO There seems to be a problem hidden somewhere in this design.
/* === Iteration control API for IterStateWrapper== */
@ -287,6 +294,28 @@ namespace engine {
/**
* This iterator represents a pipeline to pull planned jobs from.
* For dispatching individual frame jobs for rendering, this pipeline is
* generated and internally wired such as to interpret the render node definitions.
*
* \par Explanation of the structure
*
* The JobPlanningSequence is constructed from several nested layers of functionality
* - for the client, it is an iterator, exposing a sequence of JobPlanning elements
* - a JobPlanning element allows to add a frame render job to the scheduler
* - actually such an element can even be \em converted directly into a Job (descriptor)
* - the sequence of such JobPlanning elements (that is, the iterator) is called a PlanningState,
* since evaluating this iterator effectively drives the process of job planning ahead
* - this planning process is \em implemented as a recursive evaluation and exploration of
* a tree of prerequisites; these prerequisites are defined in the JobTicket datastructure
* - there is an underlying grid of evaluation starting points, each corresponding to a
* single frame. Typically, each frame generates at least two jobs, one for fetching
* data, and one for the actual calculations. Depending on the actual render network,
* a lot of additional jobs might be necessary
* - this basic frame grid is generated by the PlanningStepGenerator, which is
* effectively backed by the Dispatcher and thus the render node model.
*
*
* @todo 6/12 WIP-WIP-WIP how to prepare jobs for scheduling
*/
class JobPlanningSequence

View file

@ -242,6 +242,9 @@ using util::isnil;
/////////////////////TODO problem is: we need an JobTicket::Prerequisite instance, where the descriptor points to "self" (this JobTicket)
/////////////////////TODO : but this instance needs to reside somewhere at a safe location, since we want to embed an LinkedElements-iterator
/////////////////////TODO : into the ExplorationState. And obviously we do not want that instance in each JobTicket, only in the top level ones
/////////////////////TODO : on second thought -- better have a top-level entry point to the evaluation of a frame
/////////////////////TODO basically this inherits from Prerequisite and lives somehow in the dispatcher-table or segment
}

View file

@ -46,17 +46,14 @@ namespace engine {
// class ExitNode;
/**
* The process of playback or rendering is a continued series of
* exploration and evaluation. The outline of what needs to be calculated
* is determined continuously, proceeding in chunks of evaluation.
* Each of these continued partial evaluations establishes a distinct
* anchor or breaking point in time: everything before this point
* is settled and planned thus far. Effectively, this time point
* acts as a <i>evaluation closure</i>, to be picked up on the
* next partial evaluation. More specifically, the TimeAnchor
* closure is the definitive binding between the abstract
* logical time of the session timeline, and the real
* wall-clock time forming the deadline for rendering.
* The process of playback or rendering is a continued series of exploration and evaluation.
* The outline of what needs to be calculated is determined continuously, proceeding in
* chunks of evaluation. Each of these continued partial evaluations establishes a distinct
* anchor or breaking point in time: everything before this point can be considered settled
* and planned thus far. Effectively, this time point acts as a <i>evaluation closure</i>,
* to be picked up on the next partial evaluation. More specifically, the TimeAnchor closure
* is the definitive binding between the abstract logical time of the session timeline, and
* the real wall-clock time forming the deadline for rendering.
*
* \par internals
* The time anchor associates a nominal time, defined on the implicit time grid