mirror of
https://github.com/blawar/GLideN64.git
synced 2024-07-04 10:03:36 +00:00
Memory cache implementation of TxCache
This commit is contained in:
parent
a1a443ca47
commit
dee7065982
|
@ -33,24 +33,43 @@
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
class TxCache::TxCacheImpl
|
class TxCacheImpl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TxCacheImpl(const TxCache* pCache, uint64 cacheLimit);
|
virtual ~TxCacheImpl() = default;
|
||||||
|
|
||||||
bool add(Checksum checksum, GHQTexInfo *info, int dataSize = 0);
|
virtual bool add(Checksum checksum, GHQTexInfo *info, int dataSize = 0) = 0;
|
||||||
bool get(Checksum checksum, GHQTexInfo *info);
|
virtual bool get(Checksum checksum, GHQTexInfo *info) = 0;
|
||||||
|
virtual bool save(const wchar_t *path, const wchar_t *filename, const int config) = 0;
|
||||||
|
virtual bool load(const wchar_t *path, const wchar_t *filename, const int config, boolean force) = 0;
|
||||||
|
virtual bool del(Checksum checksum) = 0;
|
||||||
|
virtual bool isCached(Checksum checksum) = 0;
|
||||||
|
virtual void clear() = 0;
|
||||||
|
virtual bool empty() const = 0;
|
||||||
|
|
||||||
bool save(const wchar_t *path, const wchar_t *filename, const int config);
|
virtual uint64 size() const = 0;
|
||||||
bool load(const wchar_t *path, const wchar_t *filename, const int config, boolean force);
|
virtual uint64 totalSize() const = 0;
|
||||||
bool del(Checksum checksum);
|
virtual uint64 cacheLimit() const = 0;
|
||||||
bool isCached(Checksum checksum);
|
};
|
||||||
void clear();
|
|
||||||
bool empty() const { return _cache.empty(); }
|
|
||||||
|
|
||||||
uint64 size() const { return _cache.size(); }
|
class TxMemoryCache : public TxCacheImpl
|
||||||
uint64 totalSize() const { return _totalSize; }
|
{
|
||||||
uint64 cacheLimit() const { return _cacheLimit; }
|
public:
|
||||||
|
TxMemoryCache(uint32 & _options, uint64 cacheLimit, dispInfoFuncExt callback);
|
||||||
|
|
||||||
|
bool add(Checksum checksum, GHQTexInfo *info, int dataSize = 0) override;
|
||||||
|
bool get(Checksum checksum, GHQTexInfo *info) override;
|
||||||
|
|
||||||
|
bool save(const wchar_t *path, const wchar_t *filename, const int config) override;
|
||||||
|
bool load(const wchar_t *path, const wchar_t *filename, const int config, boolean force) override;
|
||||||
|
bool del(Checksum checksum) override;
|
||||||
|
bool isCached(Checksum checksum) override;
|
||||||
|
void clear() override;
|
||||||
|
bool empty() const override { return _cache.empty(); }
|
||||||
|
|
||||||
|
uint64 size() const override { return _cache.size(); }
|
||||||
|
uint64 totalSize() const override { return _totalSize; }
|
||||||
|
uint64 cacheLimit() const override { return _cacheLimit; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct TXCACHE {
|
struct TXCACHE {
|
||||||
|
@ -59,34 +78,36 @@ private:
|
||||||
std::list<uint64>::iterator it;
|
std::list<uint64>::iterator it;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uint32 & _options;
|
||||||
|
dispInfoFuncExt _callback;
|
||||||
|
uint64 _cacheLimit;
|
||||||
|
uint64 _totalSize;
|
||||||
|
|
||||||
std::map<uint64, TXCACHE*> _cache;
|
std::map<uint64, TXCACHE*> _cache;
|
||||||
std::list<uint64> _cachelist;
|
std::list<uint64> _cachelist;
|
||||||
|
|
||||||
uint8 *_gzdest0;
|
uint8 *_gzdest0 = nullptr;
|
||||||
uint8 *_gzdest1;
|
uint8 *_gzdest1 = nullptr;
|
||||||
uint32 _gzdestLen;
|
uint32 _gzdestLen = 0;
|
||||||
|
|
||||||
uint64 _totalSize;
|
|
||||||
uint64 _cacheLimit;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const TxCache* _pTxCache;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TxCache::TxCacheImpl::TxCacheImpl(const TxCache* pCache, uint64 cacheLimit)
|
TxMemoryCache::TxMemoryCache(uint32 & options,
|
||||||
: _pTxCache(pCache)
|
uint64 cacheLimit,
|
||||||
|
dispInfoFuncExt callback)
|
||||||
|
: _options(options)
|
||||||
, _cacheLimit(cacheLimit)
|
, _cacheLimit(cacheLimit)
|
||||||
|
, _callback(callback)
|
||||||
, _totalSize(0U)
|
, _totalSize(0U)
|
||||||
{
|
{
|
||||||
/* zlib memory buffers to (de)compress hires textures */
|
/* zlib memory buffers to (de)compress hires textures */
|
||||||
if (_pTxCache->_options & (GZ_TEXCACHE | GZ_HIRESTEXCACHE)) {
|
if (_options & (GZ_TEXCACHE | GZ_HIRESTEXCACHE)) {
|
||||||
_gzdest0 = TxMemBuf::getInstance()->get(0);
|
_gzdest0 = TxMemBuf::getInstance()->get(0);
|
||||||
_gzdest1 = TxMemBuf::getInstance()->get(1);
|
_gzdest1 = TxMemBuf::getInstance()->get(1);
|
||||||
_gzdestLen = (TxMemBuf::getInstance()->size_of(0) < TxMemBuf::getInstance()->size_of(1)) ?
|
_gzdestLen = (TxMemBuf::getInstance()->size_of(0) < TxMemBuf::getInstance()->size_of(1)) ?
|
||||||
TxMemBuf::getInstance()->size_of(0) : TxMemBuf::getInstance()->size_of(1);
|
TxMemBuf::getInstance()->size_of(0) : TxMemBuf::getInstance()->size_of(1);
|
||||||
|
|
||||||
if (!_gzdest0 || !_gzdest1 || !_gzdestLen) {
|
if (!_gzdest0 || !_gzdest1 || !_gzdestLen) {
|
||||||
_pTxCache->_options &= ~(GZ_TEXCACHE | GZ_HIRESTEXCACHE);
|
_options &= ~(GZ_TEXCACHE | GZ_HIRESTEXCACHE);
|
||||||
_gzdest0 = nullptr;
|
_gzdest0 = nullptr;
|
||||||
_gzdest1 = nullptr;
|
_gzdest1 = nullptr;
|
||||||
_gzdestLen = 0;
|
_gzdestLen = 0;
|
||||||
|
@ -94,7 +115,7 @@ TxCache::TxCacheImpl::TxCacheImpl(const TxCache* pCache, uint64 cacheLimit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TxCache::TxCacheImpl::add(Checksum checksum, GHQTexInfo *info, int dataSize)
|
bool TxMemoryCache::add(Checksum checksum, GHQTexInfo *info, int dataSize)
|
||||||
{
|
{
|
||||||
/* NOTE: dataSize must be provided if info->data is zlib compressed. */
|
/* NOTE: dataSize must be provided if info->data is zlib compressed. */
|
||||||
|
|
||||||
|
@ -110,7 +131,7 @@ bool TxCache::TxCacheImpl::add(Checksum checksum, GHQTexInfo *info, int dataSize
|
||||||
if (!dataSize)
|
if (!dataSize)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (_pTxCache->_options & (GZ_TEXCACHE | GZ_HIRESTEXCACHE)) {
|
if (_options & (GZ_TEXCACHE | GZ_HIRESTEXCACHE)) {
|
||||||
/* zlib compress it. compression level:1 (best speed) */
|
/* zlib compress it. compression level:1 (best speed) */
|
||||||
uLongf destLen = _gzdestLen;
|
uLongf destLen = _gzdestLen;
|
||||||
dest = (dest == _gzdest0) ? _gzdest1 : _gzdest0;
|
dest = (dest == _gzdest0) ? _gzdest1 : _gzdest0;
|
||||||
|
@ -202,7 +223,7 @@ bool TxCache::TxCacheImpl::add(Checksum checksum, GHQTexInfo *info, int dataSize
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TxCache::TxCacheImpl::get(Checksum checksum, GHQTexInfo *info)
|
bool TxMemoryCache::get(Checksum checksum, GHQTexInfo *info)
|
||||||
{
|
{
|
||||||
if (!checksum || _cache.empty())
|
if (!checksum || _cache.empty())
|
||||||
return false;
|
return false;
|
||||||
|
@ -239,7 +260,7 @@ bool TxCache::TxCacheImpl::get(Checksum checksum, GHQTexInfo *info)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TxCache::TxCacheImpl::save(const wchar_t *path, const wchar_t *filename, int config)
|
bool TxMemoryCache::save(const wchar_t *path, const wchar_t *filename, int config)
|
||||||
{
|
{
|
||||||
if (_cache.empty())
|
if (_cache.empty())
|
||||||
return false;
|
return false;
|
||||||
|
@ -249,7 +270,6 @@ bool TxCache::TxCacheImpl::save(const wchar_t *path, const wchar_t *filename, in
|
||||||
|
|
||||||
osal_mkdirp(path);
|
osal_mkdirp(path);
|
||||||
|
|
||||||
/* Ugly hack to enable fopen/gzopen in Win9x */
|
|
||||||
#ifdef OS_WINDOWS
|
#ifdef OS_WINDOWS
|
||||||
wchar_t curpath[MAX_PATH];
|
wchar_t curpath[MAX_PATH];
|
||||||
GETCWD(MAX_PATH, curpath);
|
GETCWD(MAX_PATH, curpath);
|
||||||
|
@ -311,8 +331,8 @@ bool TxCache::TxCacheImpl::save(const wchar_t *path, const wchar_t *filename, in
|
||||||
|
|
||||||
itMap++;
|
itMap++;
|
||||||
|
|
||||||
if (_pTxCache->_callback)
|
if (_callback)
|
||||||
(*_pTxCache->_callback)(wst("Total textures saved to HDD: %d\n"), ++total);
|
(*_callback)(wst("Total textures saved to HDD: %d\n"), ++total);
|
||||||
}
|
}
|
||||||
gzclose(gzfp);
|
gzclose(gzfp);
|
||||||
}
|
}
|
||||||
|
@ -322,7 +342,7 @@ bool TxCache::TxCacheImpl::save(const wchar_t *path, const wchar_t *filename, in
|
||||||
return !_cache.empty();
|
return !_cache.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TxCache::TxCacheImpl::load(const wchar_t *path, const wchar_t *filename, int config, boolean force)
|
bool TxMemoryCache::load(const wchar_t *path, const wchar_t *filename, int config, boolean force)
|
||||||
{
|
{
|
||||||
/* find it on disk */
|
/* find it on disk */
|
||||||
char cbuf[MAX_PATH];
|
char cbuf[MAX_PATH];
|
||||||
|
@ -379,8 +399,8 @@ bool TxCache::TxCacheImpl::load(const wchar_t *path, const wchar_t *filename, in
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skip in between to prevent the loop from being tied down to vsync */
|
/* skip in between to prevent the loop from being tied down to vsync */
|
||||||
if (_pTxCache->_callback && (!(_cache.size() % 100) || gzeof(gzfp)))
|
if (_callback && (!(_cache.size() % 100) || gzeof(gzfp)))
|
||||||
(*_pTxCache->_callback)(wst("[%d] total mem:%.02fmb - %ls\n"), _cache.size(), (float)_totalSize / 1000000, filename);
|
(*_callback)(wst("[%d] total mem:%.02fmb - %ls\n"), _cache.size(), (float)_totalSize / 1000000, filename);
|
||||||
|
|
||||||
} while (!gzeof(gzfp));
|
} while (!gzeof(gzfp));
|
||||||
gzclose(gzfp);
|
gzclose(gzfp);
|
||||||
|
@ -392,7 +412,7 @@ bool TxCache::TxCacheImpl::load(const wchar_t *path, const wchar_t *filename, in
|
||||||
return !_cache.empty();
|
return !_cache.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TxCache::TxCacheImpl::del(Checksum checksum)
|
bool TxMemoryCache::del(Checksum checksum)
|
||||||
{
|
{
|
||||||
if (!checksum || _cache.empty())
|
if (!checksum || _cache.empty())
|
||||||
return false;
|
return false;
|
||||||
|
@ -418,12 +438,12 @@ bool TxCache::TxCacheImpl::del(Checksum checksum)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TxCache::TxCacheImpl::isCached(Checksum checksum)
|
bool TxMemoryCache::isCached(Checksum checksum)
|
||||||
{
|
{
|
||||||
return _cache.find(checksum) != _cache.end();
|
return _cache.find(checksum) != _cache.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TxCache::TxCacheImpl::clear()
|
void TxMemoryCache::clear()
|
||||||
{
|
{
|
||||||
if (!_cache.empty()) {
|
if (!_cache.empty()) {
|
||||||
auto itMap = _cache.begin();
|
auto itMap = _cache.begin();
|
||||||
|
@ -462,7 +482,7 @@ TxCache::TxCache(uint32 options,
|
||||||
if (ident)
|
if (ident)
|
||||||
_ident.assign(ident);
|
_ident.assign(ident);
|
||||||
|
|
||||||
_pImpl.reset(new TxCacheImpl(this, cachesize));
|
_pImpl.reset(new TxMemoryCache(_options, cachesize, _callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TxCache::add(Checksum checksum, GHQTexInfo *info, int dataSize)
|
bool TxCache::add(Checksum checksum, GHQTexInfo *info, int dataSize)
|
||||||
|
|
|
@ -52,17 +52,15 @@ struct Checksum
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//class TxCacheImpl;
|
class TxCacheImpl;
|
||||||
|
|
||||||
class TxCache
|
class TxCache
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
class TxCacheImpl;
|
|
||||||
friend class TxCacheImpl;
|
|
||||||
std::unique_ptr<TxCacheImpl> _pImpl;
|
std::unique_ptr<TxCacheImpl> _pImpl;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
mutable uint32 _options;
|
uint32 _options;
|
||||||
tx_wstring _ident;
|
tx_wstring _ident;
|
||||||
tx_wstring _cachePath;
|
tx_wstring _cachePath;
|
||||||
dispInfoFuncExt _callback;
|
dispInfoFuncExt _callback;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user