Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tfxattributes.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "trenderer.h"
Toshihiro Shimizu 890ddd
#include "tcacheresource.h"
Toshihiro Shimizu 890ddd
#include "tcacheresourcepool.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tpassivecachemanager.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//#define USE_SQLITE_HDPOOL
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/* PRACTICAL EXPLANATION:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
The TPassiveCacheManager's purpose is that of storing render results from a specified set of fx nodes.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
When an fx is passed to the manager to be cached, a structure of type FxData is generated for the fx.
Toshihiro Shimizu 890ddd
It is stored inside the manager and ASSOCIATED to the fx through an INDEX key - this one being stored
Toshihiro Shimizu 890ddd
inside the fx data.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
In particular, the FxData instances contain a PERSISTANT identifier (passiveCacheId) that is saved inside
Toshihiro Shimizu 890ddd
the scene data, a flag specifying the cache status of the fx node (like, if it's enabled or not), and
Toshihiro Shimizu 890ddd
a description of the schematic dag below the associated fx.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Now, when a resource request is made to the TPassiveCacheManager, it checks the FxData about the generating
Toshihiro Shimizu 890ddd
fx - if it contains the flag specifying that it must be cached, a resource is allocated (if not already
Toshihiro Shimizu 890ddd
present), a reference to it is stored, and finally the resource is returned.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
References to interesting resources are stored in a TABLE container, indexed by "rendering context" and
Toshihiro Shimizu 890ddd
fx. A rendering context is hereby intended as a SEQUENCE of render processes where the next render of the
Toshihiro Shimizu 890ddd
sequence is assumed to REPLACE the previous one.
Toshihiro Shimizu 890ddd
We therefore have one context for the swatch viewer, one for File>Preview, one for the Preview Fx of each
Toshihiro Shimizu 890ddd
fx node, and one context for EACH FRAME of the sceneviewer preview (one frame is not supposed to replace
Toshihiro Shimizu 890ddd
another in that case).
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
The table is in practice a map of maps (a kind of 'comb' structure) - where the primary map is associated
Toshihiro Shimizu 890ddd
by render context and the secondary ones by fx. This mean that we are able to address and iterate contexts
Toshihiro Shimizu 890ddd
easier than fxs. Values of the table are set of resources.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
RESOURCES MAINTENANCE POLICY:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
As resources use a concrete amount of memory for storage, they should be kept in the resources table only
Toshihiro Shimizu 890ddd
for the time they are supposedly useful to the user. There are 2 ways of dealing with this issue.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
1) First, we can track scene changes and eliminate those resources that will no longer be accessed due to the
Toshihiro Shimizu 890ddd
applied change. This happens, for example, when a level is being drawn, fxs are inserted, moved or removed.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Level changes are delivered immediately to the ::invalidateLevel(..) method, which removes all resources
Toshihiro Shimizu 890ddd
whose name contains the level's name. Unfortunately, this cannot be done at frame precision (ie you cannot
Toshihiro Shimizu 890ddd
invalidate a single frame of the level, but ALL the level).
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Xsheet (schematic) changes are tracked through the schematic node description stored inside the FxData structure.
Toshihiro Shimizu 890ddd
Once one such change happens, all resources update their description - if that changes, the associated resources
Toshihiro Shimizu 890ddd
are released.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
The same schematic description is used to track and release resources affected by changes on a downstream fx's
Toshihiro Shimizu 890ddd
parameters.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
There are also scene changes that are inherently hard to track or intercept. For example, pegbar affines changes,
Toshihiro Shimizu 890ddd
fx nodes expressions referencing data not directly connected to the fx, and possibly others. These are currently
Toshihiro Shimizu 890ddd
NOT handled by direct tracking.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
2) As there may be resources which escape the resource control by point (1), we need some extra control
Toshihiro Shimizu 890ddd
policies. Here they are:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
We assume that the pool of resources accessed by render processes of a same render context should be CONSTANT
Toshihiro Shimizu 890ddd
IF NO SCENE CHANGE HAPPENS. In other words, we are guessing that only those resources used in the last
Toshihiro Shimizu 890ddd
rendering will be used in the next. Resources accessed in a render but NOT in the next (of the same context)
Toshihiro Shimizu 890ddd
are released.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
However, it could be that the sequence of render processes from a context is halted from a certain moment on.
Toshihiro Shimizu 890ddd
In that case, it is a waste to keep the resources accessed by its last render if no new render will ever take
Toshihiro Shimizu 890ddd
place. We then assume further that a rendering context can be ENABLED or DISABLED - when a render context is
Toshihiro Shimizu 890ddd
enabled, it will most likely have a next render - and therefore can keep its resources in memory.
Toshihiro Shimizu 890ddd
Once a context is DISABLED, it moves the resources to a TEMPORARY context.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Resources in the temporary context are those 'on their way for release'. They will be KEPT only if the
Toshihiro Shimizu 890ddd
next rendering - INDEPENDENTLY FROM THE RENDER CONTEXT - requires them (in this case, they will be adopted
Toshihiro Shimizu 890ddd
by the new context). This is necessary since context disables typically happen when a preview window closes.
Toshihiro Shimizu 890ddd
It is not unfrequent that users close the preview window, modify the scene, and then restore the preview.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
CONSIDERATIONS:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
* The File>Render generates NO CONTEXT - and therefore does NOT PASSIVELY CACHE RESOURCES, since it cannot be
Toshihiro Shimizu 890ddd
  stated whether it is in the 'enabled' or 'disabled' state. It could be considered coherent with what tcomposer
Toshihiro Shimizu 890ddd
  does, by the way...
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
* Our resources maintenance policy ensures that the memory usage should be stable over time - that is, no
Toshihiro Shimizu 890ddd
  useless resource is kept in memory.
Toshihiro Shimizu 890ddd
  Of course, it is possibly more restrictive than what the user may desire. For example, closing 2 preview
Toshihiro Shimizu 890ddd
  windows marks their resources for deletion, but only one of the two restored previews will keep its
Toshihiro Shimizu 890ddd
  resources intact...
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*****************************************************************************************
Toshihiro Shimizu 890ddd
//    Preliminaries
Toshihiro Shimizu 890ddd
//*****************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//  Local stuff - inlines
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
inline QRect toQRect(const TRect &r) { return QRect(r.x0, r.y0, r.getLx(), r.getLy()); }
Toshihiro Shimizu 890ddd
inline TRect toTRect(const QRect &r) { return TRect(r.left(), r.top(), r.right(), r.bottom()); }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFx *TPassiveCacheManager::getNotAllowingAncestor(TFx *fx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//Trace all output ports
Toshihiro Shimizu 890ddd
	int outputPortsCount = fx->getOutputConnectionCount();
Toshihiro Shimizu 890ddd
	/*if(!outputPortsCount)   //We have no access to TApp here!!
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
    //It could be a terminal fx. In that case, pass to the xsheet fx
Toshihiro Shimizu 890ddd
    FxDag* dag = TApp::instance()->getCurrentXsheet()->getXsheet()->getFxDag();
Toshihiro Shimizu 890ddd
    if(dag->getTerminalFxs()->containsFx(fx))
Toshihiro Shimizu 890ddd
      return getNotAllowingAncestor(dag->getXsheetFx());
Toshihiro Shimizu 890ddd
  }*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Now, for common ports
Toshihiro Shimizu 890ddd
	for (int i = 0; i < outputPortsCount; ++i) {
Toshihiro Shimizu 890ddd
		//Find the output Fx and the port connected to our fx
Toshihiro Shimizu 890ddd
		TFxPort *port = fx->getOutputConnection(i);
Toshihiro Shimizu 890ddd
		TRasterFx *outFx = static_cast<trasterfx *="">(port->getOwnerFx());</trasterfx>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int portIdx, portsCount = outFx->getInputPortCount();
Toshihiro Shimizu 890ddd
		for (portIdx = 0; portIdx < portsCount; ++portIdx)
Toshihiro Shimizu 890ddd
			if (outFx->getInputPort(portIdx) == port)
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
		assert(portIdx < portsCount);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (!outFx->allowUserCacheOnPort(portIdx))
Toshihiro Shimizu 890ddd
			return outFx;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TFx *naAncestor = getNotAllowingAncestor(outFx);
Toshihiro Shimizu 890ddd
		if (naAncestor)
Toshihiro Shimizu 890ddd
			return naAncestor;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*****************************************************************************************
Toshihiro Shimizu 890ddd
//    Resources Container Definition
Toshihiro Shimizu 890ddd
//*****************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename colkey,="" rowkey,="" typename="" val=""></typename>
Toshihiro Shimizu 890ddd
class Table
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	typedef typename std::map<colkey, val=""> Row;</colkey,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	std::map<rowkey, row=""> m_table;</rowkey,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	friend class Iterator;
Toshihiro Shimizu 890ddd
	friend class ColIterator;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	typedef typename std::map<rowkey, row="">::iterator RowsIterator;</rowkey,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	class Iterator
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	protected:
Toshihiro Shimizu 890ddd
		Table *m_table;
Toshihiro Shimizu 890ddd
		RowsIterator m_rowIt;
Toshihiro Shimizu 890ddd
		typename Row::iterator m_it;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		friend class Table;
Toshihiro Shimizu 890ddd
		Iterator(Table *table) : m_table(table) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		virtual void makeConsistent()
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			if (m_it == m_rowIt->second.end()) {
Toshihiro Shimizu 890ddd
				if (++m_rowIt == m_table->m_table.end())
Toshihiro Shimizu 890ddd
					return;
Toshihiro Shimizu 890ddd
				m_it = m_rowIt->second.begin();
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	public:
Toshihiro Shimizu 890ddd
		const RowKey &row() { return m_rowIt->first; }
Toshihiro Shimizu 890ddd
		const ColKey &col() { return m_it->first; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		virtual void operator++()
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			++m_it;
Toshihiro Shimizu 890ddd
			makeConsistent();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		virtual operator bool() { return m_rowIt != m_table->m_table.end(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		Val &operator*() { return m_it->second; }
Toshihiro Shimizu 890ddd
		Val *operator->() { return &m_it->second; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		bool operator==(const Iterator &it)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			return m_it == it.m_it;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		bool operator!=(const Iterator &it)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			return !operator==(it);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	class ColIterator : public Iterator
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		ColKey m_colKey;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		friend class Table;
Toshihiro Shimizu 890ddd
		ColIterator(Table *table, const ColKey &c) : Iterator(table), m_colKey(c) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		void makeConsistent()
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			Iterator::m_rowIt = Iterator::m_rowIt;
Toshihiro Shimizu 890ddd
			while (Iterator::m_rowIt != Iterator::m_table->m_table.end()) {
Toshihiro Shimizu 890ddd
				Iterator::m_it = Iterator::m_rowIt->second.find(m_colKey);
Toshihiro Shimizu 890ddd
				if (Iterator::m_it != Iterator::m_rowIt->second.end())
Toshihiro Shimizu 890ddd
					break;
Toshihiro Shimizu 890ddd
				++Iterator::m_rowIt;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	public:
Toshihiro Shimizu 890ddd
		void operator++()
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			++Iterator::m_rowIt;
Toshihiro Shimizu 890ddd
			makeConsistent();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	class RowIterator : public Iterator
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		friend class Table;
Toshihiro Shimizu 890ddd
		RowIterator(Table *table) : Iterator(table) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		void makeConsistent() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	public:
Toshihiro Shimizu 890ddd
		RowIterator(const RowsIterator rowIt) : Iterator(0)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			Iterator::m_rowIt = rowIt;
Toshihiro Shimizu 890ddd
			Iterator::m_it = rowIt->second.begin();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		void operator++() { ++Iterator::m_it; }
Toshihiro Shimizu 890ddd
		operator bool() { return Iterator::m_it != Iterator::m_rowIt->second.end(); }
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	Table() {}
Toshihiro Shimizu 890ddd
	~Table() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::map<rowkey, row=""> &rows() { return m_table; }</rowkey,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Iterator begin()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		Iterator result(this);
Toshihiro Shimizu 890ddd
		result.m_rowIt = m_table.begin();
Toshihiro Shimizu 890ddd
		if (result.m_rowIt != m_table.end())
Toshihiro Shimizu 890ddd
			result.m_it = result.m_rowIt->second.begin();
Toshihiro Shimizu 890ddd
		return result;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	RowIterator rowBegin(const RowKey &row)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		RowIterator result(this);
Toshihiro Shimizu 890ddd
		result.m_rowIt = m_table.find(row);
Toshihiro Shimizu 890ddd
		if (result.m_rowIt != m_table.end())
Toshihiro Shimizu 890ddd
			result.m_it = result.m_rowIt->second.begin();
Toshihiro Shimizu 890ddd
		return result;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ColIterator colBegin(const ColKey &col)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		ColIterator result(this, col);
Toshihiro Shimizu 890ddd
		result.m_rowIt = m_table.begin();
Toshihiro Shimizu 890ddd
		result.makeConsistent();
Toshihiro Shimizu 890ddd
		return result;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Val &value(const RowKey &r, const ColKey &c)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return m_table[r][c];
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Iterator insert(const RowKey &r, const ColKey &c, const Val &val)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		Iterator result(this);
Toshihiro Shimizu 890ddd
		result.m_rowIt = m_table.insert(std::make_pair(r, Row())).first;
Toshihiro Shimizu 890ddd
		result.m_it = result.m_rowIt->second.insert(std::make_pair(c, val)).first;
Toshihiro Shimizu 890ddd
		return result;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Iterator find(const RowKey &r, const ColKey &c)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		Iterator result(this);
Toshihiro Shimizu 890ddd
		result.m_rowIt = m_table.find(r);
Toshihiro Shimizu 890ddd
		if (result.m_rowIt == m_table.end())
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		result.m_it = result.m_rowIt->second.find(c);
Toshihiro Shimizu 890ddd
		if (result.m_it == result.m_rowIt->second.end())
Toshihiro Shimizu 890ddd
			result.m_rowIt = m_table.end();
Toshihiro Shimizu 890ddd
		return result;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Iterator erase(const RowKey &r, const ColKey &c)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		Iterator it(find(r, c));
Toshihiro Shimizu 890ddd
		return erase(it);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Iterator erase(const Iterator &it)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		Iterator result(it);
Toshihiro Shimizu 890ddd
		Row &row = it.m_rowIt->second;
Toshihiro Shimizu 890ddd
		++result.m_it;
Toshihiro Shimizu 890ddd
		row.erase(it.m_it);
Toshihiro Shimizu 890ddd
		if (result.m_it == row.end() && row.empty()) {
Toshihiro Shimizu 890ddd
			result.makeConsistent();
Toshihiro Shimizu 890ddd
			m_table.erase(it.m_rowIt);
Toshihiro Shimizu 890ddd
			return result;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		result.makeConsistent();
Toshihiro Shimizu 890ddd
		return result;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void erase(const ColKey &c)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		ColIterator it(colBegin(c));
Toshihiro Shimizu 890ddd
		while (it) {
Toshihiro Shimizu 890ddd
			RowsIterator rowIt = it.m_rowIt;
Toshihiro Shimizu 890ddd
			rowIt->second.erase(it.m_it);
Toshihiro Shimizu 890ddd
			++it;
Toshihiro Shimizu 890ddd
			if (rowIt->second.empty())
Toshihiro Shimizu 890ddd
				m_table.erase(rowIt);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void erase(const RowKey &r)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_table.erase(r);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void clear() { m_table.clear(); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct LockedResourceP {
Toshihiro Shimizu 890ddd
	TCacheResourceP m_resource;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	LockedResourceP(const TCacheResourceP &resource) : m_resource(resource)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_resource->addLock();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	LockedResourceP(const LockedResourceP &resource) : m_resource(resource.m_resource)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_resource->addLock();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	~LockedResourceP()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_resource->releaseLock();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	LockedResourceP &operator=(const LockedResourceP &src)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		src.m_resource->addLock();
Toshihiro Shimizu 890ddd
		if (m_resource)
Toshihiro Shimizu 890ddd
			m_resource->releaseLock();
Toshihiro Shimizu 890ddd
		m_resource = src.m_resource;
Toshihiro Shimizu 890ddd
		return *this;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	operator bool() const { return m_resource; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool operator<(const LockedResourceP &resource) const { return m_resource < resource.m_resource; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TCacheResource *operator->() const { return m_resource.getPointer(); }
Toshihiro Shimizu 890ddd
	TCacheResource &operator*() const { return *m_resource.getPointer(); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef Table<std::string, int,="" std::set<lockedresourcep="">> ResourcesTable;</std::string,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class TPassiveCacheManager::ResourcesContainer
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	ResourcesTable m_resources;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	ResourcesContainer() {}
Toshihiro Shimizu 890ddd
	~ResourcesContainer() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ResourcesTable &getTable() { return m_resources; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*****************************************************************************************
Toshihiro Shimizu 890ddd
//    FxData implementation
Toshihiro Shimizu 890ddd
//*****************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPassiveCacheManager::FxData::FxData()
Toshihiro Shimizu 890ddd
	: m_storageFlag(0), m_passiveCacheId(0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPassiveCacheManager::FxData::~FxData()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*****************************************************************************************
Toshihiro Shimizu 890ddd
//    Manager generator
Toshihiro Shimizu 890ddd
//*****************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=======================================
Toshihiro Shimizu 890ddd
//    TPassiveCacheManagerGenerator
Toshihiro Shimizu 890ddd
//---------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class TPassiveCacheManagerGenerator : public TRenderResourceManagerGenerator
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRenderResourceManager *operator()(void)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		//return new TPassiveCacheManager;
Toshihiro Shimizu 890ddd
		return TPassiveCacheManager::instance();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
MANAGER_FILESCOPE_DECLARATION_DEP(
Toshihiro Shimizu 890ddd
	TPassiveCacheManager,
Toshihiro Shimizu 890ddd
	TPassiveCacheManagerGenerator,
Toshihiro Shimizu 890ddd
	TFxCacheManager::deps())
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*****************************************************************************************
Toshihiro Shimizu 890ddd
//    Implementation
Toshihiro Shimizu 890ddd
//*****************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPassiveCacheManager::TPassiveCacheManager()
Toshihiro Shimizu 890ddd
#ifdef USE_SQLITE_HDPOOL
Toshihiro Shimizu 890ddd
	: m_currStorageFlag(ON_DISK)
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
	: m_currStorageFlag(IN_MEMORY)
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	  ,
Toshihiro Shimizu 890ddd
	  m_enabled(true), m_descriptorCallback(0), m_mutex(QMutex::Recursive), m_resources(new ResourcesContainer)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	reset();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPassiveCacheManager::~TPassiveCacheManager()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	delete m_resources;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPassiveCacheManager *TPassiveCacheManager::instance()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	static TPassiveCacheManager theInstance;
Toshihiro Shimizu 890ddd
	return &theInstance;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TPassiveCacheManager::setContextName(unsigned long renderId, const std::string &name)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QMutexLocker locker(&m_mutex);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Retrieve the context data if already present
Toshihiro Shimizu 890ddd
	std::map<std::string, uchar="">::iterator it = m_contextNames.find(name);</std::string,>
Toshihiro Shimizu 890ddd
	if (it == m_contextNames.end())
Toshihiro Shimizu 890ddd
		it = m_contextNames.insert(std::make_pair(name, 0)).first;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	it->second = !it->second;
Shinya Kitaoka 9eb50d
	m_contextNamesByRenderId.insert(std::make_pair(renderId, name + "%" + std::to_string(it->second)));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
std::string TPassiveCacheManager::getContextName()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QMutexLocker locker(&m_mutex);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//First, search the context name
Toshihiro Shimizu 890ddd
	std::map<unsigned long,="" std::string="">::iterator it =</unsigned>
Toshihiro Shimizu 890ddd
		m_contextNamesByRenderId.find(TRenderer::renderId());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (it == m_contextNamesByRenderId.end())
Toshihiro Shimizu 890ddd
		return "";
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return it->second;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TPassiveCacheManager::setEnabled(bool enabled)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_enabled = enabled;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TPassiveCacheManager::isEnabled() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_enabled;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TPassiveCacheManager::setStorageMode(StorageFlag mode)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_currStorageFlag = mode;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPassiveCacheManager::StorageFlag TPassiveCacheManager::getStorageMode() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_currStorageFlag;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TPassiveCacheManager::setTreeDescriptor(TreeDescriptor callback)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_descriptorCallback = callback;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TPassiveCacheManager::getNewPassiveCacheId()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return ++m_currentPassiveCacheId;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TPassiveCacheManager::updatePassiveCacheId(int id)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_updatingPassiveCacheIds)
Shinya Kitaoka 12c444
		m_currentPassiveCacheId = std::max(m_currentPassiveCacheId, id);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		id = getNewPassiveCacheId();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return id;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TPassiveCacheManager::onSceneLoaded()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_updatingPassiveCacheIds = false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//Initialize the fxs tree description. This was not possible before, as the
Toshihiro Shimizu 890ddd
//scene was yet incomplete (in loading state).
Toshihiro Shimizu 890ddd
#ifndef USE_SQLITE_HDPOOL
Toshihiro Shimizu 890ddd
	unsigned int count = m_fxDataVector.size();
Toshihiro Shimizu 890ddd
	for (unsigned int i = 0; i < count; ++i) {
Toshihiro Shimizu 890ddd
		FxData &data = m_fxDataVector[i];
Toshihiro Shimizu 890ddd
		(*m_descriptorCallback)(data.m_treeDescription, data.m_fx);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TPassiveCacheManager::touchFxData(int &idx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (idx >= 0)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QMutexLocker locker(&m_mutex);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_fxDataVector.push_back(FxData());
Toshihiro Shimizu 890ddd
	idx = m_fxDataVector.size() - 1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TPassiveCacheManager::declareCached(TFx *fx, int passiveCacheId)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int &idx = fx->getAttributes()->passiveCacheDataIdx();
Toshihiro Shimizu 890ddd
	touchFxData(idx);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	FxData &data = m_fxDataVector[idx];
Toshihiro Shimizu 890ddd
	data.m_fx = fx;
Toshihiro Shimizu 890ddd
	data.m_storageFlag = m_currStorageFlag;
Toshihiro Shimizu 890ddd
	data.m_passiveCacheId = updatePassiveCacheId(passiveCacheId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return idx;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TPassiveCacheManager::reset()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_updatingPassiveCacheIds = true;
Toshihiro Shimizu 890ddd
	m_currentPassiveCacheId = 0;
Toshihiro Shimizu 890ddd
	m_fxDataVector.clear();
Toshihiro Shimizu 890ddd
	m_resources->getTable().clear();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TPassiveCacheManager::cacheEnabled(TFx *fx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int idx = fx->getAttributes()->passiveCacheDataIdx();
Toshihiro Shimizu 890ddd
	if (idx < 0)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(idx < (int)m_fxDataVector.size());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QMutexLocker locker(&m_mutex);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return m_fxDataVector[idx].m_storageFlag > 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TPassiveCacheManager::getPassiveCacheId(TFx *fx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int idx = fx->getAttributes()->passiveCacheDataIdx();
Toshihiro Shimizu 890ddd
	if (idx < 0)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//This needs not be mutex locked
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(idx < (int)m_fxDataVector.size());
Toshihiro Shimizu 890ddd
	return m_fxDataVector[idx].m_passiveCacheId;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPassiveCacheManager::StorageFlag TPassiveCacheManager::getStorageMode(TFx *fx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int idx = fx->getAttributes()->passiveCacheDataIdx();
Toshihiro Shimizu 890ddd
	if (idx < 0)
Toshihiro Shimizu 890ddd
		return NONE;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QMutexLocker locker(&m_mutex);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return (StorageFlag)m_fxDataVector[idx].m_storageFlag;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TPassiveCacheManager::enableCache(TFx *fx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int &idx = fx->getAttributes()->passiveCacheDataIdx();
Toshihiro Shimizu 890ddd
	touchFxData(idx);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	FxData &data = m_fxDataVector[idx];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QMutexLocker locker(&m_mutex);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef DIAGNOSTICS
Toshihiro Shimizu 890ddd
	DIAGNOSTICS_STR("#activity.txt | " + QTime::currentTime().toString() + " " +
Toshihiro Shimizu 890ddd
					QString("Enable Cache"));
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	StorageFlag flag = getStorageMode();
Toshihiro Shimizu 890ddd
	if (flag) {
Toshihiro Shimizu 890ddd
		UCHAR &storedFlag = data.m_storageFlag;
Toshihiro Shimizu 890ddd
		UCHAR oldFlag = storedFlag;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		storedFlag |= flag;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (data.m_passiveCacheId == 0)
Toshihiro Shimizu 890ddd
			data.m_passiveCacheId = getNewPassiveCacheId();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if ((storedFlag & ON_DISK) && !(oldFlag & ON_DISK)) {
Toshihiro Shimizu 890ddd
			ResourcesTable::ColIterator it = m_resources->getTable().colBegin(data.m_passiveCacheId);
Toshihiro Shimizu 890ddd
			for (; it; ++it) {
Toshihiro Shimizu 890ddd
				std::set<lockedresourcep> &resources = *it;</lockedresourcep>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				std::set<lockedresourcep>::iterator jt;</lockedresourcep>
Toshihiro Shimizu 890ddd
				for (jt = resources.begin(); jt != resources.end(); ++jt)
Toshihiro Shimizu 890ddd
					(*jt)->enableBackup();
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef USE_SQLITE_HDPOOL
Toshihiro Shimizu 890ddd
		if ((storedFlag & IN_MEMORY) && !(oldFlag & IN_MEMORY)) {
Toshihiro Shimizu 890ddd
			data.m_fx = fx;
Toshihiro Shimizu 890ddd
			(*m_descriptorCallback)(data.m_treeDescription, data.m_fx);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TPassiveCacheManager::disableCache(TFx *fx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int idx = fx->getAttributes()->passiveCacheDataIdx();
Toshihiro Shimizu 890ddd
	if (idx < 0)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	FxData &data = m_fxDataVector[idx];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QMutexLocker locker(&m_mutex);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef DIAGNOSTICS
Toshihiro Shimizu 890ddd
	DIAGNOSTICS_STR("#activity.txt | " + QTime::currentTime().toString() + " " +
Toshihiro Shimizu 890ddd
					QString("Disable Cache"));
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	StorageFlag flag = getStorageMode();
Toshihiro Shimizu 890ddd
	if (flag) {
Toshihiro Shimizu 890ddd
		UCHAR &storedFlag = data.m_storageFlag;
Toshihiro Shimizu 890ddd
		UCHAR oldFlag = storedFlag;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		storedFlag &= ~flag;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if ((oldFlag & IN_MEMORY) && !(storedFlag & IN_MEMORY)) {
Toshihiro Shimizu 890ddd
			m_resources->getTable().erase(data.m_passiveCacheId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			data.m_fx = TFxP();
Toshihiro Shimizu 890ddd
			data.m_treeDescription = "";
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_SQLITE_HDPOOL
Toshihiro Shimizu 890ddd
		if ((oldFlag & ON_DISK) && !(storedFlag & ON_DISK))
Toshihiro Shimizu 890ddd
			TCacheResourcePool::instance()->releaseReferences("P" + QString::number(data.m_passiveCacheId));
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TPassiveCacheManager::toggleCache(TFx *fx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int &idx = fx->getAttributes()->passiveCacheDataIdx();
Toshihiro Shimizu 890ddd
	touchFxData(idx);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	FxData &data = m_fxDataVector[idx];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QMutexLocker locker(&m_mutex);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	StorageFlag flag = getStorageMode();
Toshihiro Shimizu 890ddd
	if (flag) {
Toshihiro Shimizu 890ddd
		UCHAR &storedFlag = data.m_storageFlag;
Toshihiro Shimizu 890ddd
		UCHAR oldFlag = storedFlag;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		storedFlag ^= flag;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef DIAGNOSTICS
Toshihiro Shimizu 890ddd
		DIAGNOSTICS_STR("#activity.txt | " + QTime::currentTime().toString() + " " +
Toshihiro Shimizu 890ddd
						QString("Toggle Cache (now ") + ((storedFlag & IN_MEMORY) ? "enabled)" : "disabled)"));
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (data.m_passiveCacheId == 0)
Toshihiro Shimizu 890ddd
			data.m_passiveCacheId = getNewPassiveCacheId();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if ((storedFlag & ON_DISK) && !(oldFlag & ON_DISK)) {
Toshihiro Shimizu 890ddd
			ResourcesTable::ColIterator it = m_resources->getTable().colBegin(data.m_passiveCacheId);
Toshihiro Shimizu 890ddd
			for (; it; ++it) {
Toshihiro Shimizu 890ddd
				std::set<lockedresourcep> &resources = *it;</lockedresourcep>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				std::set<lockedresourcep>::iterator jt;</lockedresourcep>
Toshihiro Shimizu 890ddd
				for (jt = resources.begin(); jt != resources.end(); ++jt)
Toshihiro Shimizu 890ddd
					(*jt)->enableBackup();
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Implementa la versione contraria - eliminazione dell'fx nell'hdPool...
Toshihiro Shimizu 890ddd
		//Metti anche questo in versione ritardata con flush... Il flush e' da unificare...
Toshihiro Shimizu 890ddd
		//e magari da spostare direttamente nell'hdPool
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if ((oldFlag & IN_MEMORY) && !(storedFlag & IN_MEMORY)) {
Toshihiro Shimizu 890ddd
			m_resources->getTable().erase(data.m_passiveCacheId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			data.m_fx = TFxP();
Toshihiro Shimizu 890ddd
			data.m_treeDescription = "";
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef USE_SQLITE_HDPOOL
Toshihiro Shimizu 890ddd
		if ((storedFlag & IN_MEMORY) && !(oldFlag & IN_MEMORY)) {
Toshihiro Shimizu 890ddd
			data.m_fx = fx;
Toshihiro Shimizu 890ddd
			(*m_descriptorCallback)(data.m_treeDescription, data.m_fx);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_SQLITE_HDPOOL
Toshihiro Shimizu 890ddd
		if ((oldFlag & ON_DISK) && !(storedFlag & ON_DISK))
Toshihiro Shimizu 890ddd
			TCacheResourcePool::instance()->releaseReferences("P" + QString::number(data.m_passiveCacheId));
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TPassiveCacheManager::invalidateLevel(const std::string &levelName)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QMutexLocker locker(&m_mutex);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Traverse the managed resources for passed levelName.
Toshihiro Shimizu 890ddd
	ResourcesTable &table = m_resources->getTable();
Toshihiro Shimizu 890ddd
	ResourcesTable::Iterator it = table.begin();
Toshihiro Shimizu 890ddd
	while (it) {
Toshihiro Shimizu 890ddd
		std::set<lockedresourcep> &resources = *it;</lockedresourcep>
Toshihiro Shimizu 890ddd
		std::set<lockedresourcep>::iterator jt, kt;</lockedresourcep>
Toshihiro Shimizu 890ddd
		for (jt = resources.begin(); jt != resources.end();) {
Shinya Kitaoka 3bfa54
			if ((*jt)->getName().find(levelName) != std::string::npos) {
Toshihiro Shimizu 890ddd
				kt = jt++;
Toshihiro Shimizu 890ddd
				it->erase(kt);
Toshihiro Shimizu 890ddd
			} else
Toshihiro Shimizu 890ddd
				++jt;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (resources.empty())
Toshihiro Shimizu 890ddd
			it = table.erase(it);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			++it;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_SQLITE_HDPOOL
Toshihiro Shimizu 890ddd
	//Store the level name until the invalidation is forced
Toshihiro Shimizu 890ddd
	m_invalidatedLevels.insert(levelName);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TPassiveCacheManager::forceInvalidate()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
#ifdef USE_SQLITE_HDPOOL
Toshihiro Shimizu 890ddd
	TCacheResourcePool *pool = TCacheResourcePool::instance();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Clear all invalidated levels from the resource pool
Toshihiro Shimizu 890ddd
	std::set<std::string>::iterator it;</std::string>
Toshihiro Shimizu 890ddd
	for (it = m_invalidatedLevels.begin(); it != m_invalidatedLevels.end(); ++it)
Toshihiro Shimizu 890ddd
		pool->clearKeyword(*it);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_invalidatedLevels.clear();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//Generate the fx's tree description. If it is contained in one of those
Toshihiro Shimizu 890ddd
//stored with cached fxs, release their associated resources.
Toshihiro Shimizu 890ddd
void TPassiveCacheManager::onFxChanged(const TFxP &fx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
#ifndef USE_SQLITE_HDPOOL
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::string fxTreeDescription;
Toshihiro Shimizu 890ddd
	(*m_descriptorCallback)(fxTreeDescription, fx);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	unsigned int count = m_fxDataVector.size();
Toshihiro Shimizu 890ddd
	for (unsigned int i = 0; i < count; ++i) {
Toshihiro Shimizu 890ddd
		FxData &data = m_fxDataVector[i];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (!data.m_fx)
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (data.m_treeDescription.find(fxTreeDescription) != std::string::npos)
Toshihiro Shimizu 890ddd
			m_resources->getTable().erase(data.m_passiveCacheId);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//Regenerate the tree descriptions of cached fxs. If the new description does
Toshihiro Shimizu 890ddd
//not match the previous one, release the associated resources.
Toshihiro Shimizu 890ddd
void TPassiveCacheManager::onXsheetChanged()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
#ifndef USE_SQLITE_HDPOOL
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef DIAGNOSTICS
Toshihiro Shimizu 890ddd
	DIAGNOSTICS_STR("#activity.txt | " + QTime::currentTime().toString() + " XSheet changed");
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	unsigned int count = m_fxDataVector.size();
Toshihiro Shimizu 890ddd
	for (unsigned int i = 0; i < count; ++i) {
Toshihiro Shimizu 890ddd
		FxData &data = m_fxDataVector[i];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (!data.m_fx)
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		std::string newTreeDescription;
Toshihiro Shimizu 890ddd
		(*m_descriptorCallback)(newTreeDescription, data.m_fx);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (data.m_treeDescription != newTreeDescription) {
Toshihiro Shimizu 890ddd
			m_resources->getTable().erase(data.m_passiveCacheId);
Toshihiro Shimizu 890ddd
			data.m_treeDescription = newTreeDescription;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TPassiveCacheManager::getResource(
Shinya Kitaoka 3bfa54
	TCacheResourceP &resource, const std::string &alias,
Toshihiro Shimizu 890ddd
	const TFxP &fx, double frame, const TRenderSettings &rs,
Toshihiro Shimizu 890ddd
	ResourceDeclaration *resData)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!(m_enabled && fx && rs.m_userCachable))
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	StorageFlag flag = getStorageMode(fx.getPointer());
Toshihiro Shimizu 890ddd
	if (flag == NONE)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::string contextName(getContextName());
Toshihiro Shimizu 890ddd
	if (contextName.empty())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Build a resource if none was passed.
Toshihiro Shimizu 890ddd
	if (!resource)
Toshihiro Shimizu 890ddd
		resource = TCacheResourceP(alias, true);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_SQLITE_HDPOOL
Toshihiro Shimizu 890ddd
	if (flag & ON_DISK) {
Toshihiro Shimizu 890ddd
		resource->enableBackup();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int passiveCacheId = m_fxDataVector[fx->getAttributes()->passiveCacheDataIdx()].m_passiveCacheId;
Toshihiro Shimizu 890ddd
		TCacheResourcePool::instance()->addReference(resource, "P" + QString::number(passiveCacheId));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (flag & IN_MEMORY) {
Toshihiro Shimizu 890ddd
		QMutexLocker locker(&m_mutex);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int passiveCacheId = m_fxDataVector[fx->getAttributes()->passiveCacheDataIdx()].m_passiveCacheId;
Toshihiro Shimizu 890ddd
		m_resources->getTable().value(contextName, passiveCacheId).insert(resource);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TPassiveCacheManager::releaseContextNamesWithPrefix(const std::string &prefix)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QMutexLocker locker(&m_mutex);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef DIAGNOSTICS
Toshihiro Shimizu 890ddd
	DIAGNOSTICS_STR("#activity.txt | " + QTime::currentTime().toString() +
Toshihiro Shimizu 890ddd
					" Release Context Name (" + QString::fromStdString(prefix) + ")");
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Retrieve the context range
Toshihiro Shimizu 890ddd
	std::string prefixPlus1 = prefix;
Toshihiro Shimizu 890ddd
	prefixPlus1[prefix.size() - 1]++;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		std::map<std::string, uchar="">::iterator it, jt;</std::string,>
Toshihiro Shimizu 890ddd
		it = m_contextNames.lower_bound(prefix);
Toshihiro Shimizu 890ddd
		jt = m_contextNames.lower_bound(prefixPlus1);
Toshihiro Shimizu 890ddd
		m_contextNames.erase(it, jt);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Transfer to temporary
Toshihiro Shimizu 890ddd
	ResourcesTable &table = m_resources->getTable();
Toshihiro Shimizu 890ddd
	std::map<std::string, resourcestable::row=""> &rows = m_resources->getTable().rows();</std::string,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::map<std::string, resourcestable::row="">::iterator it, jt, kt;</std::string,>
Toshihiro Shimizu 890ddd
	it = rows.lower_bound(prefix);
Toshihiro Shimizu 890ddd
	jt = rows.lower_bound(prefixPlus1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::string temporaryName("T");
Toshihiro Shimizu 890ddd
	for (kt = it; kt != jt; ++kt) {
Toshihiro Shimizu 890ddd
		ResourcesTable::RowIterator lt(kt);
Toshihiro Shimizu 890ddd
		for (; lt; ++lt)
Toshihiro Shimizu 890ddd
			table.value(temporaryName, lt.col()).insert(lt->begin(), lt->end());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	rows.erase(it, jt == rows.end() ? rows.lower_bound(prefixPlus1) : jt);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TPassiveCacheManager::releaseOldResources()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QMutexLocker locker(&m_mutex);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Release all the resources that were stored in the old render instance of the
Toshihiro Shimizu 890ddd
	//context, PLUS those of the temporary container.
Toshihiro Shimizu 890ddd
	//Resources that were held by the TPassiveCacheManager::getResource() procedure
Toshihiro Shimizu 890ddd
	//are now duplicated in a proper row of the table - and will not be freed.
Toshihiro Shimizu 890ddd
	std::string contextName(getContextName());
Toshihiro Shimizu 890ddd
	if (contextName.empty())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	char &lastChar = contextName[contextName.size() - 1];
Toshihiro Shimizu 890ddd
	lastChar = '0' + !(lastChar - '0');
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ResourcesTable &table = m_resources->getTable();
Toshihiro Shimizu 890ddd
	table.erase(contextName);
Toshihiro Shimizu 890ddd
	table.erase("T");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TPassiveCacheManager::onRenderInstanceStart(unsigned long renderId)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TFxCacheManagerDelegate::onRenderInstanceStart(renderId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_SQLITE_HDPOOL
Toshihiro Shimizu 890ddd
	//Force invalidation of levels before the render starts
Toshihiro Shimizu 890ddd
	forceInvalidate();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TPassiveCacheManager::onRenderInstanceEnd(unsigned long renderId)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QMutexLocker locker(&m_mutex);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	releaseOldResources();
Toshihiro Shimizu 890ddd
	m_contextNamesByRenderId.erase(renderId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TPassiveCacheManager::onRenderStatusEnd(int renderStatus)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (renderStatus == TRenderer::TESTRUN)
Toshihiro Shimizu 890ddd
		releaseOldResources();
Toshihiro Shimizu 890ddd
}