71 #include <sys/types.h> 93 bool isAbsolute = (filename[0] ==
'/' 95 || filename[0] ==
'\\' 96 || (isalpha(filename[0]) && filename[1] ==
':')
99 if (isAbsolute || _searchdirs.empty())
return true;
104 for (
size_t i = 0, size = _searchdirs.size(); i < size; i++) {
105 buffer = _searchdirs[i];
108 if (stat(buffer.c_str(), &statbuf) == 0) {
109 filename = buffer.c_str();
114 std::string errstr =
"Can't find ptex file: ";
116 error = errstr.
c_str();
129 if (!reader->
ok())
return 0;
143 const char* pathToOpen = filename;
145 if (
_io || findFile(pathToOpen, buffer, error)) {
146 reader->
open(pathToOpen, error);
154 size_t newMemUsed = 0;
156 reader = _files.tryInsert(key, reader, newMemUsed);
157 adjustMemUsed(newMemUsed);
158 if (reader != newreader) {
182 if (maxFiles <= 0) maxFiles = 100;
184 return new PtexReaderCache(maxFiles, maxMem, premultiply, inputHandler, errorHandler);
193 if (slot < numMruFiles) {
194 mruList->
files[slot] = reader;
199 while (_mruList->next >= numMruFiles);
207 if (!_mruLock.trylock())
return;
208 if (_mruList->next < numMruFiles) {
216 _prevMruList = mruList;
219 size_t memUsedChange = 0, filesOpenChange = 0;
220 for (
int i = 0; i < numMruFiles; ++i) {
222 do { reader = mruList->
files[i]; }
while (!reader);
223 mruList->
files[i] = 0;
227 filesOpenChange += opens;
228 if (opens || blockReads) {
231 _openFiles.push(reader);
234 _activeFiles.push(reader);
238 adjustMemUsed(memUsedChange);
239 adjustFilesOpen(filesOpenChange);
241 bool shouldPruneFiles = _filesOpen > _maxFiles;
242 bool shouldPruneData = _maxMem &&
_memUsed > _maxMem;
244 if (shouldPruneFiles) {
247 if (shouldPruneData) {
256 size_t numToClose = _filesOpen - _maxFiles;
257 if (numToClose > 0) {
260 if (!reader) { _filesOpen = 0;
break; }
272 size_t memUsedChangeTotal = 0;
274 while (memUsed + memUsedChangeTotal > _maxMem) {
277 size_t memUsedChange;
278 if (reader->
tryPrune(memUsedChange)) {
280 memUsedChangeTotal += memUsedChange;
283 adjustMemUsed(memUsedChangeTotal);
300 if (reader)
purge(reader);
305 size_t memUsedChange;
306 if (reader->
tryPurge(memUsedChange)) {
307 adjustMemUsed(memUsedChange);
313 size_t memUsedChange;
314 if (reader->
tryPurge(memUsedChange)) {
315 memUsedChangeTotal += memUsedChange;
322 _files.foreach(purger);
virtual PtexTexture * get(const char *path, Ptex::String &error)
Access a texture.
virtual void getStats(Stats &stats)
Get stats.
File-handle and memory cache for reading ptex files.
PtexCachedReader(bool premultiply, PtexInputHandler *inputHandler, PtexErrorHandler *errorHandler, PtexReaderCache *cache)
bool findFile(const char *&filename, std::string &buffer, Ptex::String &error)
const char * c_str() const
bool tryPurge(size_t &memUsedChange)
Custom handler interface redirecting Ptex error messages.
friend class PtexReaderCache
void operator()(PtexCachedReader *reader)
void logRecentlyUsed(PtexCachedReader *reader)
virtual void release()
Release resources held by this pointer (pointer becomes invalid).
Interface for reading data from a ptex file.
static PtexCache * create(int maxFiles, size_t maxMem, bool premultiply=false, PtexInputHandler *inputHandler=0, PtexErrorHandler *errorHandler=0)
Create a cache with the specified limits.
bool tryPrune(size_t &memUsedChange)
size_t getBlockReadsChange()
bool pendingPurge() const
bool open(const char *path, Ptex::String &error)
size_t memUsedChangeTotal
virtual void purgeAll()
Remove all texture files from the cache.
virtual void purge(PtexTexture *)
Remove a texture file from the cache.
size_t getMemUsedChange()
PtexCachedReader *volatile files[numMruFiles]
#define PTEX_NAMESPACE_END
volatile size_t _blockReads
Public API classes for reading, writing, caching, and filtering Ptex files.