|
tomosu |
eea0ac |
#include <sstream></sstream>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tsystem.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcachedlevel.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tcodec.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "texception.h"
|
|
Toshihiro Shimizu |
890ddd |
//#include "tcachedlevel.h"
|
|
Toshihiro Shimizu |
890ddd |
//#include "tcodec.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tconvert.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef LINUX
|
|
Toshihiro Shimizu |
890ddd |
#include "texception.h"
|
|
Toshihiro Shimizu |
890ddd |
//#include "tsystem.h"
|
|
Toshihiro Shimizu |
890ddd |
#include <unistd.h></unistd.h>
|
|
Toshihiro Shimizu |
890ddd |
#include <sys mman.h=""></sys>
|
|
Toshihiro Shimizu |
890ddd |
#include <sys types.h=""></sys>
|
|
Toshihiro Shimizu |
890ddd |
#include <sys stat.h=""></sys>
|
|
Toshihiro Shimizu |
890ddd |
#include <fcntl.h></fcntl.h>
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef MACOSX
|
|
Toshihiro Shimizu |
890ddd |
#include "sys/mman.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "sys/errno.h"
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#define DWORDLONG_LO_DWORD(dwl64) ((DWORD)(dwl64))
|
|
Toshihiro Shimizu |
890ddd |
#define DWORDLONG_HI_DWORD(dwl64) ((DWORD)(dwl64 >> 32))
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
// TDiskCachePersist
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class ImpPD {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
ImpPD(const TFilePath &fn)
|
|
Shinya Kitaoka |
120a6e |
: m_fname(fn)
|
|
Shinya Kitaoka |
120a6e |
, m_chunkSize(0)
|
|
Shinya Kitaoka |
120a6e |
, m_currentFileSize(0)
|
|
Shinya Kitaoka |
120a6e |
, m_fileMapAddress(0)
|
|
Shinya Kitaoka |
120a6e |
, m_mapOffset(0) {
|
|
Shinya Kitaoka |
120a6e |
TFileStatus fileStatus(fn);
|
|
Shinya Kitaoka |
120a6e |
if (fileStatus.doesExist())
|
|
Shinya Kitaoka |
120a6e |
m_currentFileSize = fileStatus.getSize();
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
m_currentFileSize = ImpPD::m_defaultFileSize;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
virtual ~ImpPD() {}
|
|
Shinya Kitaoka |
120a6e |
virtual void openFile(const TFilePath &, TINT64 fileSize) = 0;
|
|
Shinya Kitaoka |
120a6e |
virtual void setCurrentView(int pos, int &newLowPos, int &newHiPos) = 0;
|
|
Shinya Kitaoka |
120a6e |
TFilePath m_fname;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TINT64 m_chunkSize;
|
|
Shinya Kitaoka |
120a6e |
TINT64 m_currentFileSize;
|
|
Shinya Kitaoka |
120a6e |
void *m_fileMapAddress;
|
|
Shinya Kitaoka |
120a6e |
TINT64 m_mapOffset;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// quantita' espresse in byte
|
|
Shinya Kitaoka |
120a6e |
static TINT64 m_defaultFileSize;
|
|
Shinya Kitaoka |
120a6e |
TUINT32 m_viewSize;
|
|
Shinya Kitaoka |
120a6e |
TINT64 m_reallocSize;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TINT64 ImpPD::m_defaultFileSize(100 * 1024 * 1024);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class TDiskCachePersist::Imp {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
Imp(const TFilePath &fp);
|
|
Shinya Kitaoka |
120a6e |
~Imp();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool put(int frame, UCHAR *data, TUINT32 dataSize);
|
|
Shinya Kitaoka |
120a6e |
UCHAR *get(int pos, TUINT32 *size);
|
|
Shinya Kitaoka |
120a6e |
void openFile(const TFilePath &fp, TINT64 fileSize);
|
|
Shinya Kitaoka |
120a6e |
void setCurrentView(int frame) {
|
|
Shinya Kitaoka |
120a6e |
if (!m_force && ((m_lowFrame <= frame) && (frame < m_hiFrame)))
|
|
Shinya Kitaoka |
120a6e |
return; // la vista corrente gia' copre il frame
|
|
Shinya Kitaoka |
120a6e |
m_force = false;
|
|
Shinya Kitaoka |
120a6e |
m_impPD->setCurrentView(frame, m_lowFrame, m_hiFrame);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ImpPD *m_impPD;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int m_lowFrame, m_hiFrame;
|
|
Shinya Kitaoka |
120a6e |
TThread::Mutex m_mutex;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool m_force;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef WIN32
|
|
Shinya Kitaoka |
120a6e |
class ImpPDW : public ImpPD {
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
string getLastErrorMessage() {
|
|
Shinya Kitaoka |
120a6e |
LPVOID lpMsgBuf;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
DWORD err = GetLastError();
|
|
Shinya Kitaoka |
120a6e |
FormatMessage(
|
|
Shinya Kitaoka |
120a6e |
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
|
|
Shinya Kitaoka |
120a6e |
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
Shinya Kitaoka |
120a6e |
NULL, err,
|
|
Shinya Kitaoka |
120a6e |
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
|
Shinya Kitaoka |
120a6e |
(LPTSTR)&lpMsgBuf, 0, NULL);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
string msg((LPCTSTR)lpMsgBuf);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Free the buffer.
|
|
Shinya Kitaoka |
120a6e |
LocalFree(lpMsgBuf);
|
|
Shinya Kitaoka |
120a6e |
return msg;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
ImpPDW(const TFilePath &fp);
|
|
Shinya Kitaoka |
120a6e |
~ImpPDW();
|
|
Shinya Kitaoka |
120a6e |
void openFile(const TFilePath &fname, TINT64 fileSize);
|
|
Shinya Kitaoka |
120a6e |
void setCurrentView(int pos, int &newLowPos, int &newHiPos);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
HANDLE m_hFile;
|
|
Shinya Kitaoka |
120a6e |
HANDLE m_hMap;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
SYSTEM_INFO m_systemInfo;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class ImpPDX : public ImpPD {
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
class TCachedLevelException : public TException {
|
|
Shinya Kitaoka |
120a6e |
static string msgFromErrorCode(int errorCode) {
|
|
Shinya Kitaoka |
120a6e |
switch (errorCode) {
|
|
Shinya Kitaoka |
120a6e |
case EBADF:
|
|
Shinya Kitaoka |
120a6e |
return " fd is not a valid file descriptor (and MAP_ANONYMOUS was "
|
|
Shinya Kitaoka |
120a6e |
"not set).";
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
case EACCES_MAP_PRIVATE:
|
|
Shinya Kitaoka |
120a6e |
return "Map private was requested, but fd is not open for reading. Or MAP_SHARED
|
|
Shinya Kitaoka |
120a6e |
was requested and PROT_WRITE is set, but fd is not open in read/write O_RDWR)
|
|
Shinya Kitaoka |
120a6e |
mode.";
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
case EINVAL:
|
|
Shinya Kitaoka |
120a6e |
return "We don't like start or length or offset. (E.g., they are "
|
|
Shinya Kitaoka |
120a6e |
"too large, or not aligned on a PAGESIZE boundary.)";
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case ETXTBSY:
|
|
Shinya Kitaoka |
120a6e |
return "MAP_DENYWRITE was set but the object specified by fd is open "
|
|
Shinya Kitaoka |
120a6e |
"for writing.";
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case EAGAIN:
|
|
Shinya Kitaoka |
120a6e |
return "The file has been locked, or too much memory has been "
|
|
Shinya Kitaoka |
120a6e |
"locked.";
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case ENOMEM:
|
|
Shinya Kitaoka |
120a6e |
return "No memory is available.";
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
default:
|
|
Shinya Kitaoka |
120a6e |
char *sysErr = strerror(errorCode);
|
|
Shinya Kitaoka |
120a6e |
ostringstream os;
|
|
Shinya Kitaoka |
120a6e |
os << errorCode << '\0';
|
|
Shinya Kitaoka |
120a6e |
return string(sysErr) + "(" + os.str() + ")";
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return "";
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
public:
|
|
Shinya Kitaoka |
120a6e |
TCachedLevelException(int errorCode)
|
|
Shinya Kitaoka |
120a6e |
: TException(msgFromErrorCode(errorCode)) {}
|
|
Shinya Kitaoka |
120a6e |
~TCachedLevelException() {}
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
ImpPDX(const TFilePath &fp);
|
|
Shinya Kitaoka |
120a6e |
~ImpPDX();
|
|
Shinya Kitaoka |
120a6e |
void openFile(const TFilePath &fname, TINT64 fileSize);
|
|
Shinya Kitaoka |
120a6e |
void setCurrentView(int pos, int &newLowPos, int &newHiPos);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
int m_fd;
|
|
Shinya Kitaoka |
120a6e |
size_t m_pageSize;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// HIGH
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TDiskCachePersist::TDiskCachePersist(TRasterCodec *codec, const TFilePath &fp)
|
|
Shinya Kitaoka |
120a6e |
: TCachePersist(codec), m_imp(new Imp(fp)) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TDiskCachePersist::~TDiskCachePersist() { delete m_imp; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDiskCachePersist::setFrameSize(int lx, int ly, int bpp) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_impPD->m_chunkSize = lx * ly * (bpp >> 3) + m_codec->getHeaderSize();
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_force = true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRasterP TDiskCachePersist::doGetRaster(int frame) {
|
|
Shinya Kitaoka |
120a6e |
TRasterP rasP;
|
|
Shinya Kitaoka |
120a6e |
TUINT32 size;
|
|
Shinya Kitaoka |
120a6e |
UCHAR *src = m_imp->get(frame, &size);
|
|
Shinya Kitaoka |
120a6e |
m_codec->decompress(src, size, rasP);
|
|
Shinya Kitaoka |
120a6e |
delete[] src;
|
|
Shinya Kitaoka |
120a6e |
return rasP;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TDiskCachePersist::doGetRaster(int frame, TRaster32P &ras) const {
|
|
Shinya Kitaoka |
120a6e |
assert(false);
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TDiskCachePersist::doPutRaster(int frame, const TRasterP &ras) {
|
|
Shinya Kitaoka |
120a6e |
UCHAR *outData = 0;
|
|
Shinya Kitaoka |
120a6e |
TINT32 outDataSize = 0;
|
|
Shinya Kitaoka |
120a6e |
m_codec->compress(ras, 1, &outData, outDataSize);
|
|
Shinya Kitaoka |
120a6e |
bool cached = m_imp->put(frame, outData, outDataSize);
|
|
Shinya Kitaoka |
120a6e |
delete[] outData;
|
|
Shinya Kitaoka |
120a6e |
return cached;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
UCHAR *TDiskCachePersist::getRawData(int frame, TINT32 &size, int &lx,
|
|
Shinya Kitaoka |
120a6e |
int &ly) {
|
|
Shinya Kitaoka |
120a6e |
TUINT32 inDataSize;
|
|
Shinya Kitaoka |
120a6e |
UCHAR *src = m_imp->get(frame, &inDataSize);
|
|
Shinya Kitaoka |
120a6e |
return m_codec->removeHeader(src, inDataSize, size, lx, ly);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
// MEDIUM
|
|
Shinya Kitaoka |
120a6e |
TDiskCachePersist::Imp::Imp(const TFilePath &fp) : m_impPD(0) {
|
|
Toshihiro Shimizu |
890ddd |
#ifdef WIN32
|
|
Shinya Kitaoka |
120a6e |
m_impPD = new ImpPDW(fp);
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Shinya Kitaoka |
120a6e |
m_impPD = new ImpPDX(fp);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
m_impPD->m_currentFileSize = TFileStatus(fp).doesExist()
|
|
Shinya Kitaoka |
120a6e |
? TFileStatus(fp).getSize()
|
|
Shinya Kitaoka |
120a6e |
: 0; // per gli arrotondamenti...
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TDiskCachePersist::Imp::~Imp() { delete m_impPD; }
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
// LOW
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef WIN32
|
|
Shinya Kitaoka |
120a6e |
ImpPDW::ImpPDW(const TFilePath &fp) : ImpPD(fp), m_hFile(0), m_hMap(0) {
|
|
Shinya Kitaoka |
120a6e |
GetSystemInfo(&m_systemInfo);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_viewSize = 100 * 1024 * 1024;
|
|
Shinya Kitaoka |
120a6e |
m_reallocSize = 250 * 1024 * 1024;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TINT64 allocUnitCount = m_reallocSize / m_systemInfo.dwAllocationGranularity;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// rendo m_reallocSize multiplo di m_systemInfo.dwAllocationGranularity
|
|
Shinya Kitaoka |
120a6e |
if ((m_reallocSize % m_systemInfo.dwAllocationGranularity) != 0)
|
|
Shinya Kitaoka |
120a6e |
++allocUnitCount;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_reallocSize = allocUnitCount * m_systemInfo.dwAllocationGranularity;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TINT64 fileSize = m_defaultFileSize;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFileStatus fileStatus(fp);
|
|
Shinya Kitaoka |
120a6e |
if (fileStatus.doesExist()) fileSize = fileStatus.getSize();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
try {
|
|
Shinya Kitaoka |
120a6e |
openFile(fp, fileSize);
|
|
Shinya Kitaoka |
120a6e |
} catch (TException &e) {
|
|
Shinya Kitaoka |
120a6e |
m_currentFileSize = 0;
|
|
Shinya Kitaoka |
120a6e |
throw e;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_currentFileSize = fileSize;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ImpPDW::~ImpPDW() {
|
|
Shinya Kitaoka |
120a6e |
if (m_fileMapAddress) UnmapViewOfFile(m_fileMapAddress);
|
|
Shinya Kitaoka |
120a6e |
CloseHandle(m_hMap);
|
|
Shinya Kitaoka |
120a6e |
CloseHandle(m_hFile);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ImpPDW::openFile(const TFilePath &fname, TINT64 fileSize) {
|
|
Shinya Kitaoka |
120a6e |
DWORD dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
|
|
Shinya Kitaoka |
120a6e |
DWORD dwShareMode = 0; // dwShareMode == 0 --> accesso esclusivo
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// lpSecurityAttributes == NULL --> l'handle non puo' essere
|
|
Shinya Kitaoka |
120a6e |
// ereditato da processi figli
|
|
Shinya Kitaoka |
120a6e |
LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
DWORD dwCreationDisposition = OPEN_ALWAYS; // CREATE_ALWAYS;
|
|
Shinya Kitaoka |
120a6e |
DWORD dwFlagsAndAttributes =
|
|
Shinya Kitaoka |
120a6e |
FILE_FLAG_SEQUENTIAL_SCAN; // FILE_ATTRIBUTE_NORMAL;//
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
HANDLE hTemplateFile = NULL;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_hFile = CreateFileW(fname.getWideString().c_str(), // file name
|
|
Shinya Kitaoka |
120a6e |
dwDesiredAccess, // access mode
|
|
Shinya Kitaoka |
120a6e |
dwShareMode, // share mode
|
|
Shinya Kitaoka |
120a6e |
NULL, // SD
|
|
Shinya Kitaoka |
120a6e |
dwCreationDisposition, // how to create
|
|
Shinya Kitaoka |
120a6e |
dwFlagsAndAttributes, // file attributes
|
|
Shinya Kitaoka |
120a6e |
hTemplateFile // handle to template file
|
|
Shinya Kitaoka |
120a6e |
);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_hFile == INVALID_HANDLE_VALUE) {
|
|
Shinya Kitaoka |
120a6e |
string errMsg = getLastErrorMessage();
|
|
Shinya Kitaoka |
120a6e |
throw TException(wstring(L"Unable to open cache file: ") +
|
|
Shinya Kitaoka |
120a6e |
fname.getWideString() + L"\n" + toWideString(errMsg));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
DWORD flProtect = PAGE_READWRITE;
|
|
Shinya Kitaoka |
120a6e |
DWORD dwMaximumSizeHigh = DWORDLONG_HI_DWORD(fileSize);
|
|
Shinya Kitaoka |
120a6e |
DWORD dwMaximumSizeLow = DWORDLONG_LO_DWORD(fileSize);
|
|
Shinya Kitaoka |
120a6e |
LPCTSTR lpName = NULL; // l'oggetto non ha nome
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_hMap = CreateFileMapping(m_hFile, // handle to file
|
|
Shinya Kitaoka |
120a6e |
NULL, // security
|
|
Shinya Kitaoka |
120a6e |
flProtect, // protection
|
|
Shinya Kitaoka |
120a6e |
dwMaximumSizeHigh, // high-order DWORD of size
|
|
Shinya Kitaoka |
120a6e |
dwMaximumSizeLow, // low-order DWORD of size
|
|
Shinya Kitaoka |
120a6e |
lpName // object name
|
|
Shinya Kitaoka |
120a6e |
);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_hMap == NULL) {
|
|
Shinya Kitaoka |
120a6e |
string errMsg = getLastErrorMessage();
|
|
Shinya Kitaoka |
120a6e |
CloseHandle(m_hFile);
|
|
Shinya Kitaoka |
120a6e |
m_hFile = 0;
|
|
Shinya Kitaoka |
120a6e |
throw TException("Unable to create file mapping. " + errMsg);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ImpPDW::setCurrentView(int frame, int &newLowFrame, int &newHiFrame) {
|
|
Shinya Kitaoka |
120a6e |
if (m_fileMapAddress) UnmapViewOfFile(m_fileMapAddress);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
newLowFrame = frame;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
newHiFrame = newLowFrame + TINT32(m_viewSize / m_chunkSize);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
DWORD allocGranularity = m_systemInfo.dwAllocationGranularity;
|
|
Shinya Kitaoka |
120a6e |
TINT64 viewOffset =
|
|
Shinya Kitaoka |
120a6e |
(TINT64(newLowFrame * m_chunkSize) / allocGranularity) * allocGranularity;
|
|
Shinya Kitaoka |
120a6e |
m_mapOffset = newLowFrame * m_chunkSize - viewOffset;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TINT64 fileSize = newHiFrame * m_chunkSize;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if ((fileSize > m_currentFileSize) || !m_hMap) // devo riallocare!
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
CloseHandle(m_hMap);
|
|
Shinya Kitaoka |
120a6e |
m_hMap = 0;
|
|
Shinya Kitaoka |
120a6e |
CloseHandle(m_hFile);
|
|
Shinya Kitaoka |
120a6e |
m_hFile = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TINT64 allocUnitCount = fileSize / m_reallocSize;
|
|
Shinya Kitaoka |
120a6e |
// rendo fileSize multiplo di m_reallocSize
|
|
Shinya Kitaoka |
120a6e |
if ((fileSize % m_reallocSize) != 0) ++allocUnitCount;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
fileSize = allocUnitCount * m_reallocSize;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
openFile(m_fname, fileSize);
|
|
Shinya Kitaoka |
120a6e |
m_currentFileSize = fileSize;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
DWORD dwDesiredAccess = FILE_MAP_WRITE;
|
|
Shinya Kitaoka |
120a6e |
m_fileMapAddress = MapViewOfFile(
|
|
Shinya Kitaoka |
120a6e |
m_hMap, // handle to file-mapping object
|
|
Shinya Kitaoka |
120a6e |
dwDesiredAccess, // access mode: Write permission
|
|
Shinya Kitaoka |
120a6e |
DWORDLONG_HI_DWORD(
|
|
Shinya Kitaoka |
120a6e |
viewOffset), // high-order DWORD of offset: Max. object size.
|
|
Shinya Kitaoka |
120a6e |
DWORDLONG_LO_DWORD(
|
|
Shinya Kitaoka |
120a6e |
viewOffset), // low-order DWORD of offset: Size of hFile.
|
|
Shinya Kitaoka |
120a6e |
m_viewSize); // number of bytes to map
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_fileMapAddress == NULL) {
|
|
Shinya Kitaoka |
120a6e |
string errMsg = getLastErrorMessage();
|
|
Shinya Kitaoka |
120a6e |
CloseHandle(m_hMap);
|
|
Shinya Kitaoka |
120a6e |
m_hMap = 0;
|
|
Shinya Kitaoka |
120a6e |
CloseHandle(m_hFile);
|
|
Shinya Kitaoka |
120a6e |
m_hFile = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
throw TException("Unable to memory map cache file. " + errMsg);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ImpPDX::ImpPDX(const TFilePath &fp) : ImpPD(fp), m_fd(-1) {
|
|
Shinya Kitaoka |
120a6e |
// std::cout << "cache file " << toString(m_fname.getFullPath()) << std::endl;
|
|
Shinya Kitaoka |
120a6e |
m_pageSize = getpagesize();
|
|
Shinya Kitaoka |
120a6e |
openFile(m_fname, 0);
|
|
Shinya Kitaoka |
120a6e |
assert(m_fd >= 0);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ImpPDX::~ImpPDX() {
|
|
Shinya Kitaoka |
120a6e |
if (m_fileMapAddress) munmap(m_fileMapAddress, m_viewSize);
|
|
Shinya Kitaoka |
120a6e |
close(m_fd);
|
|
Shinya Kitaoka |
120a6e |
m_fd = 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ImpPDX::openFile(const TFilePath &fname, TINT64 fileSize) {
|
|
Shinya Kitaoka |
120a6e |
assert(0);
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Toshihiro Shimizu |
890ddd |
string fn(toString(fname.getWideString()));
|
|
Toshihiro Shimizu |
890ddd |
std::cout << "open " << fn << std::endl;
|
|
Toshihiro Shimizu |
890ddd |
m_fd = open(fn.c_str(), O_RDWR|O_CREAT, 00666);
|
|
Toshihiro Shimizu |
890ddd |
assert(m_fd >=0);
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ImpPDX::setCurrentView(int pos, int &newLowPos, int &newHiPos) {
|
|
Shinya Kitaoka |
120a6e |
newLowPos = pos;
|
|
Shinya Kitaoka |
120a6e |
newHiPos = newLowPos + (m_viewSize / m_chunkSize);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(m_fd >= 0);
|
|
Shinya Kitaoka |
120a6e |
if (m_fileMapAddress) // previous view...
|
|
Shinya Kitaoka |
120a6e |
if (munmap(m_fileMapAddress, m_viewSize) != 0)
|
|
Shinya Kitaoka |
120a6e |
throw TCachedLevelException(errno);
|
|
Shinya Kitaoka |
120a6e |
void *start = 0;
|
|
Shinya Kitaoka |
120a6e |
int flags = MAP_SHARED;
|
|
Shinya Kitaoka |
120a6e |
size_t viewOffset = ((newLowPos * m_chunkSize) / m_pageSize) * m_pageSize;
|
|
Shinya Kitaoka |
120a6e |
m_mapOffset = newLowPos * m_chunkSize - viewOffset;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(!"controllare le dimensioni");
|
|
Shinya Kitaoka |
120a6e |
unsigned long lastByte =
|
|
Shinya Kitaoka |
120a6e |
(unsigned long)(((newHiPos * m_chunkSize) / (double)m_pageSize + 0.5) *
|
|
Shinya Kitaoka |
120a6e |
m_pageSize);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (lastByte > m_currentFileSize) // devo riallocare!
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
unsigned long bu =
|
|
Shinya Kitaoka |
120a6e |
(unsigned long)((lastByte / (double)m_reallocSize + 0.5) *
|
|
Shinya Kitaoka |
120a6e |
m_reallocSize);
|
|
Shinya Kitaoka |
120a6e |
bu = (unsigned long)((bu / (double)m_pageSize + 0.5) * m_pageSize);
|
|
Shinya Kitaoka |
120a6e |
// m_maxFileSize = tmax(m_maxFileSize + m_reallocFileSize, lastByte);
|
|
Shinya Kitaoka |
120a6e |
m_currentFileSize += bu;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::cout << "new cache size " << m_currentFileSize << std::endl;
|
|
Shinya Kitaoka |
120a6e |
if (lseek(m_fd, m_currentFileSize, SEEK_SET) == -1)
|
|
Shinya Kitaoka |
120a6e |
throw TCachedLevelException(errno);
|
|
Shinya Kitaoka |
120a6e |
if (write(m_fd, "", 1) == -1) throw TCachedLevelException(errno);
|
|
Shinya Kitaoka |
120a6e |
if (ftruncate(m_fd, m_currentFileSize) == -1)
|
|
Shinya Kitaoka |
120a6e |
throw TCachedLevelException(errno);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_fileMapAddress =
|
|
Shinya Kitaoka |
120a6e |
mmap(start, m_viewSize, PROT_READ | PROT_WRITE, flags, m_fd, viewOffset);
|
|
Shinya Kitaoka |
120a6e |
if (m_fileMapAddress == (void *)-1) throw TCachedLevelException(errno);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
#ifndef WIN32
|
|
Toshihiro Shimizu |
890ddd |
#define ULONGLONG unsigned long long
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
bool TDiskCachePersist::Imp::put(int frame, UCHAR *data, TUINT32 dataSize) {
|
|
Shinya Kitaoka |
120a6e |
if (dataSize != m_impPD->m_chunkSize) return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock sl(m_mutex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
setCurrentView(frame);
|
|
Shinya Kitaoka |
120a6e |
ULONGLONG offset = (frame - m_lowFrame) * m_impPD->m_chunkSize;
|
|
Shinya Kitaoka |
120a6e |
UCHAR *dst = (UCHAR *)m_impPD->m_fileMapAddress + offset;
|
|
Shinya Kitaoka |
120a6e |
memcpy(dst + m_impPD->m_mapOffset, data, dataSize);
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
UCHAR *TDiskCachePersist::Imp::get(int pos, TUINT32 *size) {
|
|
Shinya Kitaoka |
120a6e |
UCHAR *ret = new UCHAR[TINT32(m_impPD->m_chunkSize)];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock sl(m_mutex);
|
|
Shinya Kitaoka |
120a6e |
setCurrentView(pos);
|
|
Shinya Kitaoka |
120a6e |
ULONGLONG offset = (pos - m_lowFrame) * m_impPD->m_chunkSize;
|
|
Shinya Kitaoka |
120a6e |
UCHAR *src =
|
|
Shinya Kitaoka |
120a6e |
(UCHAR *)m_impPD->m_fileMapAddress + offset + m_impPD->m_mapOffset;
|
|
Shinya Kitaoka |
120a6e |
memcpy(ret, src, TINT32(m_impPD->m_chunkSize));
|
|
Shinya Kitaoka |
120a6e |
*size = TUINT32(m_impPD->m_chunkSize);
|
|
Shinya Kitaoka |
120a6e |
return ret;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
// TRasterCache
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class TRasterCache::Data {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
Data(TCachePersist *cp)
|
|
Shinya Kitaoka |
120a6e |
: m_cp(cp)
|
|
Shinya Kitaoka |
120a6e |
, m_size(0, 0)
|
|
Shinya Kitaoka |
120a6e |
, m_prefetchEnabled(false)
|
|
Shinya Kitaoka |
120a6e |
, m_prefetchedFrame(-1)
|
|
Shinya Kitaoka |
120a6e |
, m_frameToPrefetch(-1)
|
|
Shinya Kitaoka |
120a6e |
, m_preLoader(1, true) {}
|
|
Shinya Kitaoka |
120a6e |
~Data() {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
class FrameData {
|
|
Shinya Kitaoka |
120a6e |
public:
|
|
Shinya Kitaoka |
120a6e |
bool m_valid;
|
|
Shinya Kitaoka |
120a6e |
// int m_size; // dimensione in byte del raster codificato
|
|
Shinya Kitaoka |
120a6e |
~FrameData() {}
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool isFrameCached(int frame) const;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TDimension m_size; // dimensioni dei raster in cache
|
|
Shinya Kitaoka |
120a6e |
int m_bpp;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
typedef map<int, framedata=""> Status;</int,>
|
|
Shinya Kitaoka |
120a6e |
Status m_status;
|
|
Shinya Kitaoka |
120a6e |
TCachePersist *m_cp;
|
|
Shinya Kitaoka |
120a6e |
TThread::Mutex m_accessMutex;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TThread::Executor m_preLoader;
|
|
Shinya Kitaoka |
120a6e |
bool m_prefetchEnabled;
|
|
Shinya Kitaoka |
120a6e |
int m_prefetchedFrame;
|
|
Shinya Kitaoka |
120a6e |
int m_frameToPrefetch;
|
|
Shinya Kitaoka |
120a6e |
TRasterP m_prefetchedRas;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TRasterCache::Data::isFrameCached(int frame) const {
|
|
Shinya Kitaoka |
120a6e |
// volutamente senza ScopedLock
|
|
Shinya Kitaoka |
120a6e |
Data::Status::const_iterator it = m_status.find(frame);
|
|
Shinya Kitaoka |
120a6e |
if (it == m_status.end()) return false;
|
|
Shinya Kitaoka |
120a6e |
Data::FrameData fd = it->second;
|
|
Shinya Kitaoka |
120a6e |
return fd.m_valid;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class Load : public TThread::Runnable {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
Load(int frameToPrefetch, TCachePersist *cp, int &prefetchedFrame,
|
|
Shinya Kitaoka |
120a6e |
TRasterP &prefetchedRas)
|
|
Shinya Kitaoka |
120a6e |
: m_frame(frameToPrefetch)
|
|
Shinya Kitaoka |
120a6e |
, m_cp(cp)
|
|
Shinya Kitaoka |
120a6e |
, m_prefetchedFrame(prefetchedFrame)
|
|
Shinya Kitaoka |
120a6e |
, m_prefetchedRas(prefetchedRas) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void run();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
int m_frame;
|
|
Shinya Kitaoka |
120a6e |
TCachePersist *m_cp;
|
|
Shinya Kitaoka |
120a6e |
int &m_prefetchedFrame;
|
|
Shinya Kitaoka |
120a6e |
TRasterP &m_prefetchedRas;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void Load::run() {
|
|
Shinya Kitaoka |
120a6e |
m_prefetchedRas = m_cp->doGetRaster(m_frame);
|
|
Shinya Kitaoka |
120a6e |
m_prefetchedFrame = m_frame;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRasterCache::TRasterCache(TCachePersist *cp) : m_data(new Data(cp)) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRasterCache::~TRasterCache() { delete m_data; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
void TRasterCache::setMode(const TDimension &size, int bpp) {
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock sl(m_data->m_accessMutex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_data->m_size = size; // dimensioni dei raster in cache
|
|
Shinya Kitaoka |
120a6e |
m_data->m_bpp = bpp;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_data->m_cp->setFrameSize(size.lx, size.ly, bpp);
|
|
Shinya Kitaoka |
120a6e |
invalidate();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TRasterCache::getMode(TDimension &size, int &bpp) const {
|
|
Shinya Kitaoka |
120a6e |
size = m_data->m_size; // dimensioni dei raster in cache
|
|
Shinya Kitaoka |
120a6e |
bpp = m_data->m_bpp;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRasterP TRasterCache::getRaster(int frame) const {
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock sl(m_data->m_accessMutex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_data->m_prefetchEnabled) {
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
if (frame == m_data->m_frameToPrefetch)
|
|
Shinya Kitaoka |
120a6e |
m_data->m_preLoader.wait();
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
m_data->m_preLoader.clear();
|
|
Shinya Kitaoka |
120a6e |
// m_data->m_preLoader.cancel();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRasterP ras;
|
|
Shinya Kitaoka |
120a6e |
if (frame == m_data->m_prefetchedFrame)
|
|
Shinya Kitaoka |
120a6e |
ras = m_data->m_prefetchedRas;
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Shinya Kitaoka |
120a6e |
ras = m_data->m_cp->doGetRaster(frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (isFrameCached(frame + 1)) {
|
|
Shinya Kitaoka |
120a6e |
// il frame successivo a quello richiesto e' nella cache
|
|
Shinya Kitaoka |
120a6e |
// -> avvia il prefetch di tale raster
|
|
Shinya Kitaoka |
120a6e |
m_data->m_frameToPrefetch = frame + 1;
|
|
Shinya Kitaoka |
120a6e |
m_data->m_preLoader.addTask(
|
|
Shinya Kitaoka |
120a6e |
new Load(m_data->m_frameToPrefetch, m_data->m_cp,
|
|
Shinya Kitaoka |
120a6e |
m_data->m_prefetchedFrame, m_data->m_prefetchedRas));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return ras;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
return m_data->m_cp->doGetRaster(frame);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TRasterCache::getRaster(int frame, TRaster32P &ras) const {
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock sl(m_data->m_accessMutex);
|
|
Shinya Kitaoka |
120a6e |
if (m_data->isFrameCached(frame)) {
|
|
Shinya Kitaoka |
120a6e |
bool rc = m_data->m_cp->doGetRaster(frame, ras);
|
|
Shinya Kitaoka |
120a6e |
assert(rc);
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TRasterCache::putRaster(int frame, const TRasterP &ras) {
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock sl(m_data->m_accessMutex);
|
|
Shinya Kitaoka |
120a6e |
Data::Status::iterator it = m_data->m_status.find(frame);
|
|
Shinya Kitaoka |
120a6e |
bool cached = false;
|
|
Shinya Kitaoka |
120a6e |
try {
|
|
Shinya Kitaoka |
120a6e |
cached = m_data->m_cp->doPutRaster(frame, ras);
|
|
Shinya Kitaoka |
120a6e |
} catch (TException &e) {
|
|
Shinya Kitaoka |
120a6e |
if (it != m_data->m_status.end()) {
|
|
Shinya Kitaoka |
120a6e |
Data::FrameData fd;
|
|
Shinya Kitaoka |
120a6e |
fd.m_valid = false;
|
|
Shinya Kitaoka |
120a6e |
m_data->m_status[frame] = fd;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
throw e;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (cached) {
|
|
Shinya Kitaoka |
120a6e |
Data::FrameData fd;
|
|
Shinya Kitaoka |
120a6e |
fd.m_valid = true;
|
|
Shinya Kitaoka |
120a6e |
m_data->m_status[frame] = fd;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
UCHAR *TRasterCache::getRawData(int frame, TINT32 &size, int &lx,
|
|
Shinya Kitaoka |
120a6e |
int &ly) const {
|
|
Shinya Kitaoka |
120a6e |
return m_data->m_cp->getRawData(frame, size, lx, ly);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TRasterCache::isFrameCached(int frame) const {
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock sl(m_data->m_accessMutex);
|
|
Shinya Kitaoka |
120a6e |
return m_data->isFrameCached(frame);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TRasterCache::invalidate() {
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock sl(m_data->m_accessMutex);
|
|
Shinya Kitaoka |
120a6e |
m_data->m_status.clear();
|
|
Shinya Kitaoka |
120a6e |
m_data->m_cp->onInvalidate();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TRasterCache::invalidate(int startFrame, int endFrame) {
|
|
Shinya Kitaoka |
120a6e |
assert(startFrame <= endFrame);
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock sl(m_data->m_accessMutex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Data::Status::iterator low = m_data->m_status.lower_bound(startFrame);
|
|
Shinya Kitaoka |
120a6e |
Data::Status::iterator hi = m_data->m_status.upper_bound(endFrame);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
int count = m_data->m_status.size();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (low != m_data->m_status.end() && hi != m_data->m_status.end()) {
|
|
Shinya Kitaoka |
120a6e |
int ll = low->first;
|
|
Shinya Kitaoka |
120a6e |
int hh = hi->first;
|
|
Shinya Kitaoka |
120a6e |
assert(ll <= hh);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (low != m_data->m_status.end()) {
|
|
Shinya Kitaoka |
120a6e |
m_data->m_status.erase(low, hi);
|
|
Shinya Kitaoka |
120a6e |
m_data->m_cp->onInvalidate(startFrame, endFrame);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TRasterCache::enablePrefetch(bool newState) {
|
|
Shinya Kitaoka |
120a6e |
m_data->m_prefetchEnabled = newState;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TRasterCache::isPrefetchEnabled() const {
|
|
Shinya Kitaoka |
120a6e |
return m_data->m_prefetchEnabled;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TUINT64 TRasterCache::getUsedSpace() { return m_data->m_cp->getUsedSpace(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
// TRamCachePersist
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
class TRamCachePersist::Imp {
|
|
Shinya Kitaoka |
120a6e |
friend class TRamCachePersist;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
Imp() : m_cacheSize(0), m_chunks() {}
|
|
Shinya Kitaoka |
120a6e |
~Imp() {
|
|
Shinya Kitaoka |
120a6e |
for (CompressedChunks::iterator it = m_chunks.begin(); it != m_chunks.end();
|
|
Shinya Kitaoka |
120a6e |
++it) {
|
|
Shinya Kitaoka |
120a6e |
CompressedChunk *cc = it->second;
|
|
Shinya Kitaoka |
120a6e |
m_cacheSize -= cc->m_size;
|
|
Shinya Kitaoka |
120a6e |
delete cc;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
assert(m_cacheSize == 0); // se m_cacheSize > 0 mi sono perso qualche chunk
|
|
Shinya Kitaoka |
120a6e |
// se m_cacheSize < 0 ho liberato 2 volte qualche chunk
|
|
Shinya Kitaoka |
120a6e |
m_chunks.clear();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
class CompressedChunk {
|
|
Shinya Kitaoka |
120a6e |
public:
|
|
Shinya Kitaoka |
120a6e |
CompressedChunk(UCHAR *buffer, int size) : m_buffer(buffer), m_size(size) {}
|
|
Shinya Kitaoka |
120a6e |
~CompressedChunk() { delete[] m_buffer; }
|
|
Shinya Kitaoka |
120a6e |
UCHAR *m_buffer;
|
|
Shinya Kitaoka |
120a6e |
int m_size;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
typedef map<int, *="" compressedchunk=""> CompressedChunks;</int,>
|
|
Shinya Kitaoka |
120a6e |
CompressedChunks m_chunks;
|
|
Shinya Kitaoka |
120a6e |
TUINT64 m_cacheSize;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRamCachePersist::TRamCachePersist(TRasterCodec *codec)
|
|
Shinya Kitaoka |
120a6e |
: TCachePersist(codec), m_imp(new Imp) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRamCachePersist::~TRamCachePersist() { delete m_imp; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRasterP TRamCachePersist::doGetRaster(int frame)
|
|
Shinya Kitaoka |
120a6e |
// void TRamCachePersist::doGetRaster(int frame, const TRasterP &ras)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
120a6e |
Imp::CompressedChunks::const_iterator it = m_imp->m_chunks.find(frame);
|
|
Shinya Kitaoka |
120a6e |
if (it == m_imp->m_chunks.end()) return TRasterP();
|
|
Shinya Kitaoka |
120a6e |
Imp::CompressedChunk *cc = it->second;
|
|
Shinya Kitaoka |
120a6e |
assert(cc);
|
|
Shinya Kitaoka |
120a6e |
TRasterP rasP;
|
|
Shinya Kitaoka |
120a6e |
m_codec->decompress(cc->m_buffer, cc->m_size, rasP);
|
|
Shinya Kitaoka |
120a6e |
return rasP;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TRamCachePersist::doGetRaster(int frame, TRaster32P &ras) const {
|
|
Shinya Kitaoka |
120a6e |
Imp::CompressedChunks::const_iterator it = m_imp->m_chunks.find(frame);
|
|
Shinya Kitaoka |
120a6e |
if (it == m_imp->m_chunks.end()) return false;
|
|
Shinya Kitaoka |
120a6e |
Imp::CompressedChunk *cc = it->second;
|
|
Shinya Kitaoka |
120a6e |
assert(cc);
|
|
Shinya Kitaoka |
120a6e |
TRasterP rasP(ras);
|
|
Shinya Kitaoka |
120a6e |
m_codec->decompress(cc->m_buffer, cc->m_size, rasP);
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TRamCachePersist::doPutRaster(int frame, const TRasterP &ras) {
|
|
Shinya Kitaoka |
120a6e |
Imp::CompressedChunks::iterator it = m_imp->m_chunks.find(frame);
|
|
Shinya Kitaoka |
120a6e |
if (it != m_imp->m_chunks.end()) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_cacheSize -= it->second->m_size;
|
|
Shinya Kitaoka |
120a6e |
delete it->second;
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_chunks.erase(it);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
UCHAR *outData = 0;
|
|
Shinya Kitaoka |
120a6e |
TINT32 outDataSize = 0;
|
|
Shinya Kitaoka |
120a6e |
m_codec->compress(ras, 1, &outData, outDataSize);
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_cacheSize += outDataSize;
|
|
Shinya Kitaoka |
120a6e |
Imp::CompressedChunk *cc = new Imp::CompressedChunk(outData, outDataSize);
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_chunks.insert(Imp::CompressedChunks::value_type(frame, cc));
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TRamCachePersist::onInvalidate() {
|
|
Shinya Kitaoka |
120a6e |
for (Imp::CompressedChunks::iterator it = m_imp->m_chunks.begin();
|
|
Shinya Kitaoka |
120a6e |
it != m_imp->m_chunks.end(); ++it) {
|
|
Shinya Kitaoka |
120a6e |
Imp::CompressedChunk *cc = it->second;
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_cacheSize -= cc->m_size;
|
|
Shinya Kitaoka |
120a6e |
delete cc;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_chunks.clear();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TRamCachePersist::onInvalidate(int startFrame,
|
|
Shinya Kitaoka |
120a6e |
int endFrame) { // ottimizzabile
|
|
Shinya Kitaoka |
120a6e |
assert(startFrame <= endFrame);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (int frame = startFrame; frame <= endFrame; ++frame) {
|
|
Shinya Kitaoka |
120a6e |
Imp::CompressedChunks::iterator it = m_imp->m_chunks.find(frame);
|
|
Shinya Kitaoka |
120a6e |
if (it != m_imp->m_chunks.end()) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_cacheSize -= it->second->m_size;
|
|
Shinya Kitaoka |
120a6e |
delete it->second;
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_chunks.erase(it);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
UCHAR *TRamCachePersist::getRawData(int frame, TINT32 &size, int &lx, int &ly) {
|
|
Shinya Kitaoka |
120a6e |
Imp::CompressedChunks::const_iterator it = m_imp->m_chunks.find(frame);
|
|
Shinya Kitaoka |
120a6e |
if (it == m_imp->m_chunks.end()) return 0;
|
|
Shinya Kitaoka |
120a6e |
Imp::CompressedChunk *cc = it->second;
|
|
Shinya Kitaoka |
120a6e |
assert(cc);
|
|
Shinya Kitaoka |
120a6e |
return m_codec->removeHeader(cc->m_buffer, cc->m_size, size, lx, ly);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TUINT64 TRamCachePersist::getUsedSpace() { return m_imp->m_cacheSize; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDiskCachePersist::onInvalidate() {
|
|
Shinya Kitaoka |
120a6e |
// m_imp->m_chunkSize = 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDiskCachePersist::onInvalidate(int startFrame, int endFrame) {
|
|
Shinya Kitaoka |
120a6e |
// m_imp->m_chunkSize = 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TUINT64 TDiskCachePersist::getUsedSpace() {
|
|
Shinya Kitaoka |
120a6e |
assert(0);
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// TDiskCachePersist2
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
#ifdef WIN32
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class ZFile {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
ZFile(const TFilePath &fp, bool directIO, bool asyncIO);
|
|
Shinya Kitaoka |
120a6e |
~ZFile();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void open();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int read(BYTE buf[], int size, TINT64 qwOffset) const;
|
|
Shinya Kitaoka |
120a6e |
int write(BYTE buf[], int size, TINT64 qwOffset) const;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void waitForAsyncIOCompletion() const;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TFilePath getFilePath() const { return m_filepath; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int getBytesPerSector() const { return m_bytesPerSector; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
static void CALLBACK FileIOCompletionRoutine(DWORD errCode,
|
|
Shinya Kitaoka |
120a6e |
DWORD byteTransferred,
|
|
Shinya Kitaoka |
120a6e |
LPOVERLAPPED overlapped);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
TFilePath m_filepath;
|
|
Shinya Kitaoka |
120a6e |
bool m_directIO;
|
|
Shinya Kitaoka |
120a6e |
bool m_asyncIO;
|
|
Shinya Kitaoka |
120a6e |
DWORD m_bytesPerSector;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
HANDLE m_fileHandle;
|
|
Shinya Kitaoka |
120a6e |
HANDLE m_writeNotPending;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ZFile::ZFile(const TFilePath &fp, bool directIO, bool asyncIO)
|
|
Shinya Kitaoka |
120a6e |
: m_filepath(fp)
|
|
Shinya Kitaoka |
120a6e |
, m_directIO(directIO)
|
|
Shinya Kitaoka |
120a6e |
, m_asyncIO(asyncIO)
|
|
Shinya Kitaoka |
120a6e |
, m_fileHandle(0)
|
|
Shinya Kitaoka |
120a6e |
, m_writeNotPending(0) {
|
|
Shinya Kitaoka |
120a6e |
DWORD sectorsPerCluster;
|
|
Shinya Kitaoka |
120a6e |
DWORD numberOfFreeClusters;
|
|
Shinya Kitaoka |
120a6e |
DWORD totalNumberOfClusters;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TFilePathSet disks = TSystem::getDisks();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TFilePath disk = fp;
|
|
Shinya Kitaoka |
120a6e |
while (std::find(disks.begin(), disks.end(), disk) == disks.end())
|
|
Shinya Kitaoka |
120a6e |
disk = disk.getParentDir();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
BOOL ret = GetDiskFreeSpaceW(disk.getWideString().c_str(), // root path
|
|
Shinya Kitaoka |
120a6e |
§orsPerCluster, // sectors per cluster
|
|
Shinya Kitaoka |
120a6e |
&m_bytesPerSector, // bytes per sector
|
|
Shinya Kitaoka |
120a6e |
&numberOfFreeClusters, // free clusters
|
|
Shinya Kitaoka |
120a6e |
&totalNumberOfClusters // total clusters
|
|
Shinya Kitaoka |
120a6e |
);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_asyncIO) m_writeNotPending = CreateEvent(NULL, TRUE, TRUE, NULL);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ZFile::~ZFile() {
|
|
Shinya Kitaoka |
120a6e |
if (m_fileHandle) CloseHandle(m_fileHandle);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_writeNotPending) CloseHandle(m_writeNotPending);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ZFile::open() {
|
|
Shinya Kitaoka |
120a6e |
DWORD flagsAndAttributes = 0;
|
|
Shinya Kitaoka |
120a6e |
flagsAndAttributes = m_directIO ? FILE_FLAG_NO_BUFFERING : 0UL;
|
|
Shinya Kitaoka |
120a6e |
flagsAndAttributes |= m_asyncIO ? FILE_FLAG_OVERLAPPED : 0UL;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Open the file for write access.
|
|
Shinya Kitaoka |
120a6e |
m_fileHandle =
|
|
Shinya Kitaoka |
120a6e |
CreateFileW(m_filepath.getWideString().c_str(),
|
|
Shinya Kitaoka |
120a6e |
GENERIC_READ | GENERIC_WRITE, // Read/Write access
|
|
Shinya Kitaoka |
120a6e |
0, // no sharing allowed
|
|
Shinya Kitaoka |
120a6e |
NULL, // no security
|
|
Shinya Kitaoka |
120a6e |
OPEN_ALWAYS, // open it or create new if it doesn't exist
|
|
Shinya Kitaoka |
120a6e |
flagsAndAttributes,
|
|
Shinya Kitaoka |
120a6e |
NULL); // ignored
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_fileHandle == INVALID_HANDLE_VALUE) {
|
|
Shinya Kitaoka |
120a6e |
m_fileHandle = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
char errorMessage[2048];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
DWORD error = GetLastError();
|
|
Shinya Kitaoka |
120a6e |
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0UL, error,
|
|
Shinya Kitaoka |
120a6e |
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), errorMessage, 2048,
|
|
Shinya Kitaoka |
120a6e |
NULL);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
throw TException(errorMessage);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int ZFile::read(BYTE buf[], int size, TINT64 qwOffset) const {
|
|
Shinya Kitaoka |
120a6e |
assert(size % m_bytesPerSector == 0);
|
|
Shinya Kitaoka |
120a6e |
assert(qwOffset % m_bytesPerSector == 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
char msg[2048] = "";
|
|
Shinya Kitaoka |
120a6e |
unsigned long bytesToRead; // Padded number of bytes to read.
|
|
Shinya Kitaoka |
120a6e |
unsigned long bytesRead; // count of bytes actually read
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
OVERLAPPED overLapped;
|
|
Shinya Kitaoka |
120a6e |
memset(&overLapped, 0, sizeof(overLapped));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#define DWORDLONG_LO_DWORD(dwl64) ((DWORD)(dwl64))
|
|
Toshihiro Shimizu |
890ddd |
#define DWORDLONG_HI_DWORD(dwl64) ((DWORD)(dwl64 >> 32))
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// set the overlapped stucture with the offsets
|
|
Shinya Kitaoka |
120a6e |
overLapped.Offset = DWORDLONG_LO_DWORD(qwOffset);
|
|
Shinya Kitaoka |
120a6e |
overLapped.OffsetHigh = DWORDLONG_HI_DWORD(qwOffset);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_asyncIO) {
|
|
Shinya Kitaoka |
120a6e |
overLapped.hEvent = CreateEvent(NULL, // SD
|
|
Shinya Kitaoka |
120a6e |
TRUE, // manual reset
|
|
Shinya Kitaoka |
120a6e |
FALSE, // initial state is not signaled
|
|
Shinya Kitaoka |
120a6e |
NULL); // object name
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
overLapped.hEvent = NULL;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bytesToRead = size;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Read a bunch of bytes and store in buf
|
|
Shinya Kitaoka |
120a6e |
int result = ReadFile(m_fileHandle, // file handle
|
|
Shinya Kitaoka |
120a6e |
(void *)buf, // buffer to store data
|
|
Shinya Kitaoka |
120a6e |
bytesToRead, // num bytes to read
|
|
Shinya Kitaoka |
120a6e |
&bytesRead, // bytes read
|
|
Shinya Kitaoka |
120a6e |
&overLapped); // stucture for file offsets
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!result) {
|
|
Shinya Kitaoka |
120a6e |
DWORD error = GetLastError();
|
|
Shinya Kitaoka |
120a6e |
if (m_asyncIO && ERROR_IO_PENDING == error) {
|
|
Shinya Kitaoka |
120a6e |
if (!GetOverlappedResult(m_fileHandle, &overLapped, &bytesRead, TRUE)) {
|
|
Shinya Kitaoka |
120a6e |
char errorMessage[2048];
|
|
Shinya Kitaoka |
120a6e |
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0UL, error,
|
|
Shinya Kitaoka |
120a6e |
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), errorMessage,
|
|
Shinya Kitaoka |
120a6e |
2048, NULL);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
throw TException(errorMessage);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
char errorMessage[2048];
|
|
Shinya Kitaoka |
120a6e |
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0UL, error,
|
|
Shinya Kitaoka |
120a6e |
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), errorMessage,
|
|
Shinya Kitaoka |
120a6e |
2048, NULL);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
throw TException(errorMessage);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return bytesRead;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int ZFile::write(BYTE buf[], int size, TINT64 qwOffset) const {
|
|
Shinya Kitaoka |
120a6e |
assert(size % m_bytesPerSector == 0);
|
|
Shinya Kitaoka |
120a6e |
assert(qwOffset % m_bytesPerSector == 0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
char msg[2048] = "";
|
|
Shinya Kitaoka |
120a6e |
unsigned long bytesToWrite; // Padded number of bytes to write.
|
|
Shinya Kitaoka |
120a6e |
unsigned long bytesWritten = 0; // count of bytes actually writtten
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int result;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_asyncIO) {
|
|
Shinya Kitaoka |
120a6e |
OVERLAPPED *overLapped = new OVERLAPPED;
|
|
Shinya Kitaoka |
120a6e |
memset(overLapped, 0, sizeof(OVERLAPPED));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// set the overlapped stucture with the offsets
|
|
Shinya Kitaoka |
120a6e |
overLapped->Offset = DWORDLONG_LO_DWORD(qwOffset);
|
|
Shinya Kitaoka |
120a6e |
overLapped->OffsetHigh = DWORDLONG_HI_DWORD(qwOffset);
|
|
Shinya Kitaoka |
120a6e |
overLapped->hEvent = NULL;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bytesToWrite = size;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
result = WriteFileEx(m_fileHandle, // file handle
|
|
Shinya Kitaoka |
120a6e |
(void *)buf, // data buffer
|
|
Shinya Kitaoka |
120a6e |
bytesToWrite, // num bytes to write
|
|
Shinya Kitaoka |
120a6e |
overLapped, // stucture for file offsets
|
|
Shinya Kitaoka |
120a6e |
&ZFile::FileIOCompletionRoutine);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ResetEvent(m_writeNotPending);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
OVERLAPPED overLapped;
|
|
Shinya Kitaoka |
120a6e |
memset(&overLapped, 0, sizeof(overLapped));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// set the overlapped stucture with the offsets
|
|
Shinya Kitaoka |
120a6e |
overLapped.Offset = DWORDLONG_LO_DWORD(qwOffset);
|
|
Shinya Kitaoka |
120a6e |
overLapped.OffsetHigh = DWORDLONG_HI_DWORD(qwOffset);
|
|
Shinya Kitaoka |
120a6e |
overLapped.hEvent = NULL;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bytesToWrite = size;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
result = WriteFile(m_fileHandle, // file handle
|
|
Shinya Kitaoka |
120a6e |
(void *)buf, // data buffer
|
|
Shinya Kitaoka |
120a6e |
bytesToWrite, // num bytes to read
|
|
Shinya Kitaoka |
120a6e |
&bytesWritten, // bytes read
|
|
Shinya Kitaoka |
120a6e |
&overLapped); // stucture for file offsets
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!result) {
|
|
Shinya Kitaoka |
120a6e |
char errorMessage[2048];
|
|
Shinya Kitaoka |
120a6e |
DWORD error = GetLastError();
|
|
Shinya Kitaoka |
120a6e |
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0UL, error,
|
|
Shinya Kitaoka |
120a6e |
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), errorMessage, 2048,
|
|
Shinya Kitaoka |
120a6e |
NULL);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
throw TException(errorMessage);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return bytesWritten;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void ZFile::waitForAsyncIOCompletion() const {
|
|
Shinya Kitaoka |
120a6e |
if (m_asyncIO) {
|
|
Shinya Kitaoka |
120a6e |
WaitForSingleObjectEx(m_writeNotPending, INFINITE, TRUE);
|
|
Shinya Kitaoka |
120a6e |
SetEvent(m_writeNotPending);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void CALLBACK ZFile::FileIOCompletionRoutine(DWORD errCode,
|
|
Shinya Kitaoka |
120a6e |
DWORD byteTransferred,
|
|
Shinya Kitaoka |
120a6e |
LPOVERLAPPED overlapped) {
|
|
Shinya Kitaoka |
120a6e |
delete overlapped;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class BufferQueue {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
class Item {
|
|
Shinya Kitaoka |
120a6e |
public:
|
|
Shinya Kitaoka |
120a6e |
Item(int frame, UCHAR *buffer, int bufferSize, int chunkSize)
|
|
Shinya Kitaoka |
120a6e |
: m_frame(frame)
|
|
Shinya Kitaoka |
120a6e |
, m_buffer(buffer)
|
|
Shinya Kitaoka |
120a6e |
, m_bufferSize(bufferSize)
|
|
Shinya Kitaoka |
120a6e |
, m_chunkSize(chunkSize) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int m_frame;
|
|
Shinya Kitaoka |
120a6e |
UCHAR *m_buffer;
|
|
Shinya Kitaoka |
120a6e |
int m_bufferSize;
|
|
Shinya Kitaoka |
120a6e |
TINT64 m_chunkSize;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
BufferQueue(int capacity, int allocUnit)
|
|
Shinya Kitaoka |
120a6e |
: m_capacity(capacity)
|
|
Shinya Kitaoka |
120a6e |
, m_allocUnit(allocUnit)
|
|
Shinya Kitaoka |
120a6e |
, m_notEmpty()
|
|
Shinya Kitaoka |
120a6e |
, m_notFull()
|
|
Shinya Kitaoka |
120a6e |
, m_mutex()
|
|
Shinya Kitaoka |
120a6e |
, m_bufferCount(0)
|
|
Shinya Kitaoka |
120a6e |
, m_nextPutItem(0)
|
|
Shinya Kitaoka |
120a6e |
, m_nextGetItem(0) {
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < m_capacity; ++i)
|
|
Shinya Kitaoka |
120a6e |
m_items.push_back(Item(-1, (UCHAR *)0, 0, 0));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
~BufferQueue() {
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < m_capacity; ++i) delete[] m_items[i].m_buffer;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void put(int frame, UCHAR *buffer, int bufferSize, int chunkSize) {
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock sl(m_mutex);
|
|
Shinya Kitaoka |
120a6e |
while (m_bufferCount == m_capacity) m_notFull.wait(sl);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_items[m_nextPutItem].m_chunkSize != chunkSize) {
|
|
Shinya Kitaoka |
120a6e |
delete[] m_items[m_nextPutItem].m_buffer;
|
|
Shinya Kitaoka |
120a6e |
m_items[m_nextPutItem].m_buffer = new UCHAR[chunkSize];
|
|
Shinya Kitaoka |
120a6e |
m_items[m_nextPutItem].m_chunkSize = chunkSize;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
memcpy(m_items[m_nextPutItem].m_buffer, buffer, bufferSize);
|
|
Shinya Kitaoka |
120a6e |
m_items[m_nextPutItem].m_frame = frame;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_nextPutItem = (m_nextPutItem + 1) % m_capacity;
|
|
Shinya Kitaoka |
120a6e |
++m_bufferCount;
|
|
Shinya Kitaoka |
120a6e |
m_notEmpty.notifyOne();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
BufferQueue::Item get() {
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock sl(m_mutex);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (m_bufferCount == 0) m_notEmpty.wait(sl);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_notFull.notifyOne();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
BufferQueue::Item item = m_items[m_nextGetItem];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_nextGetItem = (m_nextGetItem + 1) % m_capacity;
|
|
Shinya Kitaoka |
120a6e |
--m_bufferCount;
|
|
Shinya Kitaoka |
120a6e |
return item;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void saveOne(ZFile *file) {
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock sl(m_mutex);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (m_bufferCount == 0) m_notEmpty.wait(sl);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_notFull.notifyOne();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
BufferQueue::Item item = m_items[m_nextGetItem];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_nextGetItem = (m_nextGetItem + 1) % m_capacity;
|
|
Shinya Kitaoka |
120a6e |
--m_bufferCount;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TINT64 pos = item.m_frame * item.m_chunkSize;
|
|
Shinya Kitaoka |
120a6e |
TINT64 sectorCount = pos / m_allocUnit;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if ((pos % m_allocUnit) != 0) ++sectorCount;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
pos = sectorCount * m_allocUnit;
|
|
Shinya Kitaoka |
120a6e |
file->write(item.m_buffer, (TINT32)item.m_chunkSize, pos);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int size() {
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock sl(m_mutex);
|
|
Shinya Kitaoka |
120a6e |
return m_bufferCount;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
int m_capacity;
|
|
Shinya Kitaoka |
120a6e |
int m_allocUnit;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TThread::Condition m_notEmpty;
|
|
Shinya Kitaoka |
120a6e |
TThread::Condition m_notFull;
|
|
Shinya Kitaoka |
120a6e |
TThread::Mutex m_mutex;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
vector<item> m_items;</item>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int m_bufferCount;
|
|
Shinya Kitaoka |
120a6e |
int m_nextPutItem;
|
|
Shinya Kitaoka |
120a6e |
int m_nextGetItem;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class WriteBufferTask : public TThread::Runnable {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
WriteBufferTask(ZFile *file, BufferQueue *bufferQueue)
|
|
Shinya Kitaoka |
120a6e |
: m_file(file), m_bufferQueue(bufferQueue) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void run();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ZFile *m_file;
|
|
Shinya Kitaoka |
120a6e |
BufferQueue *m_bufferQueue;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void WriteBufferTask::run() {
|
|
Shinya Kitaoka |
120a6e |
while (true) {
|
|
Shinya Kitaoka |
120a6e |
TThread::milestone();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
try {
|
|
Shinya Kitaoka |
120a6e |
m_bufferQueue->saveOne(m_file);
|
|
Shinya Kitaoka |
120a6e |
m_file->waitForAsyncIOCompletion();
|
|
Shinya Kitaoka |
120a6e |
} catch (TException & /*e*/) {
|
|
Shinya Kitaoka |
120a6e |
} catch (...) {
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // anonymous namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class TDiskCachePersist2::Imp {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
Imp(const TFilePath &fp, bool asyncWrite)
|
|
Shinya Kitaoka |
120a6e |
: m_chunkSize(0)
|
|
Shinya Kitaoka |
120a6e |
, m_readBuffer(0)
|
|
Shinya Kitaoka |
120a6e |
, m_file(new ZFile(fp, true, asyncWrite))
|
|
Shinya Kitaoka |
120a6e |
, m_asyncWrite(asyncWrite)
|
|
Shinya Kitaoka |
120a6e |
, m_executor(0)
|
|
Shinya Kitaoka |
120a6e |
, m_bufferQueue(0) {
|
|
Shinya Kitaoka |
120a6e |
m_file->open();
|
|
Shinya Kitaoka |
120a6e |
m_allocUnit = m_file->getBytesPerSector();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_asyncWrite) {
|
|
Shinya Kitaoka |
120a6e |
m_executor = new TThread::Executor();
|
|
Shinya Kitaoka |
120a6e |
m_bufferQueue = new BufferQueue(4, m_allocUnit);
|
|
Shinya Kitaoka |
120a6e |
m_executor->addTask(new WriteBufferTask(m_file, m_bufferQueue));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
~Imp() {
|
|
Shinya Kitaoka |
120a6e |
delete m_file;
|
|
Shinya Kitaoka |
120a6e |
delete[] m_readBuffer;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_executor) {
|
|
Shinya Kitaoka |
120a6e |
m_executor->cancel();
|
|
Shinya Kitaoka |
120a6e |
delete m_executor;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
delete m_bufferQueue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool put(int frame, UCHAR *data, TUINT32 dataSize);
|
|
Shinya Kitaoka |
120a6e |
UCHAR *get(int pos, TUINT32 *size);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TThread::Mutex m_mutex;
|
|
Shinya Kitaoka |
120a6e |
TINT64 m_chunkSize;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ZFile *m_file;
|
|
Shinya Kitaoka |
120a6e |
int m_allocUnit;
|
|
Shinya Kitaoka |
120a6e |
UCHAR *m_readBuffer;
|
|
Shinya Kitaoka |
120a6e |
int m_lx;
|
|
Shinya Kitaoka |
120a6e |
int m_ly;
|
|
Shinya Kitaoka |
120a6e |
int m_bpp;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool m_asyncWrite;
|
|
Shinya Kitaoka |
120a6e |
TThread::Executor *m_executor;
|
|
Shinya Kitaoka |
120a6e |
BufferQueue *m_bufferQueue;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TDiskCachePersist2::Imp::put(int frame, UCHAR *data, TUINT32 dataSize) {
|
|
Shinya Kitaoka |
120a6e |
if (dataSize != m_chunkSize) return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TINT64 pos = frame * m_chunkSize;
|
|
Shinya Kitaoka |
120a6e |
TINT64 sectorCount = pos / m_allocUnit;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if ((pos % m_allocUnit) != 0) ++sectorCount;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
pos = sectorCount * m_allocUnit;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_file->write(data, dataSize, pos);
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
UCHAR *TDiskCachePersist2::Imp::get(int frame, TUINT32 *size) {
|
|
Shinya Kitaoka |
120a6e |
UCHAR *ret = new UCHAR[TINT32(m_chunkSize)];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TThread::ScopedLock sl(m_mutex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TINT64 pos = frame * m_chunkSize;
|
|
Shinya Kitaoka |
120a6e |
TINT64 sectorCount = pos / m_allocUnit;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if ((pos % m_allocUnit) != 0) ++sectorCount;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
pos = sectorCount * m_allocUnit;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_file->read(ret, TINT32(m_chunkSize), pos);
|
|
Shinya Kitaoka |
120a6e |
*size = TUINT32(m_chunkSize);
|
|
Shinya Kitaoka |
120a6e |
return ret;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TDiskCachePersist2::TDiskCachePersist2(TRasterCodec *codec,
|
|
Shinya Kitaoka |
120a6e |
const TFilePath &fullpath)
|
|
Shinya Kitaoka |
120a6e |
: TCachePersist(codec), m_imp(new Imp(fullpath, false /*true*/)) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TDiskCachePersist2::~TDiskCachePersist2() { delete m_imp; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDiskCachePersist2::setFrameSize(int lx, int ly, int bpp) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_lx = lx;
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_ly = ly;
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_bpp = bpp;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// inizializza m_imp->m_chunkSize in modo che sia un multiplo di
|
|
Shinya Kitaoka |
120a6e |
// m_imp->m_allocUnit
|
|
Shinya Kitaoka |
120a6e |
if (m_codec)
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_chunkSize = m_codec->getMaxCompressionSize(lx * ly * (bpp >> 3));
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_chunkSize = lx * ly * (bpp >> 3);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TINT64 allocUnitCount = m_imp->m_chunkSize / m_imp->m_allocUnit;
|
|
Shinya Kitaoka |
120a6e |
if ((m_imp->m_chunkSize % m_imp->m_allocUnit) != 0) ++allocUnitCount;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_chunkSize = allocUnitCount * m_imp->m_allocUnit;
|
|
Shinya Kitaoka |
120a6e |
delete[] m_imp->m_readBuffer;
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_readBuffer = 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRasterP TDiskCachePersist2::doGetRaster(int frame) {
|
|
Shinya Kitaoka |
120a6e |
TRasterP outRas;
|
|
Shinya Kitaoka |
120a6e |
TUINT32 size;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!m_imp->m_readBuffer)
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_readBuffer = new UCHAR[TINT32(m_imp->m_chunkSize)];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TINT64 pos = frame * m_imp->m_chunkSize;
|
|
Shinya Kitaoka |
120a6e |
TINT64 sectorCount = pos / m_imp->m_allocUnit;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if ((pos % m_imp->m_allocUnit) != 0) ++sectorCount;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
pos = sectorCount * m_imp->m_allocUnit;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_file->read(m_imp->m_readBuffer, TINT32(m_imp->m_chunkSize), pos);
|
|
Shinya Kitaoka |
120a6e |
size = TUINT32(m_imp->m_chunkSize);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_codec)
|
|
Shinya Kitaoka |
120a6e |
m_codec->decompress(m_imp->m_readBuffer, size, outRas);
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
switch (m_imp->m_bpp) {
|
|
Shinya Kitaoka |
120a6e |
case 32: {
|
|
Shinya Kitaoka |
120a6e |
TRaster32P ras(m_imp->m_lx, m_imp->m_ly);
|
|
Shinya Kitaoka |
120a6e |
outRas = ras;
|
|
Shinya Kitaoka |
120a6e |
} break;
|
|
Shinya Kitaoka |
120a6e |
case 64: {
|
|
Shinya Kitaoka |
120a6e |
TRaster64P ras(m_imp->m_lx, m_imp->m_ly);
|
|
Shinya Kitaoka |
120a6e |
outRas = ras;
|
|
Shinya Kitaoka |
120a6e |
} break;
|
|
Shinya Kitaoka |
120a6e |
default:
|
|
Shinya Kitaoka |
120a6e |
throw TException("unsupported pixel format");
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
unsigned int rasSize = outRas->getRowSize() * outRas->getLy();
|
|
Shinya Kitaoka |
120a6e |
assert(size >= rasSize);
|
|
Shinya Kitaoka |
120a6e |
outRas->lock();
|
|
Shinya Kitaoka |
120a6e |
memcpy(outRas->getRawData(), m_imp->m_readBuffer, rasSize);
|
|
Shinya Kitaoka |
120a6e |
outRas->unlock();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return outRas;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TDiskCachePersist2::doGetRaster(int frame, TRaster32P &ras) const {
|
|
Shinya Kitaoka |
120a6e |
if (!m_imp->m_readBuffer)
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_readBuffer = new UCHAR[TINT32(m_imp->m_chunkSize)];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TINT64 pos = frame * m_imp->m_chunkSize;
|
|
Shinya Kitaoka |
120a6e |
TINT64 sectorCount = pos / m_imp->m_allocUnit;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if ((pos % m_imp->m_allocUnit) != 0) ++sectorCount;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
pos = sectorCount * m_imp->m_allocUnit;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRasterP rasP = ras;
|
|
Shinya Kitaoka |
120a6e |
if (m_codec) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_file->read(m_imp->m_readBuffer, TINT32(m_imp->m_chunkSize), pos);
|
|
Shinya Kitaoka |
120a6e |
m_codec->decompress(m_imp->m_readBuffer, TINT32(m_imp->m_chunkSize), rasP);
|
|
Shinya Kitaoka |
120a6e |
assert(rasP->getSize() == ras->getSize());
|
|
Shinya Kitaoka |
120a6e |
ras->copy(rasP);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
assert(ras->getLx() == ras->getWrap());
|
|
Shinya Kitaoka |
120a6e |
int rasSize = ras->getRowSize() * ras->getLy();
|
|
Shinya Kitaoka |
120a6e |
ras->lock();
|
|
Shinya Kitaoka |
120a6e |
if (rasSize == m_imp->m_chunkSize)
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_file->read(ras->getRawData(), TINT32(m_imp->m_chunkSize), pos);
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
assert(rasSize < m_imp->m_chunkSize);
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_file->read(m_imp->m_readBuffer, TINT32(m_imp->m_chunkSize), pos);
|
|
Shinya Kitaoka |
120a6e |
memcpy(ras->getRawData(), m_imp->m_readBuffer, rasSize);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
ras->unlock();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TDiskCachePersist2::doPutRaster(int frame, const TRasterP &inRas) {
|
|
Shinya Kitaoka |
120a6e |
UCHAR *outData = 0;
|
|
Shinya Kitaoka |
120a6e |
TINT32 outDataSize = 0;
|
|
Shinya Kitaoka |
120a6e |
int actualDataSize = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool deleteDataBuffer = false;
|
|
Shinya Kitaoka |
120a6e |
if (m_codec) {
|
|
Shinya Kitaoka |
120a6e |
m_codec->compress(inRas, m_imp->m_allocUnit, &outData, outDataSize);
|
|
Shinya Kitaoka |
120a6e |
deleteDataBuffer = true;
|
|
Shinya Kitaoka |
120a6e |
;
|
|
Shinya Kitaoka |
120a6e |
actualDataSize = outDataSize;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
assert(inRas->getLx() == inRas->getWrap());
|
|
Shinya Kitaoka |
120a6e |
int rasSize = inRas->getLx() * inRas->getLy() * inRas->getPixelSize();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
outDataSize = TINT32(m_imp->m_chunkSize);
|
|
Shinya Kitaoka |
120a6e |
inRas->lock();
|
|
Shinya Kitaoka |
120a6e |
if (rasSize == m_imp->m_chunkSize)
|
|
Shinya Kitaoka |
120a6e |
outData = inRas->getRawData();
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
if (!m_imp->m_readBuffer)
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_readBuffer = new UCHAR[TINT32(m_imp->m_chunkSize)];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
memcpy(m_imp->m_readBuffer, inRas->getRawData(), rasSize);
|
|
Shinya Kitaoka |
120a6e |
outData = m_imp->m_readBuffer;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
inRas->unlock();
|
|
Shinya Kitaoka |
120a6e |
actualDataSize = rasSize;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert((outDataSize % m_imp->m_allocUnit) == 0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool cached = true;
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_asyncWrite)
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_bufferQueue->put(frame, outData, actualDataSize, outDataSize);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
cached = m_imp->put(frame, outData, outDataSize);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (deleteDataBuffer) delete[] outData;
|
|
Shinya Kitaoka |
120a6e |
return cached;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
UCHAR *TDiskCachePersist2::getRawData(int frame, TINT32 &size, int &lx,
|
|
Shinya Kitaoka |
120a6e |
int &ly) {
|
|
Shinya Kitaoka |
120a6e |
TUINT32 inDataSize;
|
|
Shinya Kitaoka |
120a6e |
UCHAR *src = m_imp->get(frame, &inDataSize);
|
|
Shinya Kitaoka |
120a6e |
return m_codec->removeHeader(src, inDataSize, size, lx, ly);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDiskCachePersist2::onInvalidate() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TDiskCachePersist2::onInvalidate(int startFrame, int endFrame) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TUINT64 TDiskCachePersist2::getUsedSpace() {
|
|
Shinya Kitaoka |
120a6e |
TFileStatus fs(m_imp->m_file->getFilePath());
|
|
Shinya Kitaoka |
120a6e |
return fs.getSize();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
#endif // WIN32
|