aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/lltexturecache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/lltexturecache.cpp')
-rw-r--r--linden/indra/newview/lltexturecache.cpp214
1 files changed, 182 insertions, 32 deletions
diff --git a/linden/indra/newview/lltexturecache.cpp b/linden/indra/newview/lltexturecache.cpp
index 11fd348..c31fbba 100644
--- a/linden/indra/newview/lltexturecache.cpp
+++ b/linden/indra/newview/lltexturecache.cpp
@@ -50,15 +50,6 @@ class LLTextureCacheWorker : public LLWorkerClass
50 friend class LLTextureCache; 50 friend class LLTextureCache;
51 51
52private: 52private:
53 enum e_state
54 {
55 INIT = 0,
56 LOCAL = 1,
57 CACHE = 2,
58 HEADER = 3,
59 BODY = 4
60 };
61
62 class ReadResponder : public LLLFSThread::Responder 53 class ReadResponder : public LLLFSThread::Responder
63 { 54 {
64 public: 55 public:
@@ -97,10 +88,9 @@ public:
97 S32 imagesize, // for writes 88 S32 imagesize, // for writes
98 LLTextureCache::Responder* responder) 89 LLTextureCache::Responder* responder)
99 : LLWorkerClass(cache, "LLTextureCacheWorker"), 90 : LLWorkerClass(cache, "LLTextureCacheWorker"),
91 mID(id),
100 mCache(cache), 92 mCache(cache),
101 mPriority(priority), 93 mPriority(priority),
102 mID(id),
103 mState(INIT),
104 mReadData(NULL), 94 mReadData(NULL),
105 mWriteData(data), 95 mWriteData(data),
106 mDataSize(datasize), 96 mDataSize(datasize),
@@ -121,8 +111,10 @@ public:
121 delete[] mReadData; 111 delete[] mReadData;
122 } 112 }
123 113
124 bool doRead(); 114 // override this interface
125 bool doWrite(); 115 virtual bool doRead() = 0;
116 virtual bool doWrite() = 0;
117
126 virtual bool doWork(S32 param); // Called from LLWorkerThread::processRequest() 118 virtual bool doWork(S32 param); // Called from LLWorkerThread::processRequest()
127 119
128 handle_t read() { addWork(0, LLWorkerThread::PRIORITY_HIGH | mPriority); return mRequestHandle; } 120 handle_t read() { addWork(0, LLWorkerThread::PRIORITY_HIGH | mPriority); return mRequestHandle; }
@@ -133,24 +125,23 @@ public:
133 mBytesRead = bytes; 125 mBytesRead = bytes;
134 setPriority(LLWorkerThread::PRIORITY_HIGH | mPriority); 126 setPriority(LLWorkerThread::PRIORITY_HIGH | mPriority);
135 } 127 }
136 128
137private: 129private:
138 virtual void startWork(S32 param); // called from addWork() (MAIN THREAD) 130 virtual void startWork(S32 param); // called from addWork() (MAIN THREAD)
139 virtual void finishWork(S32 param, bool completed); // called from finishRequest() (WORK THREAD) 131 virtual void finishWork(S32 param, bool completed); // called from finishRequest() (WORK THREAD)
140 virtual void endWork(S32 param, bool aborted); // called from doWork() (MAIN THREAD) 132 virtual void endWork(S32 param, bool aborted); // called from doWork() (MAIN THREAD)
141 133
142private: 134protected:
143 LLTextureCache* mCache; 135 LLTextureCache* mCache;
144 U32 mPriority; 136 U32 mPriority;
145 LLUUID mID; 137 LLUUID mID;
146 e_state mState;
147 138
148 U8* mReadData; 139 U8* mReadData;
149 U8* mWriteData; 140 U8* mWriteData;
150 S32 mDataSize; 141 S32 mDataSize;
151 S32 mOffset; 142 S32 mOffset;
152 S32 mImageSize; 143 S32 mImageSize;
153 S32 mImageFormat; 144 EImageCodec mImageFormat;
154 BOOL mImageLocal; 145 BOOL mImageLocal;
155 LLPointer<LLTextureCache::Responder> mResponder; 146 LLPointer<LLTextureCache::Responder> mResponder;
156 LLLFSThread::handle_t mFileHandle; 147 LLLFSThread::handle_t mFileHandle;
@@ -158,19 +149,169 @@ private:
158 LLAtomicS32 mBytesRead; 149 LLAtomicS32 mBytesRead;
159}; 150};
160 151
152class LLTextureCacheLocalFileWorker : public LLTextureCacheWorker
153{
154public:
155 LLTextureCacheLocalFileWorker(LLTextureCache* cache, U32 priority, const LLString& filename, const LLUUID& id,
156 U8* data, S32 datasize, S32 offset,
157 S32 imagesize, // for writes
158 LLTextureCache::Responder* responder)
159 : LLTextureCacheWorker(cache, priority, id, data, datasize, offset, imagesize, responder),
160 mFileName(filename)
161
162 {
163 }
164
165 virtual bool doRead();
166 virtual bool doWrite();
167
168private:
169 LLString mFileName;
170};
171
172bool LLTextureCacheLocalFileWorker::doRead()
173{
174 S32 local_size = ll_apr_file_size(mFileName, mCache->getFileAPRPool());
175
176 if (local_size > 0 && mFileName.size() > 4)
177 {
178 mDataSize = local_size; // Only a complete file is valid
179
180 LLString extension = mFileName.substr(mFileName.size() - 3, 3);
181
182 mImageFormat = LLImageBase::getCodecFromExtension(extension);
183
184 if (mImageFormat == IMG_CODEC_INVALID)
185 {
186 llwarns << "Unrecognized file extension " << extension << " for local texture " << mFileName << llendl;
187 mDataSize = 0; // no data
188 return true;
189 }
190 }
191 else
192 {
193 // file doesn't exist
194 mDataSize = 0; // no data
195 return true;
196 }
197
198#if USE_LFS_READ
199 if (mFileHandle == LLLFSThread::nullHandle())
200 {
201 mImageLocal = TRUE;
202 mImageSize = local_size;
203 if (!mDataSize || mDataSize + mOffset > local_size)
204 {
205 mDataSize = local_size - mOffset;
206 }
207 if (mDataSize <= 0)
208 {
209 // no more data to read
210 mDataSize = 0;
211 return true;
212 }
213 mReadData = new U8[mDataSize];
214 mBytesRead = -1;
215 mBytesToRead = mDataSize;
216 setPriority(LLWorkerThread::PRIORITY_LOW | mPriority);
217 mFileHandle = LLLFSThread::sLocal->read(local_filename, mReadData, mOffset, mDataSize,
218 new ReadResponder(mCache, mRequestHandle));
219 return false;
220 }
221 else
222 {
223 if (mBytesRead >= 0)
224 {
225 if (mBytesRead != mBytesToRead)
226 {
227 llwarns << "Error reading file from local cache: " << local_filename
228 << " Bytes: " << mDataSize << " Offset: " << mOffset
229 << " / " << mDataSize << llendl;
230 mDataSize = 0; // failed
231 delete[] mReadData;
232 mReadData = NULL;
233 }
234 return true;
235 }
236 else
237 {
238 return false;
239 }
240 }
241#else
242 if (!mDataSize || mDataSize > local_size)
243 {
244 mDataSize = local_size;
245 }
246 mReadData = new U8[mDataSize];
247 S32 bytes_read = ll_apr_file_read_ex(mFileName, mCache->getFileAPRPool(),
248 mReadData, mOffset, mDataSize);
249 if (bytes_read != mDataSize)
250 {
251 llwarns << "Error reading file from local cache: " << mFileName
252 << " Bytes: " << mDataSize << " Offset: " << mOffset
253 << " / " << mDataSize << llendl;
254 mDataSize = 0;
255 delete[] mReadData;
256 mReadData = NULL;
257 }
258 else
259 {
260 mImageSize = local_size;
261 mImageLocal = TRUE;
262 }
263 return true;
264#endif
265}
266
267bool LLTextureCacheLocalFileWorker::doWrite()
268{
269 // no writes for local files
270 return false;
271}
272
273class LLTextureCacheRemoteWorker : public LLTextureCacheWorker
274{
275public:
276 LLTextureCacheRemoteWorker(LLTextureCache* cache, U32 priority, const LLUUID& id,
277 U8* data, S32 datasize, S32 offset,
278 S32 imagesize, // for writes
279 LLTextureCache::Responder* responder)
280 : LLTextureCacheWorker(cache, priority, id, data, datasize, offset, imagesize, responder),
281 mState(INIT)
282 {
283 }
284
285 virtual bool doRead();
286 virtual bool doWrite();
287
288private:
289 enum e_state
290 {
291 INIT = 0,
292 LOCAL = 1,
293 CACHE = 2,
294 HEADER = 3,
295 BODY = 4
296 };
297
298 e_state mState;
299};
300
301
161//virtual 302//virtual
162void LLTextureCacheWorker::startWork(S32 param) 303void LLTextureCacheWorker::startWork(S32 param)
163{ 304{
164} 305}
165 306
166bool LLTextureCacheWorker::doRead() 307bool LLTextureCacheRemoteWorker::doRead()
167{ 308{
168 S32 local_size = 0; 309 S32 local_size = 0;
169 std::string local_filename; 310 std::string local_filename;
170 311
171 if (mState == INIT) 312 if (mState == INIT)
172 { 313 {
173 std::string filename = mCache->getLocalFileName(mID); 314 std::string filename = mCache->getLocalFileName(mID);
174 local_filename = filename + ".j2c"; 315 local_filename = filename + ".j2c";
175 local_size = ll_apr_file_size(local_filename, mCache->getFileAPRPool()); 316 local_size = ll_apr_file_size(local_filename, mCache->getFileAPRPool());
176 if (local_size == 0) 317 if (local_size == 0)
@@ -468,19 +609,13 @@ bool LLTextureCacheWorker::doRead()
468 return false; 609 return false;
469} 610}
470 611
471bool LLTextureCacheWorker::doWrite() 612bool LLTextureCacheRemoteWorker::doWrite()
472{ 613{
473 S32 idx = -1; 614 S32 idx = -1;
474 615
475 if (mState == INIT)
476 {
477 llassert_always(mOffset == 0); // Currently don't support offsets
478 mState = CACHE;
479 }
480
481 // No LOCAL state for write() 616 // No LOCAL state for write()
482 617
483 if (mState == CACHE) 618 if (mState == INIT)
484 { 619 {
485 S32 cur_imagesize = 0; 620 S32 cur_imagesize = 0;
486 S32 offset = mOffset; 621 S32 offset = mOffset;
@@ -921,9 +1056,9 @@ struct lru_data
921 typedef const lru_data* lru_data_ptr; 1056 typedef const lru_data* lru_data_ptr;
922 bool operator()(const lru_data_ptr& a, const lru_data_ptr& b) const 1057 bool operator()(const lru_data_ptr& a, const lru_data_ptr& b) const
923 { 1058 {
924 if (!(a->time < b->time)) 1059 if (a->time > b->time)
925 return true; 1060 return true;
926 else if (!(b->time < a->time)) 1061 else if (b->time > a->time)
927 return false; 1062 return false;
928 else 1063 else
929 return a->index < b->index; 1064 return a->index < b->index;
@@ -1250,13 +1385,27 @@ S32 LLTextureCache::getHeaderCacheEntry(const LLUUID& id, bool touch, S32* image
1250 1385
1251// Calls from texture pipeline thread (i.e. LLTextureFetch) 1386// Calls from texture pipeline thread (i.e. LLTextureFetch)
1252 1387
1388LLTextureCache::handle_t LLTextureCache::readFromCache(const LLString& filename, const LLUUID& id, U32 priority,
1389 S32 offset, S32 size, ReadResponder* responder)
1390{
1391 // Note: checking to see if an entry exists can cause a stall,
1392 // so let the thread handle it
1393 LLMutexLock lock(&mWorkersMutex);
1394 LLTextureCacheWorker* worker = new LLTextureCacheLocalFileWorker(this, priority, filename, id,
1395 NULL, size, offset, 0,
1396 responder);
1397 handle_t handle = worker->read();
1398 mReaders[handle] = worker;
1399 return handle;
1400}
1401
1253LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id, U32 priority, 1402LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id, U32 priority,
1254 S32 offset, S32 size, ReadResponder* responder) 1403 S32 offset, S32 size, ReadResponder* responder)
1255{ 1404{
1256 // Note: checking to see if an entry exists can cause a stall, 1405 // Note: checking to see if an entry exists can cause a stall,
1257 // so let the thread handle it 1406 // so let the thread handle it
1258 LLMutexLock lock(&mWorkersMutex); 1407 LLMutexLock lock(&mWorkersMutex);
1259 LLTextureCacheWorker* worker = new LLTextureCacheWorker(this, priority, id, 1408 LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id,
1260 NULL, size, offset, 0, 1409 NULL, size, offset, 0,
1261 responder); 1410 responder);
1262 handle_t handle = worker->read(); 1411 handle_t handle = worker->read();
@@ -1264,6 +1413,7 @@ LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id, U32 pri
1264 return handle; 1413 return handle;
1265} 1414}
1266 1415
1416
1267bool LLTextureCache::readComplete(handle_t handle, bool abort) 1417bool LLTextureCache::readComplete(handle_t handle, bool abort)
1268{ 1418{
1269 lockWorkers(); 1419 lockWorkers();
@@ -1306,7 +1456,7 @@ LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 prio
1306 { 1456 {
1307 LLMutexLock lock(&mWorkersMutex); 1457 LLMutexLock lock(&mWorkersMutex);
1308 llassert_always(imagesize > 0); 1458 llassert_always(imagesize > 0);
1309 LLTextureCacheWorker* worker = new LLTextureCacheWorker(this, priority, id, 1459 LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id,
1310 data, datasize, 0, 1460 data, datasize, 0,
1311 imagesize, responder); 1461 imagesize, responder);
1312 handle_t handle = worker->write(); 1462 handle_t handle = worker->write();