settle and implement some long standing concerns regarding #920

- what the dispatch operation actally is
- where the deadlines are established
This commit is contained in:
Fischlurch 2013-11-18 02:25:27 +01:00
parent a640283e4c
commit 4ef1883c04
11 changed files with 94 additions and 28 deletions

View file

@ -58,10 +58,12 @@ namespace engine {
bool
CalcPlanContinuation::verify (Time nominalTime, InvocationInstanceID invoKey) const
{
UNIMPLEMENTED ("verify the planning coordinates");
return false;
return timings_.isValid()
&& Time::MIN < nominalTime && nominalTime < Time::MAX
&& nominalTime == timings_.getFrameStartAt (invoKey.frameNumber);
}
size_t
CalcPlanContinuation::hashOfInstance (InvocationInstanceID invoKey) const
{

View file

@ -59,7 +59,6 @@ namespace engine {
*/
class CalcPlanContinuation
: public JobClosure
, boost::noncopyable
{
play::Timings const& timings_;

View file

@ -31,6 +31,23 @@ namespace proc {
namespace engine {
/** */
FrameCoord
DispatchTable::locateRelative (FrameCoord const&, FrameCnt frameOffset)
{
UNIMPLEMENTED ("real implementation of the core dispatch operation");
}
bool
DispatchTable::isEndOfChunk (FrameCnt, ModelPort port)
{
UNIMPLEMENTED ("determine when to finish a planning chunk");
}
JobTicket&
DispatchTable::accessJobTicket (ModelPort, TimeValue nominalTime)
{
UNIMPLEMENTED ("hook into the real implementation of the model backbone / segmentation");
}

View file

@ -44,6 +44,14 @@ namespace engine {
class DispatchTable
: public Dispatcher
{
/* ==== Dispatcher interface ==== */
FrameCoord locateRelative (FrameCoord const&, FrameCnt frameOffset);
bool isEndOfChunk (FrameCnt, ModelPort port);
JobTicket& accessJobTicket (ModelPort, TimeValue nominalTime);
protected:
/** timerange covered by this RenderGraph */
TimeSpan segment_;

View file

@ -38,15 +38,24 @@ namespace engine {
Dispatcher::JobBuilder
Dispatcher::onCalcStream (ModelPort modelPort, uint channel)
{
UNIMPLEMENTED ("build coordinates of frame to render");
JobBuilder builder = {this, modelPort,channel};
return builder;
}
/** */
FrameCoord
Dispatcher::JobBuilder::relativeFrameLocation (TimeAnchor& refPoint, uint frameCountOffset)
Dispatcher::JobBuilder::relativeFrameLocation (TimeAnchor& refPoint, FrameCnt frameOffset)
{
UNIMPLEMENTED ("build coordinates of frame to render");
FrameCoord frame;
frame.absoluteNominalTime = refPoint;
frame.absoluteFrameNumber = refPoint.getStartFrame();
frame.absoluteRealDeadline = refPoint.establishDeadlineFor (frameOffset);
frame.modelPort = this->modelPort_;
frame.channelNr = this->channel_;
ENSURE (frame.isDefined());
return dispatcher_->locateRelative (frame, frameOffset);
}

View file

@ -75,18 +75,18 @@ namespace engine {
{
struct JobBuilder
{
Dispatcher& dispatcher_;
Dispatcher* dispatcher_;
ModelPort modelPort_;
uint channel_;
FrameCoord relativeFrameLocation (TimeAnchor& refPoint, uint frameCountOffset =0);
FrameCoord relativeFrameLocation (TimeAnchor& refPoint, FrameCnt frameCountOffset =0);
JobPlanningSequence
establishNextJobs (TimeAnchor& refPoint)
{
return JobPlanningSequence(
relativeFrameLocation(refPoint),
dispatcher_);
*dispatcher_);
}
};
@ -98,10 +98,14 @@ namespace engine {
protected:
virtual FrameCoord locateRelative (FrameCoord, uint frameCountOffset) =0;
virtual FrameCoord locateRelative (TimeAnchor, uint frameCountOffset) =0; //////////TODO is this really an interface operation, or just a convenience shortcut?
/** core dispatcher operation: based on the coordinates of a reference point,
* establish binding frame number, nominal time and real (wall clock) deadline.
* @return new FrameCoord record (copy), with the nominal time, frame number
* and deadline adjusted in accordance to the given frame offset.
*/
virtual FrameCoord locateRelative (FrameCoord const&, FrameCnt frameOffset) =0;
virtual bool isEndOfChunk (FrameCnt, ModelPort port) =0;
virtual bool isEndOfChunk (FrameCnt, ModelPort port) =0;
////////TODO: API-1 = just get next frame, without limitations .... CHECK
////////TODO: API-2 = query limitation of planning chunk .... CHECK

View file

@ -73,6 +73,7 @@ namespace engine {
FrameCoord()
: absoluteNominalTime(Time::NEVER)
, absoluteFrameNumber(std::numeric_limits<FrameCnt>::max())
, absoluteRealDeadline(Time::NEVER)
, modelPort() // unconnected
, channelNr(0)
{ }
@ -113,7 +114,7 @@ namespace engine {
}
protected:
virtual FrameCoord locateRelative (FrameCoord, uint frameCountOffset) =0;
virtual FrameCoord locateRelative (FrameCoord const&, FrameCnt frameOffset) =0;
};

View file

@ -157,14 +157,32 @@ namespace engine {
}
/** define the deadline for a grid point relative to this reference point.
* Since a TimeAnchor represents the definitive link between nominal time
* and ongoing wall clock time, and since all of the current output stream
* related timing information is available -- including the engine and the
* output latency -- this is the place to do the final decision.
* @param frameOffset frame count offset relative to this TimeAnchor point
* @return the latest real absolute wall clock time at which this frame
* has to be delivered to the OutputSlot. This deadline is exclusive,
* i.e. time < deadline is required.
*/
Time
establishDeadlineFor (FrameCnt frameOffset)
{
return this->relatedRealTime_
+ timings_.getRealOffset(frameOffset);
}
/** convenience shortcut, employing the deadline calculation in relation
* to current wall clock time */
Offset
remainingRealTimeFor (FrameCoord plannedFrame)
//////////////////////////////////////////////////TODO break this into two sensible operations, using the deadline from the FrameCoord
{
FrameCnt frameOffset = plannedFrame.absoluteFrameNumber - anchorPoint_;
return Offset(this->relatedRealTime_
+ timings_.getRealOffset(frameOffset)
- RealClock::now());
return Offset(RealClock::now()
,establishDeadlineFor(frameOffset));
}
};

View file

@ -78,6 +78,20 @@ namespace play {
Timings Timings::DISABLED(FrameRate::HALTED);
/** @internal typically invoked from assertions */
bool
Timings::isValid() const
{
return bool(grid_)
&& (( (ASAP == playbackUrgency || NICE == playbackUrgency)
&& Time::NEVER == scheduledDelivery)
||
(TIMEBOUND == playbackUrgency
&& Time::MIN < scheduledDelivery && scheduledDelivery < Time::MAX)
);
}
Time
Timings::getOrigin() const
{

View file

@ -180,6 +180,10 @@ namespace play {
bool isOriginalSpeed() const;
/** Consistency self-check */
bool isValid() const;
//////////////TODO further accessor functions here
Timings constrainedBy (Timings additionalConditions);

View file

@ -80,17 +80,7 @@ namespace test {
/* == mock Dispatcher implementation == */
FrameCoord
locateFrameNext (uint frameCountOffset, TimeAnchor refPoint)
{
UNIMPLEMENTED ("dummy implementation of the core dispatch operation");
}
FrameCoord
locateRelative (FrameCoord, uint frameCountOffset)
{
UNIMPLEMENTED ("dummy implementation of the core dispatch operation");
}
FrameCoord
locateRelative (TimeAnchor, uint frameCountOffset)
locateRelative (FrameCoord const&, FrameCnt frameOffset)
{
UNIMPLEMENTED ("dummy implementation of the core dispatch operation");
}