Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "trenderer.h"
Toshihiro Shimizu 890ddd
#include "trendererP.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
#include "tthreadmessage.h"
Toshihiro Shimizu 890ddd
#include "tthread.h"
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
#include "trasterimage.h"
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
#include "timagecache.h"
Toshihiro Shimizu 890ddd
#include "tstopwatch.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzBase includes
Toshihiro Shimizu 890ddd
#include "trenderresourcemanager.h"
Toshihiro Shimizu 890ddd
#include "tpredictivecachemanager.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Qt includes
Toshihiro Shimizu 890ddd
#include <qeventloop></qeventloop>
Toshihiro Shimizu 890ddd
#include <qcoreapplication></qcoreapplication>
Toshihiro Shimizu 890ddd
#include <qreadwritelock></qreadwritelock>
Toshihiro Shimizu 890ddd
#include <qreadlocker></qreadlocker>
Toshihiro Shimizu 890ddd
#include <qwritelocker></qwritelocker>
Toshihiro Shimizu 890ddd
#include <qthreadstorage></qthreadstorage>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// tcg includes
Toshihiro Shimizu 890ddd
#include "tcg/tcg_deleter_types.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//Debug
Toshihiro Shimizu 890ddd
//#define DIAGNOSTICS
Toshihiro Shimizu 890ddd
//#include "diagnostics.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <queue></queue>
Toshihiro Shimizu 890ddd
#include <functional></functional>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace TThread;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
std::vector<const *="" tfx=""> calculateSortedFxs(TRasterFxP rootFx);</const>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
//    Preliminaries - Anonymous namespace
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
//TRenderer-thread association storage. It provides TRenderers the per-thread
Toshihiro Shimizu 890ddd
//singleton status from inside a rendering process.
Toshihiro Shimizu 890ddd
QThreadStorage<trendererimp **=""> rendererStorage;</trendererimp>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//Same for render process ids.
Toshihiro Shimizu 890ddd
QThreadStorage<unsigned *="" long=""> renderIdsStorage;</unsigned>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//Interlacing functions for field-based rendering
Toshihiro Shimizu 890ddd
inline void interlace(TRasterP f0, const TRasterP &f1, int field)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (f0->getPixelSize() != f1->getPixelSize())
Toshihiro Shimizu 890ddd
		throw TException("interlace: invalid raster combination");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(f0->getBounds() == f1->getBounds());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int outWrapBytes = f0->getWrap() * f0->getPixelSize();
Toshihiro Shimizu 890ddd
	int inWrapBytes = f1->getWrap() * f1->getPixelSize();
Toshihiro Shimizu 890ddd
	int outWrapBytes2 = outWrapBytes * 2;
Toshihiro Shimizu 890ddd
	int inWrapBytes2 = inWrapBytes * 2;
Toshihiro Shimizu 890ddd
	int rowSize = f0->getLx() * f0->getPixelSize();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	f1->lock();
Toshihiro Shimizu 890ddd
	f0->lock();
Toshihiro Shimizu 890ddd
	UCHAR *rowIn = f1->getRawData();
Toshihiro Shimizu 890ddd
	UCHAR *rowOut = f0->getRawData();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (field)
Toshihiro Shimizu 890ddd
		rowIn += inWrapBytes;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int count = f0->getLy() / 2;
Toshihiro Shimizu 890ddd
	while (--count) {
Toshihiro Shimizu 890ddd
		memcpy(rowOut, rowIn, rowSize);
Toshihiro Shimizu 890ddd
		rowIn += inWrapBytes2;
Toshihiro Shimizu 890ddd
		rowOut += outWrapBytes2;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	f1->unlock();
Toshihiro Shimizu 890ddd
	f0->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
} // anonymous namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
//    Preliminaries - output rasters management
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================
Toshihiro Shimizu 890ddd
//    RasterItem
Toshihiro Shimizu 890ddd
//-------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! The RasterItem class represents a reusable output raster for rendering purposes.
Toshihiro Shimizu 890ddd
//! RasterItems are used as TRenderer's output rasters in order to avoid the overhead
Toshihiro Shimizu 890ddd
//! of allocating one raster for each rendered frame.
Toshihiro Shimizu 890ddd
//! Each frame-rendering task will lock a RasterItem as preallocated output before starting the
Toshihiro Shimizu 890ddd
//! render, therefore changing the \b RasterItem::m_busy attribute accordingly.
Toshihiro Shimizu 890ddd
//! As each frame is rendered on a separate thread, the number of RasterItems that
Toshihiro Shimizu 890ddd
//! TRenderer will allocate depends on the number of rendering threads specified to it.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! \sa RasterPool, TRenderer classes
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class RasterItem
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	string m_rasterId;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	int m_bpp;
Toshihiro Shimizu 890ddd
	bool m_busy;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	RasterItem(const TDimension &size, int bpp, bool busyFlag)
Toshihiro Shimizu 890ddd
		: m_rasterId(""), m_bpp(bpp), m_busy(busyFlag)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		TRasterP raster;
Toshihiro Shimizu 890ddd
		if (bpp == 32)
Toshihiro Shimizu 890ddd
			raster = TRaster32P(size);
Toshihiro Shimizu 890ddd
		else if (bpp == 64)
Toshihiro Shimizu 890ddd
			raster = TRaster64P(size);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			assert(false);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_rasterId = TImageCache::instance()->getUniqueId();
Toshihiro Shimizu 890ddd
		TImageCache::instance()->add(m_rasterId, TRasterImageP(raster));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	~RasterItem()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		TImageCache::instance()->remove(m_rasterId);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRasterP getRaster() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		TRasterImageP rimg = (TRasterImageP)TImageCache::instance()->get(m_rasterId, true);
Toshihiro Shimizu 890ddd
		return rimg ? rimg->getRaster() : TRasterP();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	//not implemented
Toshihiro Shimizu 890ddd
	RasterItem();
Toshihiro Shimizu 890ddd
	RasterItem(const TRaster &RasterItem);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================
Toshihiro Shimizu 890ddd
//    RasterPool
Toshihiro Shimizu 890ddd
//-------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Stores a list of RasterItems under TRenderer's requests.
Toshihiro Shimizu 890ddd
class RasterPool
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TDimension m_size;
Toshihiro Shimizu 890ddd
	int m_bpp;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	typedef std::list<rasteritem *=""> RasterRepository;</rasteritem>
Toshihiro Shimizu 890ddd
	RasterRepository m_rasterRepository;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TThread::Mutex m_repositoryLock;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	RasterPool() : m_size(-1, -1) {}
Toshihiro Shimizu 890ddd
	~RasterPool();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void setRasterSpecs(const TDimension &size, int bpp);
Toshihiro Shimizu 890ddd
	void getRasterSpecs(TDimension &size, int &bpp)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		size = m_size;
Toshihiro Shimizu 890ddd
		bpp = m_bpp;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRasterP getRaster();
