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