226 lines
8.1 KiB
C
226 lines
8.1 KiB
C
|
|
||
|
|
||
|
#ifndef TRENDERER_INCLUDED
|
||
|
#define TRENDERER_INCLUDED
|
||
|
|
||
|
#include "trasterfx.h"
|
||
|
|
||
|
#undef DVAPI
|
||
|
#undef DVVAR
|
||
|
#ifdef TFX_EXPORTS
|
||
|
#define DVAPI DV_EXPORT_API
|
||
|
#define DVVAR DV_EXPORT_VAR
|
||
|
#else
|
||
|
#define DVAPI DV_IMPORT_API
|
||
|
#define DVVAR DV_IMPORT_VAR
|
||
|
#endif
|
||
|
|
||
|
//=========================================================
|
||
|
|
||
|
// Forward declarations
|
||
|
|
||
|
class TRenderer;
|
||
|
class TRendererImp;
|
||
|
class TException;
|
||
|
class TRenderSettings;
|
||
|
class TRasterFxP;
|
||
|
class TFxCacheManager;
|
||
|
class TRenderResourceManager;
|
||
|
class TRenderResourceManagerGenerator;
|
||
|
|
||
|
class TFxPair
|
||
|
{
|
||
|
public:
|
||
|
TRasterFxP m_frameA, m_frameB;
|
||
|
TFxPair() : m_frameA(), m_frameB() {}
|
||
|
TFxPair(const TRasterFxP &frameA, TRasterFxP &frameB)
|
||
|
: m_frameA(frameA), m_frameB(frameB) {}
|
||
|
};
|
||
|
|
||
|
//typedef std::pair<TRasterFxP, TRasterFxP> TFxPair;
|
||
|
|
||
|
//=========================================================
|
||
|
|
||
|
//====================
|
||
|
// TRenderPort
|
||
|
//--------------------
|
||
|
|
||
|
//! The TRenderPort class acts as a spatially-declared listener to a TRenderer instance.
|
||
|
//! TRenderPorts are the formally supported receivers of TRenderer's activity notifications;
|
||
|
//! they provide some basic pure virtual members that are appropriately invoked by the TRenderer
|
||
|
//! when an associated interesting render event takes place.
|
||
|
|
||
|
class DVAPI TRenderPort
|
||
|
{
|
||
|
TRectD m_renderArea;
|
||
|
|
||
|
public:
|
||
|
struct RenderData;
|
||
|
|
||
|
TRenderPort();
|
||
|
virtual ~TRenderPort();
|
||
|
|
||
|
void setRenderArea(const TRectD &area);
|
||
|
TRectD &getRenderArea();
|
||
|
|
||
|
virtual void onRenderRasterStarted(const RenderData &renderData) {}
|
||
|
virtual void onRenderRasterCompleted(const RenderData &renderData) {}
|
||
|
virtual void onRenderFailure(const RenderData &renderData, TException &e) {}
|
||
|
virtual void onRenderFinished(bool isCanceled = false) {}
|
||
|
};
|
||
|
|
||
|
//=========================================================
|
||
|
|
||
|
//================================
|
||
|
// TRenderPort::RenderData
|
||
|
//--------------------------------
|
||
|
|
||
|
//! This storage struct contains the elementary data necessary to identify a cluster of identical
|
||
|
//! rendered frames from TRenderer. In order to avoid recalculation of identical frames during a
|
||
|
//! render process, they are merged in one 'equivalence cluster' of which only one representant is
|
||
|
//! rendered; the m_frames member stores each frame of such cluster. The associated raster is stored
|
||
|
//! in the m_ras member. Additional returned infos include the TRenderSettings under which the frames
|
||
|
//! were rendered, and unique identification vars.
|
||
|
|
||
|
struct TRenderPort::RenderData {
|
||
|
std::vector<double> m_frames; //!< Frames this output represents
|
||
|
TRenderSettings m_info; //!< Output settings description
|
||
|
TRasterP m_rasA, m_rasB; //!< The output images; m_rasB is not empty only for interlacacing and stereoscopic.
|
||
|
unsigned long m_renderId; //!< Identifier of the rendering session this output belongs to
|
||
|
unsigned long m_taskId; //!< Task identifier in the rendering session. Starts at 0, preserves
|
||
|
//!< the original submission order except for cluster equivalence.
|
||
|
|
||
|
RenderData() : m_renderId((unsigned long)-1), m_taskId((unsigned long)-1) {}
|
||
|
RenderData(const std::vector<double> &frames,
|
||
|
const TRenderSettings &info, const TRasterP &rasA, const TRasterP &rasB,
|
||
|
unsigned long renderId, unsigned long taskId)
|
||
|
: m_frames(frames), m_info(info), m_rasA(rasA), m_rasB(rasB), m_renderId(renderId), m_taskId(taskId) {}
|
||
|
};
|
||
|
|
||
|
//=================================================================================
|
||
|
|
||
|
//=========================================================
|
||
|
//
|
||
|
// TRenderer
|
||
|
//
|
||
|
//---------------------------------------------------------
|
||
|
|
||
|
//! The TRenderer class provides the core operative interface to the Toonz
|
||
|
//! rendering library.
|
||
|
|
||
|
//! The TRenderer's main purpose is that of invoking a render process on a group
|
||
|
//! of separate threads through the \b startRendering() methods. After this is done,
|
||
|
//! the activated process communicates with any TRenderPort previously set through
|
||
|
//! the \b addPort() method in order to notify the render status.
|
||
|
//! The rendering process can be interrupted with the stopRendering() method, which
|
||
|
//! makes all rendering threads quit safely at the most appropriate time; the more
|
||
|
//! specific abortRendering() method may be used to terminate a render process id in case
|
||
|
//! more than one process is running.
|
||
|
//! \n \n
|
||
|
//! Technically, this class is an \a interface to the actual rendering class,
|
||
|
//! which remains in background. This means that users have no necessity of maintaining the
|
||
|
//! TRenderer instance alive as a render process is running. We may, for example,
|
||
|
//! create a TRenderer, set its properties, launch the render, and release the TRenderer
|
||
|
//! instance immediately after as the internal rendering class will continue working on.
|
||
|
//! TRenderers may therefore be copied and assigned freely to refer an already existing
|
||
|
//! internal rendering instance. These are created anew only using the default
|
||
|
//! TRenderer(int) constructor.
|
||
|
//! \n \n
|
||
|
//! On the other hand, TRenderer's lifespan may last longer than that of a single rendering
|
||
|
//! process. This is especially useful when it is known that multiple rendering processes share
|
||
|
//! some common resources (likewise, intermediate cache results), which can be maintained
|
||
|
//! in the same internal TRenderer representation for later use.
|
||
|
//! \n \n
|
||
|
//! Some final notes about methods dealing with Toonz's lower-level API. Direct invocation
|
||
|
//! of rendering functions, such as the TRasterFx::compute() method, is discouraged. Further
|
||
|
//! improvements of the TRenderer's API will eventually make the need for these calls obsolete. However,
|
||
|
//! we've implemented the possibilty to rely on TRenderer's management support even in those cases -
|
||
|
//! it can be done by declaring the render process' interesting events through the apposite <a> declare..() <\a>
|
||
|
//! methods and invoking install() and uninstall() on each rendering thread you'll raise
|
||
|
//! for the process.
|
||
|
|
||
|
class DVAPI TRenderer
|
||
|
{
|
||
|
TRendererImp *m_imp;
|
||
|
|
||
|
friend class TRenderResourceManagerGenerator;
|
||
|
TRenderResourceManager *getManager(unsigned int id) const;
|
||
|
|
||
|
public:
|
||
|
//! The RenderData struct contains the frame specifics to supply for a
|
||
|
//! TRenderer::startRendering() call.
|
||
|
struct RenderData {
|
||
|
double m_frame;
|
||
|
TRenderSettings m_info;
|
||
|
TFxPair m_fxRoot; //The second of pair is used for field interlacing or stereoscopic render.
|
||
|
|
||
|
RenderData(double frame, const TRenderSettings &info, const TFxPair &fxRoot)
|
||
|
: m_frame(frame), m_info(info), m_fxRoot(fxRoot) {}
|
||
|
};
|
||
|
|
||
|
public:
|
||
|
TRenderer(int nThread = 1);
|
||
|
TRenderer(TRendererImp *);
|
||
|
~TRenderer();
|
||
|
|
||
|
TRenderer(const TRenderer &);
|
||
|
void operator=(const TRenderer &);
|
||
|
|
||
|
operator bool() const { return m_imp; }
|
||
|
|
||
|
void addPort(TRenderPort *port);
|
||
|
void removePort(TRenderPort *port);
|
||
|
|
||
|
unsigned long startRendering(const std::vector<TRenderer::RenderData> *renderDatas);
|
||
|
unsigned long startRendering(double f, const TRenderSettings &info, const TFxPair &actualRoot);
|
||
|
|
||
|
void abortRendering(unsigned long renderId);
|
||
|
void stopRendering(bool waitForCompleteStop = false);
|
||
|
|
||
|
void enablePrecomputing(bool on);
|
||
|
bool isPrecomputingEnabled() const;
|
||
|
|
||
|
void setThreadsCount(int nThreads);
|
||
|
|
||
|
static TRenderer instance();
|
||
|
|
||
|
unsigned long rendererId();
|
||
|
static unsigned long renderId();
|
||
|
static unsigned long nextRenderId();
|
||
|
|
||
|
//-----------------------------------------
|
||
|
|
||
|
//Render instance properties
|
||
|
|
||
|
enum RenderStatus { IDLE = 0x0,
|
||
|
FIRSTRUN = 0x1,
|
||
|
TESTRUN = 0x2,
|
||
|
COMPUTING = 0x4 };
|
||
|
int getRenderStatus(unsigned long renderId) const;
|
||
|
bool isAborted(unsigned long renderId) const;
|
||
|
|
||
|
//-----------------------------------------
|
||
|
|
||
|
// To install the TRenderer on lower-level rendering invocations
|
||
|
static unsigned long buildRenderId();
|
||
|
|
||
|
void declareRenderStart(unsigned long renderId);
|
||
|
void declareRenderEnd(unsigned long renderId);
|
||
|
|
||
|
void declareFrameStart(double frame);
|
||
|
void declareFrameEnd(double frame);
|
||
|
|
||
|
void install(unsigned long renderId);
|
||
|
void uninstall();
|
||
|
|
||
|
// Be sure that this method is called at least once before a rendering driven by a working thread
|
||
|
// (the TRendererStartInvoker singleton must be referred first by a thread that survives, e.g. the main thread)
|
||
|
static void initialize();
|
||
|
};
|
||
|
|
||
|
//-------------------------------------------------------------------------------
|
||
|
|
||
|
typedef std::vector<TRenderer::RenderData> RenderDataVector;
|
||
|
|
||
|
#endif
|