|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Toonz core includes
|
|
Toshihiro Shimizu |
890ddd |
#include "timagecache.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trasterimage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ttoonzimage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tmeshimage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "timage_io.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Qt includes (mutexing classes)
|
|
Toshihiro Shimizu |
890ddd |
#include <qmutex></qmutex>
|
|
Toshihiro Shimizu |
890ddd |
#include <qmutexlocker></qmutexlocker>
|
|
Toshihiro Shimizu |
890ddd |
#include <qreadwritelock></qreadwritelock>
|
|
Toshihiro Shimizu |
890ddd |
#include <qreadlocker></qreadlocker>
|
|
Toshihiro Shimizu |
890ddd |
#include <qwritelocker></qwritelocker>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/imagemanager.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshsimplelevel.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/* EXPLANATION (by Daniele):
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Images / Image Infos retrieval is quite a frequent task throughout Toonz - in particular,
|
|
Toshihiro Shimizu |
890ddd |
as Render operations tend to be multithreaded, it is important to ensure that the
|
|
Toshihiro Shimizu |
890ddd |
ImageManager treats these operations efficiently.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Most of the image manager's job is that of caching hard-built image data so that successive
|
|
Toshihiro Shimizu |
890ddd |
queries avoid rebuilding the same images again.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
In a multithreaded environment, we must make sure that multiple threads block each other out
|
|
Toshihiro Shimizu |
890ddd |
as little as possible.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Here are the main performance and threading notes:
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
- Image infos are completely cached, while image cachability is user-specified.
|
|
Toshihiro Shimizu |
890ddd |
This is needed as some images must be loaded only temporarily.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
- One mutex will be used to protect the bindings table. It is the outermost mutex.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
- One mutex (read/write lock) will be used to protect access to EACH individual image.
|
|
Toshihiro Shimizu |
890ddd |
Testing should be required. If file access is found to be too strictly sequential,
|
|
Toshihiro Shimizu |
890ddd |
perhaps a single mutex could suffice.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
- Having different mutexes to protect images and image infos is currently not implemented,
|
|
Toshihiro Shimizu |
890ddd |
but could be. Testing required.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
TODO: TXshSimpleLevel::setFrame(...) usa aggiunte/rimozioni manuali di immagini associate
|
|
Toshihiro Shimizu |
890ddd |
a binding nell'ImageManager - aspettandosi che poiche' l'immagine e' presente in cache,
|
|
Toshihiro Shimizu |
890ddd |
verra' beccata...
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Image Builder implementation
|
|
Toshihiro Shimizu |
890ddd |
//************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
DEFINE_CLASS_CODE(ImageBuilder, 100)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ImageBuilder::ImageBuilder()
|
|
Toshihiro Shimizu |
890ddd |
: TSmartObject(m_classCode), m_imageBuildingLock(QReadWriteLock::Recursive), m_cached(false), m_modified(false), m_imFlags(ImageManager::none)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ImageBuilder::~ImageBuilder()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool ImageBuilder::areInfosCompatible(int imFlags, void *extData)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_info.m_valid;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool ImageBuilder::isImageCompatible(int imFlags, void *extData)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_info.m_valid;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool ImageBuilder::setImageInfo(TImageInfo &info, const TDimension &size)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
info = TImageInfo();
|
|
Toshihiro Shimizu |
890ddd |
info.m_lx = size.lx;
|
|
Toshihiro Shimizu |
890ddd |
info.m_ly = size.ly;
|
|
Toshihiro Shimizu |
890ddd |
info.m_x0 = 0;
|
|
Toshihiro Shimizu |
890ddd |
info.m_y0 = 0;
|
|
Toshihiro Shimizu |
890ddd |
info.m_x1 = size.lx - 1;
|
|
Toshihiro Shimizu |
890ddd |
info.m_y1 = size.ly - 1;
|
|
Toshihiro Shimizu |
890ddd |
info.m_valid = true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool ImageBuilder::setImageInfo(TImageInfo &info, TImage *img)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
info = TImageInfo();
|
|
Toshihiro Shimizu |
890ddd |
if (TRasterImageP ri = TRasterImageP(img)) {
|
|
Toshihiro Shimizu |
890ddd |
TRasterP ras = ri->getRaster();
|
|
Toshihiro Shimizu |
890ddd |
info.m_lx = ras->getLx();
|
|
Toshihiro Shimizu |
890ddd |
info.m_ly = ras->getLy();
|
|
Toshihiro Shimizu |
890ddd |
ri->getDpi(info.m_dpix, info.m_dpiy);
|
|
Toshihiro Shimizu |
890ddd |
TRect savebox = ri->getSavebox();
|
|
Toshihiro Shimizu |
890ddd |
info.m_x0 = savebox.x0;
|
|
Toshihiro Shimizu |
890ddd |
info.m_y0 = savebox.y0;
|
|
Toshihiro Shimizu |
890ddd |
info.m_x1 = savebox.x1;
|
|
Toshihiro Shimizu |
890ddd |
info.m_y1 = savebox.y1;
|
|
Toshihiro Shimizu |
890ddd |
} else if (TToonzImageP ti = TToonzImageP(img)) {
|
|
Toshihiro Shimizu |
890ddd |
TRasterP ras = ti->getRaster();
|
|
Toshihiro Shimizu |
890ddd |
info.m_lx = ras->getLx();
|
|
Toshihiro Shimizu |
890ddd |
info.m_ly = ras->getLy();
|
|
Toshihiro Shimizu |
890ddd |
ti->getDpi(info.m_dpix, info.m_dpiy);
|
|
Toshihiro Shimizu |
890ddd |
TRect savebox = ti->getSavebox();
|
|
Toshihiro Shimizu |
890ddd |
info.m_x0 = savebox.x0;
|
|
Toshihiro Shimizu |
890ddd |
info.m_y0 = savebox.y0;
|
|
Toshihiro Shimizu |
890ddd |
info.m_x1 = savebox.x1;
|
|
Toshihiro Shimizu |
890ddd |
info.m_y1 = savebox.y1;
|
|
Toshihiro Shimizu |
890ddd |
} else if (TMeshImageP mi = TMeshImageP(img)) {
|
|
Toshihiro Shimizu |
890ddd |
mi->getDpi(info.m_dpix, info.m_dpiy);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
info.m_valid = true;
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool ImageBuilder::setImageInfo(TImageInfo &info, TImageReader *ir)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
info = TImageInfo();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
const TImageInfo *tmp = ir->getImageInfo();
|
|
Toshihiro Shimizu |
890ddd |
if (tmp) {
|
|
Toshihiro Shimizu |
890ddd |
info = *tmp;
|
|
Toshihiro Shimizu |
890ddd |
if (info.m_x1 < info.m_x0 || info.m_y1 < info.m_y0) {
|
|
Toshihiro Shimizu |
890ddd |
info.m_x0 = info.m_y0 = 0;
|
|
Toshihiro Shimizu |
890ddd |
info.m_x1 = info.m_lx - 1;
|
|
Toshihiro Shimizu |
890ddd |
info.m_y1 = info.m_ly - 1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
info.m_valid = true;
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Image Manager Privates implementation
|
|
Toshihiro Shimizu |
890ddd |
//************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
struct ImageManager::Imp {
|
|
Toshihiro Shimizu |
890ddd |
QReadWriteLock m_tableLock; //!< Lock for the builders table
|
|
Toshihiro Shimizu |
890ddd |
std::map<string, imagebuilderp=""> m_builders; //!< identifier -> ImageBuilder table</string,>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
Imp() : m_tableLock(QReadWriteLock::Recursive) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void clear() { m_builders.clear(); }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Image Manager implementation
|
|
Toshihiro Shimizu |
890ddd |
//************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ImageManager::ImageManager()
|
|
Toshihiro Shimizu |
890ddd |
: m_imp(new Imp)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ImageManager::~ImageManager()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
delete m_imp;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ImageManager *ImageManager::instance()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// Re-introdotto possibile baco: voglio controllare se esiste ancora
|
|
Toshihiro Shimizu |
890ddd |
static ImageManager theInstance;
|
|
Toshihiro Shimizu |
890ddd |
return &theInstance;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ImageManager::bind(const string &id, ImageBuilder *builderPtr)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (!builderPtr) {
|
|
Toshihiro Shimizu |
890ddd |
unbind(id);
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QWriteLocker locker(&m_imp->m_tableLock);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ImageBuilderP &builderP = m_imp->m_builders[id];
|
|
Toshihiro Shimizu |
890ddd |
if (builderP && builderP->m_cached)
|
|
Toshihiro Shimizu |
890ddd |
TImageCache::instance()->remove(id);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
builderP = builderPtr;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool ImageManager::unbind(const string &id)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
QWriteLocker locker(&m_imp->m_tableLock);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::map<std::string, imagebuilderp="">::iterator it = m_imp->m_builders.find(id);</std::string,>
|
|
Toshihiro Shimizu |
890ddd |
if (it == m_imp->m_builders.end())
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ImageBuilderP &builderP = it->second;
|
|
Toshihiro Shimizu |
890ddd |
if (builderP && builderP->m_cached)
|
|
Toshihiro Shimizu |
890ddd |
TImageCache::instance()->remove(id);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_builders.erase(it);
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool ImageManager::isBound(const string &id) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
QReadLocker locker(&m_imp->m_tableLock);
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_builders.find(id) != m_imp->m_builders.end();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool ImageManager::rebind(const string &srcId, const string &dstId)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
QWriteLocker locker(&m_imp->m_tableLock);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::map<string, imagebuilderp="">::iterator st = m_imp->m_builders.find(srcId);</string,>
|
|
Toshihiro Shimizu |
890ddd |
if (st == m_imp->m_builders.end())
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ImageBuilderP builder = st->second;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_builders.erase(st);
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_builders[dstId] = builder;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TImageCache::instance()->remap(dstId, srcId);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ImageManager::clear()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
QWriteLocker locker(&m_imp->m_tableLock);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TImageCache::instance()->clearSceneImages();
|
|
Toshihiro Shimizu |
890ddd |
m_imp->clear();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TImageInfo *ImageManager::getInfo(const string &id, int imFlags, void *extData)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// Lock for table read and try to find data in the cache
|
|
Toshihiro Shimizu |
890ddd |
QReadLocker tableLocker(&m_imp->m_tableLock);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::map<string, imagebuilderp="">::iterator it = m_imp->m_builders.find(id);</string,>
|
|
Toshihiro Shimizu |
890ddd |
if (it == m_imp->m_builders.end())
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ImageBuilderP &builder = it->second;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(!((imFlags & ImageManager::toBeModified) && !builder->m_modified));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Check cached data
|
|
Toshihiro Shimizu |
890ddd |
if (builder->areInfosCompatible(imFlags, extData))
|
|
Toshihiro Shimizu |
890ddd |
return &builder->m_info;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QWriteLocker imageBuildingLocker(&builder->m_imageBuildingLock);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Re-check as waiting may have changed the situation
|
|
Toshihiro Shimizu |
890ddd |
if (builder->areInfosCompatible(imFlags, extData))
|
|
Toshihiro Shimizu |
890ddd |
return &builder->m_info;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TImageInfo info;
|
|
Toshihiro Shimizu |
890ddd |
if (builder->getInfo(info, imFlags, extData)) {
|
|
Toshihiro Shimizu |
890ddd |
builder->m_info = info;
|
|
Toshihiro Shimizu |
890ddd |
return &builder->m_info;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TImageP ImageManager::getImage(const string &id, int imFlags, void *extData)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(!((imFlags & ImageManager::toBeModified) && (imFlags & ImageManager::dontPutInCache)));
|
|
Toshihiro Shimizu |
890ddd |
assert(!((imFlags & ImageManager::toBeModified) && (imFlags & ImageManager::toBeSaved)));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Lock for table read and try to find data in the cache
|
|
Toshihiro Shimizu |
890ddd |
QReadLocker tableLocker(&m_imp->m_tableLock);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::map<string, imagebuilderp="">::iterator it = m_imp->m_builders.find(id);</string,>
|
|
Toshihiro Shimizu |
890ddd |
if (it == m_imp->m_builders.end())
|
|
Toshihiro Shimizu |
890ddd |
return TImageP();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ImageBuilderP &builder = it->second;
|
|
Toshihiro Shimizu |
890ddd |
bool modified = builder->m_modified;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Analyze imFlags
|
|
Toshihiro Shimizu |
890ddd |
bool _putInCache = TImageCache::instance()->isEnabled() && !(bool)(imFlags & dontPutInCache);
|
|
Toshihiro Shimizu |
890ddd |
bool _toBeModified = (imFlags & toBeModified);
|
|
Toshihiro Shimizu |
890ddd |
bool _toBeSaved = (imFlags & toBeSaved);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Update the modified flag according to the specified flags
|
|
Toshihiro Shimizu |
890ddd |
if (_toBeModified)
|
|
Toshihiro Shimizu |
890ddd |
builder->m_modified = true;
|
|
Toshihiro Shimizu |
890ddd |
else if (_toBeSaved)
|
|
Toshihiro Shimizu |
890ddd |
builder->m_modified = false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Now, fetch the image.
|
|
Toshihiro Shimizu |
890ddd |
TImageP img;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (builder->m_cached) {
|
|
Toshihiro Shimizu |
890ddd |
if (modified || builder->isImageCompatible(imFlags, extData)) {
|
|
Toshihiro Shimizu |
890ddd |
img = TImageCache::instance()->get(id, _toBeModified);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(img);
|
|
Toshihiro Shimizu |
890ddd |
if (img)
|
|
Toshihiro Shimizu |
890ddd |
return img;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Lock for image building
|
|
Toshihiro Shimizu |
890ddd |
QWriteLocker imageBuildingLocker(&builder->m_imageBuildingLock);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//As multiple threads may block on filesLocker, re-check if the image is now available
|
|
Toshihiro Shimizu |
890ddd |
if (builder->m_cached) {
|
|
Toshihiro Shimizu |
890ddd |
if (modified || builder->isImageCompatible(imFlags, extData)) {
|
|
Toshihiro Shimizu |
890ddd |
img = TImageCache::instance()->get(id, _toBeModified);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(img);
|
|
Toshihiro Shimizu |
890ddd |
if (img)
|
|
Toshihiro Shimizu |
890ddd |
return img;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// The image was either not available or not conforming to the required specifications.
|
|
Toshihiro Shimizu |
890ddd |
// We have to build it now, then.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Build the image
|
|
Toshihiro Shimizu |
890ddd |
img = builder->build(imFlags, extData);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (img && _putInCache) {
|
|
Toshihiro Shimizu |
890ddd |
builder->m_cached = true;
|
|
Toshihiro Shimizu |
890ddd |
builder->m_modified = _toBeModified;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TImageCache::instance()->add(id, img, true);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return img;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
// load icon (and image) data of all frames into cache
|
|
Toshihiro Shimizu |
890ddd |
void ImageManager::loadAllTlvIconsAndPutInCache(TXshSimpleLevel *level, vector<tframeid> fids, vector<string> iconIds, bool cacheImagesAsWell)</string></tframeid>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (fids.empty() || iconIds.empty())
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
//number of fid and iconId should be the same
|
|
Toshihiro Shimizu |
890ddd |
if ((int)fids.size() != (int)iconIds.size())
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//obtain ImageLoader with the first fId
|
|
Toshihiro Shimizu |
890ddd |
TImageInfo info;
|
|
Toshihiro Shimizu |
890ddd |
std::map<string, imagebuilderp="">::iterator it = m_imp->m_builders.find(level->getImageId(fids[0]));</string,>
|
|
Toshihiro Shimizu |
890ddd |
if (it != m_imp->m_builders.end()) {
|
|
Toshihiro Shimizu |
890ddd |
const ImageBuilderP &builder = it->second;
|
|
Toshihiro Shimizu |
890ddd |
assert(builder);
|
|
Toshihiro Shimizu |
890ddd |
assert(builder->getRefCount() > 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//this function in reimpremented only in ImageLoader
|
|
Toshihiro Shimizu |
890ddd |
builder->buildAllIconsAndPutInCache(level, fids, iconIds, cacheImagesAsWell);
|
|
Toshihiro Shimizu |
890ddd |
builder->getInfo(info, ImageManager::none, 0);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (cacheImagesAsWell) {
|
|
Toshihiro Shimizu |
890ddd |
// reset the savebox
|
|
Toshihiro Shimizu |
890ddd |
info.m_x0 = info.m_y0 = 0;
|
|
Toshihiro Shimizu |
890ddd |
info.m_x1 = info.m_lx - 1;
|
|
Toshihiro Shimizu |
890ddd |
info.m_y1 = info.m_ly - 1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// put flags to all builders
|
|
Toshihiro Shimizu |
890ddd |
for (int f = 0; f < fids.size(); f++) {
|
|
Toshihiro Shimizu |
890ddd |
std::map<string, imagebuilderp="">::iterator it = m_imp->m_builders.find(level->getImageId(fids[f]));</string,>
|
|
Toshihiro Shimizu |
890ddd |
if (it != m_imp->m_builders.end()) {
|
|
Toshihiro Shimizu |
890ddd |
const ImageBuilderP &builder = it->second;
|
|
Toshihiro Shimizu |
890ddd |
builder->setImageCachedAndModified();
|
|
Toshihiro Shimizu |
890ddd |
builder->m_info = info;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool ImageManager::invalidate(const string &id)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
QWriteLocker locker(&m_imp->m_tableLock);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::map<string, imagebuilderp="">::iterator it = m_imp->m_builders.find(id);</string,>
|
|
Toshihiro Shimizu |
890ddd |
if (it == m_imp->m_builders.end())
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ImageBuilderP &builder = it->second;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
builder->invalidate();
|
|
Toshihiro Shimizu |
890ddd |
builder->m_cached = builder->m_modified = false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TImageCache::instance()->remove(id);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool ImageManager::setImage(const string &id, const TImageP &img)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (!img)
|
|
Toshihiro Shimizu |
890ddd |
return invalidate(id);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QWriteLocker locker(&m_imp->m_tableLock);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::map<string, imagebuilderp="">::iterator it = m_imp->m_builders.find(id);</string,>
|
|
Toshihiro Shimizu |
890ddd |
if (it == m_imp->m_builders.end())
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ImageBuilderP &builder = it->second;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
builder->invalidate(); // WARNING: Not all infos are correctly restored
|
|
Toshihiro Shimizu |
890ddd |
ImageBuilder::setImageInfo(builder->m_info, img.getPointer()); // from supplied image - must investigate further...
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TImageCache::instance()->add(id, img, true);
|
|
Toshihiro Shimizu |
890ddd |
builder->m_cached = builder->m_modified = true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ImageBuilder *ImageManager::getBuilder(const string &id)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
QWriteLocker locker(&m_imp->m_tableLock);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::map<string, imagebuilderp="">::iterator it = m_imp->m_builders.find(id);</string,>
|
|
Toshihiro Shimizu |
890ddd |
return (it == m_imp->m_builders.end()) ? (ImageBuilder *)0 : it->second.getPointer();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool ImageManager::isCached(const string &id)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
QWriteLocker locker(&m_imp->m_tableLock);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::map<string, imagebuilderp="">::iterator it = m_imp->m_builders.find(id);</string,>
|
|
Toshihiro Shimizu |
890ddd |
return (it == m_imp->m_builders.end()) ? false : it->second->m_cached;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool ImageManager::isModified(const string &id)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
QWriteLocker locker(&m_imp->m_tableLock);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::map<string, imagebuilderp="">::iterator it = m_imp->m_builders.find(id);</string,>
|
|
Toshihiro Shimizu |
890ddd |
return (it == m_imp->m_builders.end()) ? false : it->second->m_modified;
|
|
Toshihiro Shimizu |
890ddd |
}
|