Toshihiro Shimizu 890ddd
	TRasterP getRaster(const TDimension &size, int bpp);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void releaseRaster(const TRasterP &r);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void clear();
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RasterPool::clear()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QMutexLocker sl(&m_repositoryLock);
Toshihiro Shimizu 890ddd
	clearPointerContainer(m_rasterRepository);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RasterPool::setRasterSpecs(const TDimension &size, int bpp)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (size != m_size || bpp != m_bpp) {
Toshihiro Shimizu 890ddd
		m_size = size;
Toshihiro Shimizu 890ddd
		m_bpp = bpp;
Toshihiro Shimizu 890ddd
		clear();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRasterP RasterPool::getRaster(const TDimension &size, int bpp)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(size == m_size && bpp == m_bpp);
Toshihiro Shimizu 890ddd
	return getRaster();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!Returns for the first not-busy raster
Toshihiro Shimizu 890ddd
TRasterP RasterPool::getRaster()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QMutexLocker sl(&m_repositoryLock);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	RasterRepository::iterator it = m_rasterRepository.begin();
Toshihiro Shimizu 890ddd
	while (it != m_rasterRepository.end()) {
Toshihiro Shimizu 890ddd
		RasterItem *rasItem = *it;
Toshihiro Shimizu 890ddd
		if (rasItem->m_busy == false) {
Toshihiro Shimizu 890ddd
			TRasterP raster = rasItem->getRaster();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (!raster) {
Toshihiro Shimizu 890ddd
				delete rasItem;
Toshihiro Shimizu 890ddd
				m_rasterRepository.erase(it++);
Toshihiro Shimizu 890ddd
				continue;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			rasItem->m_busy = true;
Toshihiro Shimizu 890ddd
			raster->clear();
Toshihiro Shimizu 890ddd
			return raster;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		++it;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	RasterItem *rasItem = new RasterItem(m_size, m_bpp, true);
Toshihiro Shimizu 890ddd
	m_rasterRepository.push_back(rasItem);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return rasItem->getRaster();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!Cerca il raster \b r in m_rasterRepository; se lo trova setta a \b false il campo \b m_busy.
Toshihiro Shimizu 890ddd
void RasterPool::releaseRaster(const TRasterP &r)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!r)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QMutexLocker sl(&m_repositoryLock);
Toshihiro Shimizu 890ddd
	for (RasterRepository::iterator it = m_rasterRepository.begin();
Toshihiro Shimizu 890ddd
		 it != m_rasterRepository.end();
Toshihiro Shimizu 890ddd
		 ++it) {
Toshihiro Shimizu 890ddd
		RasterItem *rasItem = *it;
Toshihiro Shimizu 890ddd
		if (rasItem->getRaster()->getRawData() == r->getRawData()) {
Toshihiro Shimizu 890ddd
			assert(rasItem->m_busy);
Toshihiro Shimizu 890ddd
			rasItem->m_busy = false;
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
RasterPool::~RasterPool()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	/*if (m_rasterRepository.size())
Toshihiro Shimizu 890ddd
    TSystem::outputDebug("~RasterPool: itemCount = " + toString ((int)m_rasterRepository.size())+" (should be 0)\n");*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Release all raster items
Toshihiro Shimizu 890ddd
	clear();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
//    Internal rendering classes declaration
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=====================
Toshihiro Shimizu 890ddd
//    TRendererImp
Toshihiro Shimizu 890ddd
//---------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class TRendererImp : public TSmartObject
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	struct RenderInstanceInfos {
Toshihiro Shimizu 890ddd
		int m_canceled;
Toshihiro Shimizu 890ddd
		int m_activeTasks;
Toshihiro Shimizu 890ddd
		int m_status;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		RenderInstanceInfos()
Toshihiro Shimizu 890ddd
			: m_canceled(false), m_activeTasks(0), m_status(TRenderer::IDLE) {}
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	typedef std::vector<trenderport *=""> PortContainer;</trenderport>
Toshihiro Shimizu 890ddd
	typedef PortContainer::iterator PortContainerIterator;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QReadWriteLock m_portsLock;
Toshihiro Shimizu 890ddd
	PortContainer m_ports;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QMutex m_renderInstancesMutex;
Toshihiro Shimizu 890ddd
	std::map<unsigned long,="" renderinstanceinfos=""> m_activeInstances;</unsigned>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//! The renderer Id is a number uniquely associated with a TRenderer instance.
Toshihiro Shimizu 890ddd
	static unsigned long m_rendererIdCounter;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//! The render Id is a number uniquely associated with a render process started
Toshihiro Shimizu 890ddd
	//! with the startRendering() method.
Toshihiro Shimizu 890ddd
	static unsigned long m_renderIdCounter;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	unsigned long m_rendererId;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Executor m_executor;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool m_precomputingEnabled;
Toshihiro Shimizu 890ddd
	RasterPool m_rasterPool;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::vector<trenderresourcemanager *=""> m_managers;</trenderresourcemanager>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TAtomicVar m_undoneTasks;
Toshihiro Shimizu 890ddd
	//std::vector<qeventloop*> m_waitingLoops;</qeventloop*>
Toshihiro Shimizu 890ddd
	std::vector<bool *=""> m_waitingLoops;</bool>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRasterFxP rootFx;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//-------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRendererImp(int nThreads);
Toshihiro Shimizu 890ddd
	~TRendererImp();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void startRendering(unsigned long renderId, const std::vector<trenderer::renderdata> &renderDatas);</trenderer::renderdata>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void notifyRasterStarted(const TRenderPort::RenderData &rd);
Toshihiro Shimizu 890ddd
	void notifyRasterCompleted(const TRenderPort::RenderData &rd);
Toshihiro Shimizu 890ddd
	void notifyRasterFailure(const TRenderPort::RenderData &rd, TException &e);
Toshihiro Shimizu 890ddd
	void notifyRenderFinished(bool isCanceled = false);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void addPort(TRenderPort *port);
Toshihiro Shimizu 890ddd
	void removePort(TRenderPort *port);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void abortRendering(unsigned long renderId);
Toshihiro Shimizu 890ddd
	void stopRendering(bool waitForCompleteStop);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool hasToDie(unsigned long renderId);
Toshihiro Shimizu 890ddd
	int getRenderStatus(unsigned long renderId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void enablePrecomputing(bool on) { m_precomputingEnabled = on; }
Toshihiro Shimizu 890ddd
	bool isPrecomputingEnabled() const { return m_precomputingEnabled; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void setThreadsCount(int nThreads) { m_executor.setMaxActiveTasks(nThreads); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	inline void declareRenderStart(unsigned long renderId);
Toshihiro Shimizu 890ddd
	inline void declareRenderEnd(unsigned long renderId);
Toshihiro Shimizu 890ddd
	inline void declareFrameStart(double frame);
Toshihiro Shimizu 890ddd
	inline void declareFrameEnd(double frame);
Toshihiro Shimizu 890ddd
	inline void declareStatusStart(int renderStatus);
Toshihiro Shimizu 890ddd
	inline void declareStatusEnd(int renderStatus);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void quitWaitingLoops();
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef WIN32
Toshihiro Shimizu 890ddd
template class DVAPI TSmartPointerT<trendererimp>;</trendererimp>
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef TSmartPointerT<trendererimp> TRendererImpP;</trendererimp>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
unsigned long TRendererImp::m_rendererIdCounter = 0;
Toshihiro Shimizu 890ddd
unsigned long TRendererImp::m_renderIdCounter = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================
Toshihiro Shimizu 890ddd
//    RenderTask
Toshihiro Shimizu 890ddd
//-------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class RenderTask : public TThread::Runnable
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::vector<double> m_frames;</double>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	unsigned long m_taskId;
Toshihiro Shimizu 890ddd
	unsigned long m_renderId;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRendererImpP m_rendererImp;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TFxPair m_fx;
Toshihiro Shimizu 890ddd
	TPointD m_framePos;
Toshihiro Shimizu 890ddd
	TDimension m_frameSize;
Toshihiro Shimizu 890ddd
	TRenderSettings m_info;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool m_fieldRender, m_stereoscopic;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Mutex m_rasterGuard;
Toshihiro Shimizu 890ddd
	TTile m_tileA; //in normal and field rendering, Rendered at given frame; in stereoscopic, rendered left frame
Toshihiro Shimizu 890ddd
	TTile m_tileB; //in  field rendering, rendered at frame + 0.5; in stereoscopic, rendered right frame
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	RenderTask(unsigned long renderId, unsigned long taskId,
Toshihiro Shimizu 890ddd
			   double frame, const TRenderSettings &ri, const TFxPair &fx,
Toshihiro Shimizu 890ddd
			   const TPointD &framePos, const TDimension &frameSize,
Toshihiro Shimizu 890ddd
			   const TRendererImpP &rendererImp);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	~RenderTask() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void addFrame(double frame) { m_frames.push_back(frame); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void buildTile(TTile &tile);
Toshihiro Shimizu 890ddd
	void releaseTiles();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void onFrameStarted();
Toshihiro Shimizu 890ddd
	void onFrameCompleted();
Toshihiro Shimizu 890ddd
	void onFrameFailed(TException &e);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void preRun();
Toshihiro Shimizu 890ddd
	void run();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int taskLoad() { return 100; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void onFinished(TThread::RunnableP);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
//    Implementations
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==================
Toshihiro Shimizu 890ddd
//    TRenderer
Toshihiro Shimizu 890ddd
//------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRenderer::TRenderer(int nThread)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp = new TRendererImp(nThread); //Already adds a ref
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRenderer::TRenderer(TRendererImp *imp)
Toshihiro Shimizu 890ddd
	: m_imp(imp)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_imp)
Toshihiro Shimizu 890ddd
		m_imp->addRef();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRenderer::TRenderer(const TRenderer &r)
Toshihiro Shimizu 890ddd
	: m_imp(r.m_imp)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_imp)
Toshihiro Shimizu 890ddd
		m_imp->addRef();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRenderer::operator=(const TRenderer &r)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp = r.m_imp;
Toshihiro Shimizu 890ddd
	if (m_imp)
Toshihiro Shimizu 890ddd
		m_imp->addRef();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRenderer::~TRenderer()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_imp)
Toshihiro Shimizu 890ddd
		m_imp->release();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! The static method is intended for use inside a rendering thread only. It returns
Toshihiro Shimizu 890ddd
//! a copy of the eventual TRenderer interface installed on the thread -
Toshihiro Shimizu 890ddd
//! or an empty TRenderer if none happened to be. It can be set using the
Toshihiro Shimizu 890ddd
//! install() and uninstall() methods.
Toshihiro Shimizu 890ddd
TRenderer TRenderer::instance()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRendererImp **lData = rendererStorage.localData();
Toshihiro Shimizu 890ddd
	if (lData)
Toshihiro Shimizu 890ddd
		return TRenderer(*lData);
Toshihiro Shimizu 890ddd
	return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Returns the renderer id.
Toshihiro Shimizu 890ddd
unsigned long TRenderer::rendererId()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_imp->m_rendererId;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Returns the rendering process id currently running on the invoking
Toshihiro Shimizu 890ddd
//! thread.
Toshihiro Shimizu 890ddd
unsigned long TRenderer::renderId()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	unsigned long *lData = renderIdsStorage.localData();
Toshihiro Shimizu 890ddd
	return lData ? *lData : -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Builds and returns an id for starting a new rendering process.
Toshihiro Shimizu 890ddd
unsigned long TRenderer::buildRenderId()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return TRendererImp::m_renderIdCounter++;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Returns the renderId that will be used by the next startRendering() call.
Toshihiro Shimizu 890ddd
//! This method can be used to retrieve the renderId of a rendering instance
Toshihiro Shimizu 890ddd
//! before it is actually started - provided that no other render instance
Toshihiro Shimizu 890ddd
//! is launched inbetween.
Toshihiro Shimizu 890ddd
unsigned long TRenderer::nextRenderId()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return TRendererImp::m_renderIdCounter;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline void TRendererImp::declareRenderStart(unsigned long renderId)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//Inform the resource managers
Toshihiro Shimizu 890ddd
	for (unsigned int i = 0; i < m_managers.size(); ++i)
Toshihiro Shimizu 890ddd
		m_managers[i]->onRenderInstanceStart(renderId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Declares that the render process of passed renderId is about to start.
Toshihiro Shimizu 890ddd
void TRenderer::declareRenderStart(unsigned long renderId)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->declareRenderStart(renderId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline void TRendererImp::declareRenderEnd(unsigned long renderId)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//Inform the resource managers
Toshihiro Shimizu 890ddd
	for (int i = m_managers.size() - 1; i >= 0; --i)
Toshihiro Shimizu 890ddd
		m_managers[i]->onRenderInstanceEnd(renderId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Declares that the render process of passed renderId has ended.
Toshihiro Shimizu 890ddd
void TRenderer::declareRenderEnd(unsigned long renderId)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->declareRenderEnd(renderId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline void TRendererImp::declareFrameStart(double frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//Inform the resource managers
Toshihiro Shimizu 890ddd
	for (unsigned int i = 0; i < m_managers.size(); ++i)
Toshihiro Shimizu 890ddd
		m_managers[i]->onRenderFrameStart(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Declares that render of passed frame is about to start.
Toshihiro Shimizu 890ddd
void TRenderer::declareFrameStart(double frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->declareFrameStart(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline void TRendererImp::declareFrameEnd(double frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//Inform the resource managers
Toshihiro Shimizu 890ddd
	for (int i = m_managers.size() - 1; i >= 0; --i)
Toshihiro Shimizu 890ddd
		m_managers[i]->onRenderFrameEnd(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Declares that render of passed has ended.
Toshihiro Shimizu 890ddd
void TRenderer::declareFrameEnd(double frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->declareFrameEnd(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline void TRendererImp::declareStatusStart(int renderStatus)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//Inform the resource managers
Toshihiro Shimizu 890ddd
	for (unsigned int i = 0; i < m_managers.size(); ++i)
Toshihiro Shimizu 890ddd
		m_managers[i]->onRenderStatusStart(renderStatus);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline void TRendererImp::declareStatusEnd(int renderStatus)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//Inform the resource managers
Toshihiro Shimizu 890ddd
	for (int i = m_managers.size() - 1; i >= 0; --i)
Toshihiro Shimizu 890ddd
		m_managers[i]->onRenderStatusEnd(renderStatus);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Installs the specified render process on the invoking thread.
Toshihiro Shimizu 890ddd
void TRenderer::install(unsigned long renderId)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->addRef();
Toshihiro Shimizu 890ddd
	rendererStorage.setLocalData(new (TRendererImp *)(m_imp));
Toshihiro Shimizu 890ddd
	renderIdsStorage.setLocalData(new unsigned long(renderId));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Uninstalls any rendering process active on the invoking thread.
Toshihiro Shimizu 890ddd
void TRenderer::uninstall()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	rendererStorage.setLocalData(0);
Toshihiro Shimizu 890ddd
	renderIdsStorage.setLocalData(0);
Toshihiro Shimizu 890ddd
	m_imp->release();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRenderResourceManager *TRenderer::getManager(unsigned int id) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_imp->m_managers[id];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRenderer::enablePrecomputing(bool on)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->enablePrecomputing(on);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TRenderer::isPrecomputingEnabled() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_imp->isPrecomputingEnabled();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRenderer::setThreadsCount(int nThreads)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->setThreadsCount(nThreads);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRenderer::addPort(TRenderPort *port)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->addPort(port);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRenderer::removePort(TRenderPort *port)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->removePort(port);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
unsigned long TRenderer::startRendering(
Toshihiro Shimizu 890ddd
	double f,
Toshihiro Shimizu 890ddd
	const TRenderSettings &info,
Toshihiro Shimizu 890ddd
	const TFxPair &actualRoot)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(f >= 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::vector<renderdata> *rds = new std::vector<renderdata>;</renderdata></renderdata>
Toshihiro Shimizu 890ddd
	rds->push_back(RenderData(f, info, actualRoot));
Toshihiro Shimizu 890ddd
	return startRendering(rds);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Queues a rendering event in the main event loop.
Toshihiro Shimizu 890ddd
//! NOTE: The passed pointer is owned by the TRenderer after it is submitted for rendering -
Toshihiro Shimizu 890ddd
//! do not delete it later.
Toshihiro Shimizu 890ddd
unsigned long TRenderer::startRendering(const std::vector<renderdata> *renderDatas)</renderdata>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (renderDatas->empty()) {
Toshihiro Shimizu 890ddd
		delete renderDatas;
Toshihiro Shimizu 890ddd
		return -1;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Build a new render Id
Toshihiro Shimizu 890ddd
	unsigned long renderId = m_imp->m_renderIdCounter++;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRendererStartInvoker::StartInvokerRenderData srd;
Toshihiro Shimizu 890ddd
	srd.m_renderId = renderId;
Toshihiro Shimizu 890ddd
	srd.m_renderDataVector = renderDatas;
Toshihiro Shimizu 890ddd
	TRendererStartInvoker::instance()->emitStartRender(m_imp, srd);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return renderId;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRenderer::abortRendering(unsigned long renderId)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->abortRendering(renderId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRenderer::stopRendering(bool waitForCompleteStop)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->stopRendering(waitForCompleteStop);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TRenderer::isAborted(unsigned long renderId) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_imp->hasToDie(renderId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TRenderer::getRenderStatus(unsigned long renderId) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_imp->getRenderStatus(renderId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=====================
Toshihiro Shimizu 890ddd
//    TRendererImp
Toshihiro Shimizu 890ddd
//---------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRendererImp::TRendererImp(int nThreads)
Toshihiro Shimizu 890ddd
	: m_executor(), m_undoneTasks(), m_rendererId(m_rendererIdCounter++), m_precomputingEnabled(true)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_executor.setMaxActiveTasks(nThreads);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::vector<trenderresourcemanagergenerator *=""> &generators =</trenderresourcemanagergenerator>
Toshihiro Shimizu 890ddd
		TRenderResourceManagerGenerator::generators(false);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//May be adopted by other TRenderers from now on.
Toshihiro Shimizu 890ddd
	addRef();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	rendererStorage.setLocalData(new (TRendererImp *)(this));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	unsigned int i;
Toshihiro Shimizu 890ddd
	for (i = 0; i < generators.size(); ++i) {
Toshihiro Shimizu 890ddd
		TRenderResourceManager *manager = (*generators[i])();
Toshihiro Shimizu 890ddd
		if (manager)
Toshihiro Shimizu 890ddd
			m_managers.push_back(manager);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	rendererStorage.setLocalData(0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRendererImp::~TRendererImp()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	rendererStorage.setLocalData(new (TRendererImp *)(this));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
	for (i = m_managers.size() - 1; i >= 0; --i)
Toshihiro Shimizu 890ddd
		if (m_managers[i]->renderHasOwnership())
Toshihiro Shimizu 890ddd
			delete m_managers[i];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	rendererStorage.setLocalData(0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRendererImp::addPort(TRenderPort *port)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QWriteLocker sl(&m_portsLock);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	PortContainerIterator it = std::find(m_ports.begin(), m_ports.end(), port);
Toshihiro Shimizu 890ddd
	if (it == m_ports.end())
Toshihiro Shimizu 890ddd
		m_ports.push_back(port);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRendererImp::removePort(TRenderPort *port)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QWriteLocker sl(&m_portsLock);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	PortContainerIterator it = std::find(m_ports.begin(), m_ports.end(), port);
Toshihiro Shimizu 890ddd
	if (it != m_ports.end())
Toshihiro Shimizu 890ddd
		m_ports.erase(it);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TRendererImp::hasToDie(unsigned long renderId)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QMutexLocker sl(&m_renderInstancesMutex);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::map<unsigned long,="" renderinstanceinfos="">::iterator it = m_activeInstances.find(renderId);</unsigned>
Toshihiro Shimizu 890ddd
	assert(it != m_activeInstances.end());
Toshihiro Shimizu 890ddd
	return it == m_activeInstances.end() ? true : it->second.m_canceled;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TRendererImp::getRenderStatus(unsigned long renderId)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QMutexLocker sl(&m_renderInstancesMutex);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::map<unsigned long,="" renderinstanceinfos="">::iterator it = m_activeInstances.find(renderId);</unsigned>
Toshihiro Shimizu 890ddd
	assert(it != m_activeInstances.end());
Toshihiro Shimizu 890ddd
	return it == m_activeInstances.end() ? true : it->second.m_status;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRendererImp::abortRendering(unsigned long renderId)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QMutexLocker sl(&m_renderInstancesMutex);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::map<unsigned long,="" renderinstanceinfos="">::iterator it = m_activeInstances.find(renderId);</unsigned>
Toshihiro Shimizu 890ddd
	if (it != m_activeInstances.end())
Toshihiro Shimizu 890ddd
		it->second.m_canceled = true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRendererImp::stopRendering(bool waitForCompleteStop)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QMutexLocker sl(&m_renderInstancesMutex);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		//Tasks already stop rendering on their own when they don't find their render ids here.
Toshihiro Shimizu 890ddd
		std::map<unsigned long,="" renderinstanceinfos="">::iterator it;</unsigned>
Toshihiro Shimizu 890ddd
		for (it = m_activeInstances.begin(); it != m_activeInstances.end(); ++it)
Toshihiro Shimizu 890ddd
			it->second.m_canceled = true;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (waitForCompleteStop && m_undoneTasks > 0) {
Toshihiro Shimizu 890ddd
		//Sometimes, QEventLoop suddenly stops processing slots (especially those notifications
Toshihiro Shimizu 890ddd
		//from active rendering instances) - therefore resulting in a block of the application.
Toshihiro Shimizu 890ddd
		//I've not figured out why (#QTBUG-11649?) - but substituting with a plain while
Toshihiro Shimizu 890ddd
		//seems to do the trick...
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*QEventLoop eventLoop;
Toshihiro Shimizu 890ddd
    m_waitingLoops.push_back(&eventLoop);
Toshihiro Shimizu 890ddd
    eventLoop.exec();*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		bool loopQuit = false;
Toshihiro Shimizu 890ddd
		m_waitingLoops.push_back(&loopQuit);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		sl.unlock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		while (!loopQuit)
Toshihiro Shimizu 890ddd
			QCoreApplication::processEvents(QEventLoop::AllEvents | QEventLoop::WaitForMoreEvents);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRendererImp::quitWaitingLoops()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//Make the stopRendering waiting loops quit
Toshihiro Shimizu 890ddd
	while (!m_waitingLoops.empty()) {
Toshihiro Shimizu 890ddd
		//rendererImp->m_waitingLoops.back()->quit();
Toshihiro Shimizu 890ddd
		*m_waitingLoops.back() = true;
Toshihiro Shimizu 890ddd
		m_waitingLoops.pop_back();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRendererImp::notifyRasterStarted(const TRenderPort::RenderData &rd)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//Since notifications may trigger port removals, we always work on a copy of the ports
Toshihiro Shimizu 890ddd
	//vector.
Toshihiro Shimizu 890ddd
	TRendererImp::PortContainer portsCopy;
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		QReadLocker sl(&m_portsLock);
Toshihiro Shimizu 890ddd
		portsCopy = m_ports;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (PortContainerIterator it = portsCopy.begin(); it != portsCopy.end(); ++it)
Toshihiro Shimizu 890ddd
		(*it)->onRenderRasterStarted(rd);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRendererImp::notifyRasterCompleted(const TRenderPort::RenderData &rd)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRendererImp::PortContainer portsCopy;
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		QReadLocker sl(&m_portsLock);
Toshihiro Shimizu 890ddd
		portsCopy = m_ports;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(rd.m_rasA);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (PortContainerIterator it = portsCopy.begin(); it != portsCopy.end(); ++it)
Toshihiro Shimizu 890ddd
		(*it)->onRenderRasterCompleted(rd);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRendererImp::notifyRasterFailure(const TRenderPort::RenderData &rd, TException &e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRendererImp::PortContainer portsCopy;
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		QReadLocker sl(&m_portsLock);
Toshihiro Shimizu 890ddd
		portsCopy = m_ports;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (PortContainerIterator it = portsCopy.begin(); it != portsCopy.end(); ++it)
Toshihiro Shimizu 890ddd
		(*it)->onRenderFailure(rd, e);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRendererImp::notifyRenderFinished(bool isCanceled)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRendererImp::PortContainer portsCopy;
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		QReadLocker sl(&m_portsLock);
Toshihiro Shimizu 890ddd
		portsCopy = m_ports;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	auto sortedFxs = calculateSortedFxs(rootFx);
Toshihiro Shimizu 890ddd
	for (auto fx : sortedFxs) {
Toshihiro Shimizu 890ddd
		if (fx)
Toshihiro Shimizu 890ddd
			const_cast<tfx *="">(fx)->callEndRenderHandler();</tfx>
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (PortContainerIterator it = portsCopy.begin(); it != portsCopy.end(); ++it)
Toshihiro Shimizu 890ddd
		(*it)->onRenderFinished();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//====================
Toshihiro Shimizu 890ddd
//    TRenderPort
Toshihiro Shimizu 890ddd
//--------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRenderPort::TRenderPort()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRenderPort::~TRenderPort()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!Setta \b m_renderArea a \b area e pulisce l'istanza corrente di \b RasterPool.
Toshihiro Shimizu 890ddd
void TRenderPort::setRenderArea(const TRectD &area)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_renderArea = area;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!Ritorna \b m_renderArea.
Toshihiro Shimizu 890ddd
TRectD &TRenderPort::getRenderArea()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_renderArea;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================
Toshihiro Shimizu 890ddd
//    RenderTask
Toshihiro Shimizu 890ddd
//-------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
RenderTask::RenderTask(unsigned long renderId, unsigned long taskId,
Toshihiro Shimizu 890ddd
					   double frame, const TRenderSettings &ri, const TFxPair &fx,
Toshihiro Shimizu 890ddd
					   const TPointD &framePos, const TDimension &frameSize,
Toshihiro Shimizu 890ddd
					   const TRendererImpP &rendererImp)
Toshihiro Shimizu 890ddd
	: m_renderId(renderId), m_taskId(taskId), m_info(ri), m_fx(fx), m_frameSize(frameSize), m_framePos(framePos), m_rendererImp(rendererImp), m_fieldRender(ri.m_fieldPrevalence != TRenderSettings::NoField), m_stereoscopic(ri.m_stereoscopic)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_frames.push_back(frame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Connect the onFinished slot
Toshihiro Shimizu 890ddd
	connect(this, SIGNAL(finished(TThread::RunnableP)), this, SLOT(onFinished(TThread::RunnableP)));
Toshihiro Shimizu 890ddd
	connect(this, SIGNAL(exception(TThread::RunnableP)), this, SLOT(onFinished(TThread::RunnableP)));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//The shrink info is currently reversed to the settings'affine. Shrink info in the TRenderSettings
Toshihiro Shimizu 890ddd
	//is no longer supported.
Toshihiro Shimizu 890ddd
	m_info.m_shrinkX = m_info.m_shrinkY = 1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RenderTask::preRun()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRectD geom(m_framePos, TDimensionD(m_frameSize.lx, m_frameSize.ly));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_fx.m_frameA)
Toshihiro Shimizu 890ddd
		m_fx.m_frameA->dryCompute(geom, m_frames[0], m_info);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_fx.m_frameB)
Toshihiro Shimizu 890ddd
		m_fx.m_frameB->dryCompute(geom, m_fieldRender ? m_frames[0] + 0.5 : m_frames[0], m_info);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RenderTask::run()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//Retrieve the task's frame
Toshihiro Shimizu 890ddd
	assert(!m_frames.empty());
Toshihiro Shimizu 890ddd
	double t = m_frames[0];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_rendererImp->hasToDie(m_renderId)) {
Toshihiro Shimizu 890ddd
		TException e("Render task aborted");
Toshihiro Shimizu 890ddd
		onFrameFailed(e);
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Install the renderer in current thread
Toshihiro Shimizu 890ddd
	rendererStorage.setLocalData(new (TRendererImp *)(m_rendererImp.getPointer()));
Toshihiro Shimizu 890ddd
	renderIdsStorage.setLocalData(new unsigned long(m_renderId));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Inform the managers of frame start
Toshihiro Shimizu 890ddd
	m_rendererImp->declareFrameStart(t);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	auto sortedFxs = calculateSortedFxs(m_fx.m_frameA);
Toshihiro Shimizu 890ddd
	for (auto fx : sortedFxs) {
Toshihiro Shimizu 890ddd
		if (fx)
Toshihiro Shimizu 890ddd
			const_cast<tfx *="">(fx)->callStartRenderFrameHandler(&m_info, t);</tfx>
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	try {
Toshihiro Shimizu 890ddd
		onFrameStarted();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TStopWatch::global(8).start();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (!m_fieldRender && !m_stereoscopic) {
Toshihiro Shimizu 890ddd
			//Common case - just build the first tile
Toshihiro Shimizu 890ddd
			buildTile(m_tileA);
Toshihiro Shimizu 890ddd
			/*-- 通常はここがFxのレンダリング処理 --*/
Toshihiro Shimizu 890ddd
			m_fx.m_frameA->compute(m_tileA, t, m_info);
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			assert(!(m_stereoscopic && m_fieldRender));
Toshihiro Shimizu 890ddd
			//Field rendering  or stereoscopic case
Toshihiro Shimizu 890ddd
			if (m_stereoscopic) {
Toshihiro Shimizu 890ddd
				buildTile(m_tileA);
Toshihiro Shimizu 890ddd
				m_fx.m_frameA->compute(m_tileA, t, m_info);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				buildTile(m_tileB);
Toshihiro Shimizu 890ddd
				m_fx.m_frameB->compute(m_tileB, t, m_info);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			//if fieldPrevalence, Decide the rendering frames depending on field prevalence
Toshihiro Shimizu 890ddd
			else if (m_info.m_fieldPrevalence == TRenderSettings::EvenField) {
Toshihiro Shimizu 890ddd
				buildTile(m_tileA);
Toshihiro Shimizu 890ddd
				m_fx.m_frameA->compute(m_tileA, t, m_info);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				buildTile(m_tileB);
Toshihiro Shimizu 890ddd
				m_fx.m_frameB->compute(m_tileB, t + 0.5, m_info);
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				buildTile(m_tileB);
Toshihiro Shimizu 890ddd
				m_fx.m_frameA->compute(m_tileB, t, m_info);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				buildTile(m_tileA);
Toshihiro Shimizu 890ddd
				m_fx.m_frameB->compute(m_tileA, t + 0.5, m_info);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TStopWatch::global(8).stop();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		onFrameCompleted();
Toshihiro Shimizu 890ddd
	} catch (TException &e) {
Toshihiro Shimizu 890ddd
		onFrameFailed(e);
Toshihiro Shimizu 890ddd
	} catch (...) {
Toshihiro Shimizu 890ddd
		TException ex("Unknown render exception");
Toshihiro Shimizu 890ddd
		onFrameFailed(ex);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Inform the managers of frame end
Toshihiro Shimizu 890ddd
	m_rendererImp->declareFrameEnd(t);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Uninstall the renderer from current thread
Toshihiro Shimizu 890ddd
	rendererStorage.setLocalData(0);
Toshihiro Shimizu 890ddd
	renderIdsStorage.setLocalData(0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (auto fx : sortedFxs) {
Toshihiro Shimizu 890ddd
		if (fx)
Toshihiro Shimizu 890ddd
			const_cast<tfx *="">(fx)->callEndRenderFrameHandler(&m_info, t);</tfx>
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RenderTask::buildTile(TTile &tile)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	tile.m_pos = m_framePos;
Toshihiro Shimizu 890ddd
	tile.setRaster(m_rendererImp->m_rasterPool.getRaster(m_frameSize, m_info.m_bpp));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RenderTask::releaseTiles()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_rendererImp->m_rasterPool.releaseRaster(m_tileA.getRaster());
Toshihiro Shimizu 890ddd
	m_tileA.setRaster(TRasterP());
Toshihiro Shimizu 890ddd
	if (m_fieldRender || m_stereoscopic) {
Toshihiro Shimizu 890ddd
		m_rendererImp->m_rasterPool.releaseRaster(m_tileB.getRaster());
Toshihiro Shimizu 890ddd
		m_tileB.setRaster(TRasterP());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RenderTask::onFrameStarted()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRenderPort::RenderData rd(m_frames, m_info, 0, 0, m_renderId, m_taskId);
Toshihiro Shimizu 890ddd
	m_rendererImp->notifyRasterStarted(rd);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RenderTask::onFrameCompleted()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRasterP rasA(m_tileA.getRaster());
Toshihiro Shimizu 890ddd
	TRasterP rasB(m_tileB.getRaster());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_fieldRender) {
Toshihiro Shimizu 890ddd
		assert(rasB);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		double t = m_frames[0];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int f = (m_info.m_fieldPrevalence == TRenderSettings::EvenField) ? 0 : 1;
Toshihiro Shimizu 890ddd
		interlace(rasA, rasB, f);
Toshihiro Shimizu 890ddd
		rasB = TRasterP();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRenderPort::RenderData rd(m_frames, m_info, rasA, rasB, m_renderId, m_taskId);
Toshihiro Shimizu 890ddd
	m_rendererImp->notifyRasterCompleted(rd);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RenderTask::onFrameFailed(TException &e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//TRasterP evenRas(m_evenTile.getRaster());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRenderPort::RenderData rd(m_frames, m_info, m_tileA.getRaster(), m_tileB.getRaster(), m_renderId, m_taskId);
Toshihiro Shimizu 890ddd
	m_rendererImp->notifyRasterFailure(rd, e);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RenderTask::onFinished(TThread::RunnableP)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRendererImp *rendererImp = m_rendererImp.getPointer();
Toshihiro Shimizu 890ddd
	--rendererImp->m_undoneTasks;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Tiles release back to the Raster Pool happens in the main thread, after all possible
Toshihiro Shimizu 890ddd
	//signals emitted in the onFrameCompleted/Failed notifications have been resolved, thus
Toshihiro Shimizu 890ddd
	//ensuring that no other rendering thread owns the rasters before them.
Toshihiro Shimizu 890ddd
	releaseTiles();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Update the render instance status
Toshihiro Shimizu 890ddd
	bool instanceExpires = false;
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		QMutexLocker sl(&rendererImp->m_renderInstancesMutex);
Toshihiro Shimizu 890ddd
		std::map<unsigned long,="" trendererimp::renderinstanceinfos="">::iterator it =</unsigned>
Toshihiro Shimizu 890ddd
			rendererImp->m_activeInstances.find(m_renderId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (it != rendererImp->m_activeInstances.end() && (--it->second.m_activeTasks) <= 0) {
Toshihiro Shimizu 890ddd
			instanceExpires = true;
Toshihiro Shimizu 890ddd
			rendererImp->m_activeInstances.erase(m_renderId);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//If the render instance has just expired
Toshihiro Shimizu 890ddd
	if (instanceExpires) {
Toshihiro Shimizu 890ddd
		/*-- キャンセルされた場合はm_overallRenderedRegionの更新をしない --*/
Toshihiro Shimizu 890ddd
		bool isCanceled = (m_info.m_isCanceled && *m_info.m_isCanceled);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Inform the render ports
Toshihiro Shimizu 890ddd
		rendererImp->notifyRenderFinished(isCanceled);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//NOTE: This slot is currently invoked on the main thread. It could eventually be
Toshihiro Shimizu 890ddd
		//invoked directly on rendering threads, specifying the Qt::DirectConnection option -
Toshihiro Shimizu 890ddd
		//but probably there would be no real advantage in doing so...
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Temporarily install the renderer in current thread
Toshihiro Shimizu 890ddd
		rendererStorage.setLocalData(new (TRendererImp *)(rendererImp));
Toshihiro Shimizu 890ddd
		renderIdsStorage.setLocalData(new unsigned long(m_renderId));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Inform the resource managers
Toshihiro Shimizu 890ddd
		rendererImp->declareRenderEnd(m_renderId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Uninstall the temporary
Toshihiro Shimizu 890ddd
		rendererStorage.setLocalData(0);
Toshihiro Shimizu 890ddd
		renderIdsStorage.setLocalData(0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		rendererImp->m_rasterPool.clear(); // Isn't this misplaced? Should be in the block
Toshihiro Shimizu 890ddd
	}									   // below...
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//If no rendering task (of this or other render instances) is found...
Toshihiro Shimizu 890ddd
	if (rendererImp->m_undoneTasks == 0) {
Toshihiro Shimizu 890ddd
		QMutexLocker sl(&rendererImp->m_renderInstancesMutex);
Toshihiro Shimizu 890ddd
		rendererImp->quitWaitingLoops();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
//    Tough Stuff
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRendererStartInvoker::emitStartRender(
Toshihiro Shimizu 890ddd
	TRendererImp *renderer, StartInvokerRenderData rd)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	renderer->addRef();
Toshihiro Shimizu 890ddd
	Q_EMIT startRender(renderer, rd);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRendererStartInvoker::doStartRender(
Toshihiro Shimizu 890ddd
	TRendererImp *renderer, StartInvokerRenderData rd)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	renderer->startRendering(rd.m_renderId, *rd.m_renderDataVector);
Toshihiro Shimizu 890ddd
	renderer->release();
Toshihiro Shimizu 890ddd
	delete rd.m_renderDataVector;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
std::vector<const *="" tfx=""> calculateSortedFxs(TRasterFxP rootFx)</const>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::map<const *="" *,="" std::set<const="" tfx="">> E; /* 辺の情報 */</const>
Toshihiro Shimizu 890ddd
	std::set<const *="" tfx=""> Sources;					/* 入次数0のノード群 */</const>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::queue<const *="" tfx=""> Q;</const>
Toshihiro Shimizu 890ddd
	Q.push(rootFx.getPointer());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	E[rootFx.getPointer()] = std::set<const *="" tfx="">();</const>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	while (!Q.empty()) {
Toshihiro Shimizu 890ddd
		const TFx *vptr = Q.front();
Toshihiro Shimizu 890ddd
		Q.pop();
Toshihiro Shimizu 890ddd
		if (!vptr) {
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/* 繋がっている入力ポートの先の Fx を訪問する
Toshihiro Shimizu 890ddd
           入力ポートが無ければ終了 */
Toshihiro Shimizu 890ddd
		int portCount = vptr->getInputPortCount();
Toshihiro Shimizu 890ddd
		if (portCount < 1) {
Toshihiro Shimizu 890ddd
			Sources.insert(vptr);
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		for (int i = 0; i < portCount; i++) {
Toshihiro Shimizu 890ddd
			TFxPort *port = vptr->getInputPort(i);
Toshihiro Shimizu 890ddd
			if (!port) {
Toshihiro Shimizu 890ddd
				continue;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			TFxP u = port->getFx();
Toshihiro Shimizu 890ddd
			const TFx *uptr = u.getPointer();
Toshihiro Shimizu 890ddd
			if (E.count(uptr) == 0) {
Toshihiro Shimizu 890ddd
				E[uptr] = std::set<const *="" tfx="">();</const>
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			if (E[uptr].count(vptr) == 0) {
Toshihiro Shimizu 890ddd
				E[uptr].insert(vptr);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			Q.push(uptr);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* トポロジカルソート */
Toshihiro Shimizu 890ddd
	std::set<const *="" tfx=""> visited;</const>
Toshihiro Shimizu 890ddd
	std::vector<const *="" tfx=""> L;</const>
Toshihiro Shimizu 890ddd
	std::function<void(const *)="" tfx=""> visit = [&visit, &visited, &E, &L](const TFx *fx) {</void(const>
Toshihiro Shimizu 890ddd
		if (visited.count(fx))
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		visited.insert(fx);
Toshihiro Shimizu 890ddd
		auto edge = E[fx];
Toshihiro Shimizu 890ddd
		for (auto i = edge.cbegin(); i != edge.cend(); i++) {
Toshihiro Shimizu 890ddd
			visit(*i);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		L.insert(L.begin(), fx);
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
	for (auto i = E.cbegin(); i != E.cend(); i++) {
Toshihiro Shimizu 890ddd
		visit(i->first);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return L;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRendererImp::startRendering(unsigned long renderId, const vector<trenderer::renderdata> &renderDatas)</trenderer::renderdata>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	rootFx = renderDatas.front().m_fxRoot.m_frameA;
Toshihiro Shimizu 890ddd
	int T = renderDatas.size();
Toshihiro Shimizu 890ddd
	for (int z = 0; z < T; z++) {
Toshihiro Shimizu 890ddd
		auto sortedFxs = calculateSortedFxs(renderDatas[z].m_fxRoot.m_frameA);
Toshihiro Shimizu 890ddd
		if (z == 0) {
Toshihiro Shimizu 890ddd
			for (auto fx : sortedFxs) {
Toshihiro Shimizu 890ddd
				if (fx)
Toshihiro Shimizu 890ddd
					const_cast<tfx *="">(fx)->callStartRenderHandler();</tfx>
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	struct locals {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		static inline void setStorage(TRendererImp *imp, unsigned long renderId)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			rendererStorage.setLocalData(new (TRendererImp *)(imp));
Toshihiro Shimizu 890ddd
			renderIdsStorage.setLocalData(new unsigned long(renderId));
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		static inline void clearStorage()
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			rendererStorage.setLocalData(0);
Toshihiro Shimizu 890ddd
			renderIdsStorage.setLocalData(0);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		static inline void declareStatusStart(
Toshihiro Shimizu 890ddd
			TRendererImp *imp, TRenderer::RenderStatus status,
Toshihiro Shimizu 890ddd
			RenderInstanceInfos *renderInfos)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			renderInfos->m_status = status;
Toshihiro Shimizu 890ddd
			imp->declareStatusStart(status);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//-----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		struct InstanceDeclaration {
Toshihiro Shimizu 890ddd
			TRendererImp *m_imp;
Toshihiro Shimizu 890ddd
			unsigned long m_renderId;
Toshihiro Shimizu 890ddd
			bool m_rollback;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			InstanceDeclaration(TRendererImp *imp, unsigned long renderId)
Toshihiro Shimizu 890ddd
				: m_imp(imp), m_renderId(renderId), m_rollback(true) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			~InstanceDeclaration()
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
				if (m_rollback) {
Toshihiro Shimizu 890ddd
					QMutexLocker locker(&m_imp->m_renderInstancesMutex);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					m_imp->m_activeInstances.erase(m_renderId);
Toshihiro Shimizu 890ddd
					if (m_imp->m_undoneTasks == 0)
Toshihiro Shimizu 890ddd
						m_imp->quitWaitingLoops();
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			void commit() { m_rollback = false; }
Toshihiro Shimizu 890ddd
		};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		struct StorageDeclaration {
Toshihiro Shimizu 890ddd
			StorageDeclaration(TRendererImp *imp, unsigned long renderId)
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
				setStorage(imp, renderId);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			~StorageDeclaration()
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
				clearStorage();
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		struct RenderDeclaration {
Toshihiro Shimizu 890ddd
			TRendererImp *m_imp;
Toshihiro Shimizu 890ddd
			unsigned long m_renderId;
Toshihiro Shimizu 890ddd
			bool m_rollback;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			RenderDeclaration(TRendererImp *imp, unsigned long renderId)
Toshihiro Shimizu 890ddd
				: m_imp(imp), m_renderId(renderId), m_rollback(true)
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
				imp->declareRenderStart(renderId);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			~RenderDeclaration()
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
				if (m_rollback)
Toshihiro Shimizu 890ddd
					m_imp->declareRenderEnd(m_renderId);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			void commit() { m_rollback = false; }
Toshihiro Shimizu 890ddd
		};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		struct StatusDeclaration {
Toshihiro Shimizu 890ddd
			TRendererImp *m_imp;
Toshihiro Shimizu 890ddd
			TRenderer::RenderStatus m_status;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			StatusDeclaration(TRendererImp *imp, TRenderer::RenderStatus status,
Toshihiro Shimizu 890ddd
							  RenderInstanceInfos *renderInfos)
Toshihiro Shimizu 890ddd
				: m_imp(imp), m_status(status)
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
				declareStatusStart(imp, status, renderInfos);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			~StatusDeclaration()
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
				m_imp->declareStatusEnd(m_status);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		};
Toshihiro Shimizu 890ddd
	}; // locals
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//DIAGNOSTICS_CLEAR;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
	//    Preliminary initializations
Toshihiro Shimizu 890ddd
	//----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Calculate the overall render area - sum of all render ports' areas
Toshihiro Shimizu 890ddd
	TRectD renderArea;
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		QReadLocker sl(&m_portsLock);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (PortContainerIterator it = m_ports.begin(); it != m_ports.end(); ++it)
Toshihiro Shimizu 890ddd
			renderArea += (*it)->getRenderArea();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const TRenderSettings &info(renderDatas[0].m_info);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Extract the render geometry
Toshihiro Shimizu 890ddd
	TPointD pos(renderArea.getP00());
Toshihiro Shimizu 890ddd
	TDimension frameSize(tceil(renderArea.getLx()), tceil(renderArea.getLy()));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRectD camBox(TPointD(pos.x / info.m_shrinkX, pos.y / info.m_shrinkY),
Toshihiro Shimizu 890ddd
				  TDimensionD(frameSize.lx, frameSize.ly));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Refresh the raster pool specs
Toshihiro Shimizu 890ddd
	m_rasterPool.setRasterSpecs(frameSize, info.m_bpp);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Set a temporary active instance count - so that hasToDie(renderId) returns false
Toshihiro Shimizu 890ddd
	RenderInstanceInfos *renderInfos;
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		QMutexLocker locker(&m_renderInstancesMutex);
Toshihiro Shimizu 890ddd
		renderInfos = &m_activeInstances[renderId];
Toshihiro Shimizu 890ddd
		renderInfos->m_activeTasks = 1;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	locals::InstanceDeclaration instanceDecl(this, renderId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
	//    Clustering - Render Tasks creation
Toshihiro Shimizu 890ddd
	//----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::vector<rendertask *=""> tasksVector;</rendertask>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	struct TasksCleaner {
Toshihiro Shimizu 890ddd
		std::vector<rendertask *=""> &m_tasksVector;</rendertask>
Toshihiro Shimizu 890ddd
		~TasksCleaner()
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			std::for_each(m_tasksVector.begin(), m_tasksVector.end(),
Toshihiro Shimizu 890ddd
						  tcg::deleter<rendertask>());</rendertask>
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} tasksCleaner = {tasksVector};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	unsigned long tasksIdCounter = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::map<std::string, *="" rendertask=""> clusters;</std::string,>
Toshihiro Shimizu 890ddd
	std::vector<trenderer::renderdata>::const_iterator it;</trenderer::renderdata>
Toshihiro Shimizu 890ddd
	std::map<std::string, *="" rendertask="">::iterator jt;</std::string,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (it = renderDatas.begin(); it != renderDatas.end(); ++it) {
Toshihiro Shimizu 890ddd
		// Check for user cancels
Toshihiro Shimizu 890ddd
		if (hasToDie(renderId))
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// Build the frame's description alias
Toshihiro Shimizu 890ddd
		const TRenderer::RenderData &renderData = *it;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*--- カメラサイズ (LevelAutoやノイズで使用する) ---*/
Toshihiro Shimizu 890ddd
		TRenderSettings rs = renderData.m_info;
Toshihiro Shimizu 890ddd
		rs.m_cameraBox = camBox;
Toshihiro Shimizu 890ddd
		/*--- 途中でPreview計算がキャンセルされたときのフラグ ---*/
Toshihiro Shimizu 890ddd
		rs.m_isCanceled = &renderInfos->m_canceled;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TRasterFxP fx = renderData.m_fxRoot.m_frameA;
Toshihiro Shimizu 890ddd
		assert(fx);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		double frame = renderData.m_frame;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		string alias = fx->getAlias(frame, renderData.m_info);
Toshihiro Shimizu 890ddd
		if (renderData.m_fxRoot.m_frameB)
Toshihiro Shimizu 890ddd
			alias = alias + renderData.m_fxRoot.m_frameB->getAlias(frame, renderData.m_info);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// Search the alias among stored clusters - and store the frame
Toshihiro Shimizu 890ddd
		jt = clusters.find(alias);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (jt == clusters.end()) {
Toshihiro Shimizu 890ddd
			RenderTask *newTask = new RenderTask(
Toshihiro Shimizu 890ddd
				renderId, tasksIdCounter++,
Toshihiro Shimizu 890ddd
				renderData.m_frame, rs, renderData.m_fxRoot,
Toshihiro Shimizu 890ddd
				pos, frameSize, this);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			tasksVector.push_back(newTask);
Toshihiro Shimizu 890ddd
			clusters.insert(std::make_pair(alias, newTask));
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			jt->second->addFrame(renderData.m_frame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// Call processEvents to make the GUI reactive.
Toshihiro Shimizu 890ddd
		QCoreApplication::instance()->processEvents();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Release the clusters - we'll just need the tasks vector from now on
Toshihiro Shimizu 890ddd
	clusters.clear();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::vector<rendertask *="">::iterator kt, kEnd = tasksVector.end();</rendertask>
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		// Install TRenderer on current thread before proceeding
Toshihiro Shimizu 890ddd
		locals::StorageDeclaration storageDecl(this, renderId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// Inform the resource managers
Toshihiro Shimizu 890ddd
		locals::RenderDeclaration renderDecl(this, renderId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
		//    Precomputing
Toshihiro Shimizu 890ddd
		//----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (m_precomputingEnabled) {
Toshihiro Shimizu 890ddd
			//Set current maxTileSize for cache manager precomputation
Toshihiro Shimizu 890ddd
			const TRenderSettings &rs = renderDatas[0].m_info;
Toshihiro Shimizu 890ddd
			TPredictiveCacheManager::instance()->setMaxTileSize(rs.m_maxTileSize);
Toshihiro Shimizu 890ddd
			TPredictiveCacheManager::instance()->setBPP(rs.m_bpp);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			//Perform the first precomputing run - fx usages declaration
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
				locals::StatusDeclaration firstrunDecl(this, TRenderer::FIRSTRUN, renderInfos);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				for (kt = tasksVector.begin(); kt != kEnd; ++kt) {
Toshihiro Shimizu 890ddd
					if (hasToDie(renderId))
Toshihiro Shimizu 890ddd
						return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					(*kt)->preRun();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					//NOTE: Thread-specific data must be temporarily uninstalled before
Toshihiro Shimizu 890ddd
					//processing events (which may redefine the thread data).
Toshihiro Shimizu 890ddd
					locals::clearStorage();
Toshihiro Shimizu 890ddd
					QCoreApplication::instance()->processEvents();
Toshihiro Shimizu 890ddd
					locals::setStorage(this, renderId);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			//Pass to the TESTRUN status - this one should faithfully reproduce
Toshihiro Shimizu 890ddd
			//the actual COMPUTING status
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
				locals::StatusDeclaration testrunDecl(this, TRenderer::TESTRUN, renderInfos);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				for (kt = tasksVector.begin(); kt != kEnd; ++kt) {
Toshihiro Shimizu 890ddd
					if (hasToDie(renderId))
Toshihiro Shimizu 890ddd
						return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					(*kt)->preRun();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					//NOTE: Thread-specific data must be temporarily uninstalled before
Toshihiro Shimizu 890ddd
					//processing events (which may redefine the thread data).
Toshihiro Shimizu 890ddd
					locals::clearStorage();
Toshihiro Shimizu 890ddd
					QCoreApplication::instance()->processEvents();
Toshihiro Shimizu 890ddd
					locals::setStorage(this, renderId);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
		//    Render
Toshihiro Shimizu 890ddd
		//----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		locals::declareStatusStart(this, TRenderer::COMPUTING, renderInfos);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// Update the tasks counts
Toshihiro Shimizu 890ddd
		m_undoneTasks += tasksVector.size();
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			QMutexLocker locker(&m_renderInstancesMutex);
Toshihiro Shimizu 890ddd
			renderInfos->m_activeTasks = tasksVector.size();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		renderDecl.commit(); // Declarations are taken over by render tasks
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	instanceDecl.commit(); // Same here
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Launch the render
Toshihiro Shimizu 890ddd
	for (kt = tasksVector.begin(); kt != tasksVector.end(); ++kt)
Toshihiro Shimizu 890ddd
		m_executor.addTask(*kt);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	tasksVector.clear(); // Prevent tasks destruction by TasksCleaner
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRenderer::initialize()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRendererStartInvoker::instance();
Toshihiro Shimizu 890ddd
}