1
0
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:
Sergey Lipskiy 2019-05-23 00:05:33 +07:00
parent a1a443ca47
commit dee7065982
2 changed files with 62 additions and 44 deletions

View File

@ -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)

View File

@ -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;