This is the result of an requirement analysis, based on the current (better) understanding of ''render job invocation'' * the `InvocationInstanceID` is @deprecated, because rather a data based hash is required * instead, two free parameters are introduced, with a meaning defined by the specific `JobFunctor` * notably the functor for rendering, the `RenderInvocation´ can use these for the exit node and an output context **Note**: the C-structs for the `job` are no longer considered an interface (and will be remoulded into an internal detail of the dispatcher)
133 lines
4.1 KiB
C++
133 lines
4.1 KiB
C++
/*
|
||
JobTicket - execution plan for render jobs
|
||
|
||
Copyright (C)
|
||
2012, Hermann Vosseler <Ichthyostega@web.de>
|
||
|
||
**Lumiera** 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. See the file COPYING for further details.
|
||
|
||
* *****************************************************************/
|
||
|
||
|
||
/** @file job-ticket.cpp
|
||
** Implementation details of preparing and performing job invocations.
|
||
**
|
||
** @todo WIP-WIP-WIP 3/2012
|
||
** @see Job
|
||
**
|
||
*/
|
||
|
||
|
||
#include "steam/engine/job-ticket.hpp"
|
||
#include "vault/gear/nop-job-functor.hpp"
|
||
#include "lib/hash-combine.hpp"
|
||
#include "lib/depend.hpp"
|
||
#include "lib/util.hpp"
|
||
|
||
|
||
namespace steam {
|
||
namespace engine {
|
||
|
||
using vault::gear::Job;
|
||
using vault::gear::JobClosure;
|
||
using lib::HashVal;
|
||
using lib::unConst;
|
||
using lib::time::FSecs;
|
||
|
||
|
||
namespace { // Details...
|
||
lib::Depend<vault::gear::NopJobFunctor> nopFunctor;
|
||
|
||
/* ======== hard wired =================*/
|
||
const FSecs JOB_MINIMUM_RUNTIME{1,1000};
|
||
|
||
} // (END) Details...
|
||
|
||
|
||
|
||
|
||
|
||
/** special »do nothing« JobTicket marker */
|
||
JobTicket JobTicket::NOP{}; ////////////////////////////////////////////////////////////////////TICKET #725 : do we actually need that for the final data structure?
|
||
|
||
JobTicket::JobTicket()
|
||
: provision_{nopFunctor(), ExitNode::NIL}
|
||
{ }
|
||
|
||
|
||
/**
|
||
* Generate a render job to invoke the render network configuration
|
||
* as defined and backing this JobTicket. The generated job descriptor record
|
||
* will include a specific InvocationInstanceID, which factors in the nominal
|
||
* frame time, but also the specific backing render configuration.
|
||
* The actual implementation of the job functionality will be delegated
|
||
* to the JobClosure, which was set up for this Segment and JobTiket
|
||
* after the last Builder run created this part of the render network.
|
||
*/
|
||
Job
|
||
JobTicket::createJobFor (Time nominalTime)
|
||
{
|
||
if (this->empty())
|
||
{ //////////////////////////////////////////////////////////////////////////////////TICKET #1296 : can we get away just with a do-nothing functor?
|
||
return Job(nopFunctor(), InvocationInstanceID(), nominalTime);
|
||
}
|
||
else
|
||
{
|
||
REQUIRE (this->isValid(), "Attempt to generate render job for incomplete or unspecified render plan.");
|
||
JobClosure& functor = static_cast<JobClosure&> (unConst(provision_.jobFunctor)); ////////////////TICKET #1287 : fix actual interface down to JobFunctor (after removing C structs)
|
||
InvocationInstanceID invoKey{timeHash (nominalTime, provision_.invocationSeed)};
|
||
|
||
return Job(functor, invoKey, nominalTime);
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Use observed runtime values of past job invocations to guess a sensible bound
|
||
* for the calculation time to expect for next invocation.
|
||
* @todo 6/2023 placeholder implementation with hard wired values in ExitNode
|
||
*/
|
||
Duration
|
||
JobTicket::getExpectedRuntime()
|
||
{
|
||
if (this->empty())
|
||
return Duration{JOB_MINIMUM_RUNTIME};
|
||
else
|
||
{
|
||
REQUIRE (isValid(), "Attempt to determine timings for incomplete or unspecified render plan.");
|
||
return provision_.exitNode.getUpperBoundRuntime();
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Tag the precomputed invocation ID with the nominal frame time
|
||
*/
|
||
InvocationInstanceID
|
||
JobTicket::timeHash (Time nominalTime, InvocationInstanceID const& seed)
|
||
{
|
||
InvocationInstanceID res{seed};
|
||
HashVal timeMark = res.part.t;
|
||
lib::hash::combine (timeMark, hash_value (nominalTime));
|
||
res.part.t = timeMark;
|
||
return res;
|
||
}
|
||
|
||
|
||
/**
|
||
* Helper for tests: verify the given invocation parameters match this JobTicket.
|
||
*/
|
||
bool
|
||
JobTicket::verifyInstance (JobFunctor& functor, InvocationInstanceID const& invoKey, Time nominalTime) const
|
||
{
|
||
return util::isSameObject (provision_.jobFunctor, functor)
|
||
and invoKey == timeHash (nominalTime, provision_.invocationSeed);
|
||
}
|
||
|
||
|
||
|
||
|
||
}} // namespace steam::engine
|