aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llimage
diff options
context:
space:
mode:
authorJacek Antonelli2010-02-09 21:11:42 -0600
committerJacek Antonelli2010-02-16 18:50:15 -0600
commite6247fbe78c4d3dacb74f3b2359aba2b6538133b (patch)
tree10c42d670a2c635b4339f7f68809c221756774f8 /linden/indra/llimage
parentPorted some cURL and HTTP-related changes from Snowglobe. (diff)
downloadmeta-impy-e6247fbe78c4d3dacb74f3b2359aba2b6538133b.zip
meta-impy-e6247fbe78c4d3dacb74f3b2359aba2b6538133b.tar.gz
meta-impy-e6247fbe78c4d3dacb74f3b2359aba2b6538133b.tar.bz2
meta-impy-e6247fbe78c4d3dacb74f3b2359aba2b6538133b.tar.xz
Ported many texture engine changes from Snowglobe.
Diffstat (limited to 'linden/indra/llimage')
-rw-r--r--linden/indra/llimage/llimage.cpp38
-rw-r--r--linden/indra/llimage/llimage.h8
-rw-r--r--linden/indra/llimage/llimagedxt.cpp19
-rw-r--r--linden/indra/llimage/llimagej2c.cpp5
-rw-r--r--linden/indra/llimage/llimagejpeg.cpp9
-rw-r--r--linden/indra/llimage/llimageworker.cpp202
-rw-r--r--linden/indra/llimage/llimageworker.h97
7 files changed, 198 insertions, 180 deletions
diff --git a/linden/indra/llimage/llimage.cpp b/linden/indra/llimage/llimage.cpp
index 4b0076e..32891e7 100644
--- a/linden/indra/llimage/llimage.cpp
+++ b/linden/indra/llimage/llimage.cpp
@@ -55,13 +55,9 @@ std::string LLImage::sLastErrorMessage;
55LLMutex* LLImage::sMutex = NULL; 55LLMutex* LLImage::sMutex = NULL;
56 56
57//static 57//static
58void LLImage::initClass(LLWorkerThread* workerthread) 58void LLImage::initClass()
59{ 59{
60 sMutex = new LLMutex(NULL); 60 sMutex = new LLMutex(NULL);
61 if (workerthread)
62 {
63 LLImageWorker::initImageWorker(workerthread);
64 }
65 LLImageJ2C::openDSO(); 61 LLImageJ2C::openDSO();
66} 62}
67 63
@@ -69,7 +65,6 @@ void LLImage::initClass(LLWorkerThread* workerthread)
69void LLImage::cleanupClass() 65void LLImage::cleanupClass()
70{ 66{
71 LLImageJ2C::closeDSO(); 67 LLImageJ2C::closeDSO();
72 LLImageWorker::cleanupImageWorker();
73 delete sMutex; 68 delete sMutex;
74 sMutex = NULL; 69 sMutex = NULL;
75} 70}
@@ -1242,25 +1237,28 @@ bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip
1242 ifs.read ((char*)buffer, length); /* Flawfinder: ignore */ 1237 ifs.read ((char*)buffer, length); /* Flawfinder: ignore */
1243 ifs.close(); 1238 ifs.close();
1244 1239
1245 image->updateData(); 1240 BOOL success;
1246 1241
1247 if (j2c_lowest_mip_only && codec == IMG_CODEC_J2C) 1242 success = image->updateData();
1243 if (success)
1248 { 1244 {
1249 S32 width = image->getWidth(); 1245 if (j2c_lowest_mip_only && codec == IMG_CODEC_J2C)
1250 S32 height = image->getHeight();
1251 S32 discard_level = 0;
1252 while (width > 1 && height > 1 && discard_level < MAX_DISCARD_LEVEL)
1253 { 1246 {
1254 width >>= 1; 1247 S32 width = image->getWidth();
1255 height >>= 1; 1248 S32 height = image->getHeight();
1256 discard_level++; 1249 S32 discard_level = 0;
1250 while (width > 1 && height > 1 && discard_level < MAX_DISCARD_LEVEL)
1251 {
1252 width >>= 1;
1253 height >>= 1;
1254 discard_level++;
1255 }
1256 ((LLImageJ2C *)((LLImageFormatted*)image))->setDiscardLevel(discard_level);
1257 } 1257 }
1258 ((LLImageJ2C *)((LLImageFormatted*)image))->setDiscardLevel(discard_level); 1258 success = image->decode(this, 100000.0f);
1259 } 1259 }
1260
1261 BOOL success = image->decode(this, 100000.0f);
1262 image = NULL; // deletes image
1263 1260
1261 image = NULL; // deletes image
1264 if (!success) 1262 if (!success)
1265 { 1263 {
1266 deleteData(); 1264 deleteData();
diff --git a/linden/indra/llimage/llimage.h b/linden/indra/llimage/llimage.h
index bd609b6..be2eb08 100644
--- a/linden/indra/llimage/llimage.h
+++ b/linden/indra/llimage/llimage.h
@@ -49,7 +49,8 @@ const S32 MAX_IMAGE_AREA = MAX_IMAGE_SIZE * MAX_IMAGE_SIZE;
49const S32 MAX_IMAGE_COMPONENTS = 8; 49const S32 MAX_IMAGE_COMPONENTS = 8;
50const S32 MAX_IMAGE_DATA_SIZE = MAX_IMAGE_AREA * MAX_IMAGE_COMPONENTS; 50const S32 MAX_IMAGE_DATA_SIZE = MAX_IMAGE_AREA * MAX_IMAGE_COMPONENTS;
51 51
52// Note! These CANNOT be changed without invalidating the viewer VFS files, I think? 52// Note! These CANNOT be changed without modifying simulator code
53// *TODO: change both to 1024 when SIM texture fetching is deprecated
53const S32 FIRST_PACKET_SIZE = 600; 54const S32 FIRST_PACKET_SIZE = 600;
54const S32 MAX_IMG_PACKET_SIZE = 1000; 55const S32 MAX_IMG_PACKET_SIZE = 1000;
55 56
@@ -60,7 +61,6 @@ const S32 MAX_IMG_PACKET_SIZE = 1000;
60class LLImageFormatted; 61class LLImageFormatted;
61class LLImageRaw; 62class LLImageRaw;
62class LLColor4U; 63class LLColor4U;
63class LLWorkerThread;
64 64
65typedef enum e_image_codec 65typedef enum e_image_codec
66{ 66{
@@ -81,7 +81,7 @@ typedef enum e_image_codec
81class LLImage 81class LLImage
82{ 82{
83public: 83public:
84 static void initClass(LLWorkerThread* workerthread); 84 static void initClass();
85 static void cleanupClass(); 85 static void cleanupClass();
86 86
87 static const std::string& getLastError(); 87 static const std::string& getLastError();
@@ -309,7 +309,7 @@ protected:
309protected: 309protected:
310 S8 mCodec; 310 S8 mCodec;
311 S8 mDecoding; 311 S8 mDecoding;
312 S8 mDecoded; 312 S8 mDecoded; // unused, but changing LLImage layout requires recompiling static Mac/Linux libs. 2009-01-30 JC
313 S8 mDiscardLevel; 313 S8 mDiscardLevel;
314 314
315public: 315public:
diff --git a/linden/indra/llimage/llimagedxt.cpp b/linden/indra/llimage/llimagedxt.cpp
index 1ce4517..0aa6840 100644
--- a/linden/indra/llimage/llimagedxt.cpp
+++ b/linden/indra/llimage/llimagedxt.cpp
@@ -264,6 +264,8 @@ void LLImageDXT::setFormat()
264// virtual 264// virtual
265BOOL LLImageDXT::decode(LLImageRaw* raw_image, F32 time) 265BOOL LLImageDXT::decode(LLImageRaw* raw_image, F32 time)
266{ 266{
267 // *TODO: Test! This has been tweaked since its intial inception,
268 // but we don't use it any more!
267 llassert_always(raw_image); 269 llassert_always(raw_image);
268 270
269 if (mFileFormat >= FORMAT_DXT1 && mFileFormat <= FORMAT_DXR5) 271 if (mFileFormat >= FORMAT_DXT1 && mFileFormat <= FORMAT_DXR5)
@@ -274,8 +276,17 @@ BOOL LLImageDXT::decode(LLImageRaw* raw_image, F32 time)
274 276
275 S32 width = getWidth(), height = getHeight(); 277 S32 width = getWidth(), height = getHeight();
276 S32 ncomponents = getComponents(); 278 S32 ncomponents = getComponents();
279 U8* data = NULL;
280 if (mDiscardLevel >= 0)
281 {
282 data = getData() + getMipOffset(mDiscardLevel);
283 calcDiscardWidthHeight(mDiscardLevel, mFileFormat, width, height);
284 }
285 else
286 {
287 data = getData() + getMipOffset(0);
288 }
277 S32 image_size = formatBytes(mFileFormat, width, height); 289 S32 image_size = formatBytes(mFileFormat, width, height);
278 U8* data = getData() + getMipOffset(0);
279 290
280 if ((!getData()) || (data + image_size > getData() + getDataSize())) 291 if ((!getData()) || (data + image_size > getData() + getDataSize()))
281 { 292 {
@@ -300,10 +311,8 @@ BOOL LLImageDXT::getMipData(LLPointer<LLImageRaw>& raw, S32 discard)
300 llerrs << "Request for invalid discard level" << llendl; 311 llerrs << "Request for invalid discard level" << llendl;
301 } 312 }
302 U8* data = getData() + getMipOffset(discard); 313 U8* data = getData() + getMipOffset(discard);
303 // I'm not sure these are the correct initial values for height and width, 314 S32 width = 0;
304 // but previously they were being used uninitialized. JC 315 S32 height = 0;
305 S32 width = raw->getWidth();
306 S32 height = raw->getHeight();
307 calcDiscardWidthHeight(discard, mFileFormat, width, height); 316 calcDiscardWidthHeight(discard, mFileFormat, width, height);
308 raw = new LLImageRaw(data, width, height, getComponents()); 317 raw = new LLImageRaw(data, width, height, getComponents());
309 return TRUE; 318 return TRUE;
diff --git a/linden/indra/llimage/llimagej2c.cpp b/linden/indra/llimage/llimagej2c.cpp
index ed58f85..1aae83e 100644
--- a/linden/indra/llimage/llimagej2c.cpp
+++ b/linden/indra/llimage/llimagej2c.cpp
@@ -277,6 +277,7 @@ BOOL LLImageJ2C::decode(LLImageRaw *raw_imagep, F32 decode_time)
277} 277}
278 278
279 279
280// Returns TRUE to mean done, whether successful or not.
280BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 first_channel, S32 max_channel_count ) 281BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 first_channel, S32 max_channel_count )
281{ 282{
282 LLMemType mt1((LLMemType::EMemType)mMemType); 283 LLMemType mt1((LLMemType::EMemType)mMemType);
@@ -289,7 +290,7 @@ BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 fir
289 if (!getData() || (getDataSize() < 16)) 290 if (!getData() || (getDataSize() < 16))
290 { 291 {
291 setLastError("LLImageJ2C uninitialized"); 292 setLastError("LLImageJ2C uninitialized");
292 res = FALSE; 293 res = TRUE; // done
293 } 294 }
294 else 295 else
295 { 296 {
@@ -342,7 +343,7 @@ BOOL LLImageJ2C::encode(const LLImageRaw *raw_imagep, const char* comment_text,
342//static 343//static
343S32 LLImageJ2C::calcHeaderSizeJ2C() 344S32 LLImageJ2C::calcHeaderSizeJ2C()
344{ 345{
345 return 600; //2048; // ??? hack... just needs to be >= actual header size... 346 return FIRST_PACKET_SIZE; // Hack. just needs to be >= actual header size...
346} 347}
347 348
348//static 349//static
diff --git a/linden/indra/llimage/llimagejpeg.cpp b/linden/indra/llimage/llimagejpeg.cpp
index fa0dd3f..79ea79c 100644
--- a/linden/indra/llimage/llimagejpeg.cpp
+++ b/linden/indra/llimage/llimagejpeg.cpp
@@ -188,6 +188,7 @@ void LLImageJPEG::decodeTermSource (j_decompress_ptr cinfo)
188} 188}
189 189
190 190
191// Returns true when done, whether or not decode was successful.
191BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time) 192BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)
192{ 193{
193 llassert_always(raw_image); 194 llassert_always(raw_image);
@@ -198,7 +199,7 @@ BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)
198 if (!getData() || (0 == getDataSize())) 199 if (!getData() || (0 == getDataSize()))
199 { 200 {
200 setLastError("LLImageJPEG trying to decode an image with no data!"); 201 setLastError("LLImageJPEG trying to decode an image with no data!");
201 return FALSE; 202 return TRUE; // done
202 } 203 }
203 204
204 S32 row_stride = 0; 205 S32 row_stride = 0;
@@ -226,7 +227,7 @@ BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)
226 if(setjmp(sSetjmpBuffer)) 227 if(setjmp(sSetjmpBuffer))
227 { 228 {
228 jpeg_destroy_decompress(&cinfo); 229 jpeg_destroy_decompress(&cinfo);
229 return FALSE; 230 return TRUE; // done
230 } 231 }
231 try 232 try
232 { 233 {
@@ -320,7 +321,7 @@ BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)
320 catch (int) 321 catch (int)
321 { 322 {
322 jpeg_destroy_decompress(&cinfo); 323 jpeg_destroy_decompress(&cinfo);
323 return FALSE; 324 return TRUE; // done
324 } 325 }
325 326
326 // Check to see whether any corrupt-data warnings occurred 327 // Check to see whether any corrupt-data warnings occurred
@@ -328,7 +329,7 @@ BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)
328 { 329 {
329 // TODO: extract the warning to find out what went wrong. 330 // TODO: extract the warning to find out what went wrong.
330 setLastError( "Unable to decode JPEG image."); 331 setLastError( "Unable to decode JPEG image.");
331 return FALSE; 332 return TRUE; // done
332 } 333 }
333 334
334 return TRUE; 335 return TRUE;
diff --git a/linden/indra/llimage/llimageworker.cpp b/linden/indra/llimage/llimageworker.cpp
index 532e996..86d4151 100644
--- a/linden/indra/llimage/llimageworker.cpp
+++ b/linden/indra/llimage/llimageworker.cpp
@@ -37,152 +37,138 @@
37 37
38//---------------------------------------------------------------------------- 38//----------------------------------------------------------------------------
39 39
40//static 40// MAIN THREAD
41LLWorkerThread* LLImageWorker::sWorkerThread = NULL; 41LLImageDecodeThread::LLImageDecodeThread(bool threaded)
42S32 LLImageWorker::sCount = 0; 42 : LLQueuedThread("imagedecode", threaded)
43{
44 mCreationMutex = new LLMutex(getAPRPool());
45}
43 46
44//static 47// MAIN THREAD
45void LLImageWorker::initImageWorker(LLWorkerThread* workerthread) 48// virtual
49S32 LLImageDecodeThread::update(U32 max_time_ms)
46{ 50{
47 sWorkerThread = workerthread; 51 LLMutexLock lock(mCreationMutex);
52 for (creation_list_t::iterator iter = mCreationList.begin();
53 iter != mCreationList.end(); ++iter)
54 {
55 creation_info& info = *iter;
56 ImageRequest* req = new ImageRequest(info.handle, info.image,
57 info.priority, info.discard, info.needs_aux,
58 info.responder);
59 addRequest(req);
60 }
61 mCreationList.clear();
62 S32 res = LLQueuedThread::update(max_time_ms);
63 return res;
48} 64}
49 65
50//static 66LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image,
51void LLImageWorker::cleanupImageWorker() 67 U32 priority, S32 discard, BOOL needs_aux, Responder* responder)
68{
69 LLMutexLock lock(mCreationMutex);
70 handle_t handle = generateHandle();
71 mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder));
72 return handle;
73}
74
75// Used by unit test only
76// Returns the size of the mutex guarded list as an indication of sanity
77S32 LLImageDecodeThread::tut_size()
78{
79 LLMutexLock lock(mCreationMutex);
80 S32 res = mCreationList.size();
81 return res;
82}
83
84LLImageDecodeThread::Responder::~Responder()
52{ 85{
53} 86}
54 87
55//---------------------------------------------------------------------------- 88//----------------------------------------------------------------------------
56 89
57LLImageWorker::LLImageWorker(LLImageFormatted* image, U32 priority, 90LLImageDecodeThread::ImageRequest::ImageRequest(handle_t handle, LLImageFormatted* image,
58 S32 discard, 91 U32 priority, S32 discard, BOOL needs_aux,
59 LLPointer<LLResponder> responder) 92 LLImageDecodeThread::Responder* responder)
60 : LLWorkerClass(sWorkerThread, "Image"), 93 : LLQueuedThread::QueuedRequest(handle, priority, FLAG_AUTO_COMPLETE),
61 mFormattedImage(image), 94 mFormattedImage(image),
62 mDecodedType(-1),
63 mDiscardLevel(discard), 95 mDiscardLevel(discard),
64 mPriority(priority), 96 mNeedsAux(needs_aux),
97 mDecodedRaw(FALSE),
98 mDecodedAux(FALSE),
65 mResponder(responder) 99 mResponder(responder)
66{ 100{
67 ++sCount;
68} 101}
69 102
70LLImageWorker::~LLImageWorker() 103LLImageDecodeThread::ImageRequest::~ImageRequest()
71{ 104{
72 mDecodedImage = NULL; 105 mDecodedImageRaw = NULL;
106 mDecodedImageAux = NULL;
73 mFormattedImage = NULL; 107 mFormattedImage = NULL;
74 --sCount;
75} 108}
76 109
77//---------------------------------------------------------------------------- 110//----------------------------------------------------------------------------
78 111
79//virtual, main thread
80void LLImageWorker::startWork(S32 param)
81{
82 llassert_always(mDecodedImage.isNull());
83 mDecodedType = -1;
84}
85 112
86bool LLImageWorker::doWork(S32 param) 113// Returns true when done, whether or not decode was successful.
114bool LLImageDecodeThread::ImageRequest::processRequest()
87{ 115{
88 bool decoded = false; 116 const F32 decode_time_slice = .1f;
89 if(mDecodedImage.isNull()) 117 bool done = true;
118 if (!mDecodedRaw && mFormattedImage.notNull())
90 { 119 {
91 if (!mFormattedImage->updateData()) 120 // Decode primary channels
92 { 121 if (mDecodedImageRaw.isNull())
93 mDecodedType = -2; // failed
94 return true;
95 }
96 if (mDiscardLevel >= 0)
97 { 122 {
98 mFormattedImage->setDiscardLevel(mDiscardLevel); 123 // parse formatted header
99 } 124 if (!mFormattedImage->updateData())
100 if (!(mFormattedImage->getWidth() * mFormattedImage->getHeight() * mFormattedImage->getComponents())) 125 {
101 { 126 return true; // done (failed)
102 decoded = true; // failed 127 }
103 } 128 if (!(mFormattedImage->getWidth() * mFormattedImage->getHeight() * mFormattedImage->getComponents()))
104 else 129 {
105 { 130 return true; // done (failed)
106 mDecodedImage = new LLImageRaw(); // allow possibly smaller size set during decoding 131 }
132 if (mDiscardLevel >= 0)
133 {
134 mFormattedImage->setDiscardLevel(mDiscardLevel);
135 }
136 mDecodedImageRaw = new LLImageRaw(mFormattedImage->getWidth(),
137 mFormattedImage->getHeight(),
138 mFormattedImage->getComponents());
107 } 139 }
140 done = mFormattedImage->decode(mDecodedImageRaw, decode_time_slice); // 1ms
141 mDecodedRaw = done;
108 } 142 }
109 if (!decoded) 143 if (done && mNeedsAux && !mDecodedAux && mFormattedImage.notNull())
110 { 144 {
111 if (param == 0) 145 // Decode aux channel
112 { 146 if (!mDecodedImageAux)
113 // Decode primary channels
114 decoded = mFormattedImage->decode(mDecodedImage, .1f); // 1ms
115 }
116 else
117 { 147 {
118 // Decode aux channel 148 mDecodedImageAux = new LLImageRaw(mFormattedImage->getWidth(),
119 decoded = mFormattedImage->decodeChannels(mDecodedImage, .1f, param, param); // 1ms 149 mFormattedImage->getHeight(),
150 1);
120 } 151 }
152 done = mFormattedImage->decodeChannels(mDecodedImageAux, decode_time_slice, 4, 4); // 1ms
153 mDecodedAux = done;
121 } 154 }
122 if (decoded)
123 {
124 // Call the callback immediately; endWork doesn't get called until ckeckWork
125 if (mResponder.notNull())
126 {
127 bool success = (!wasAborted() && mDecodedImage.notNull() && mDecodedImage->getDataSize() != 0);
128 mResponder->completed(success);
129 }
130 }
131 return decoded;
132}
133 155
134void LLImageWorker::endWork(S32 param, bool aborted) 156 return done;
135{
136 if (mDecodedType != -2)
137 {
138 mDecodedType = aborted ? -2 : param;
139 }
140} 157}
141 158
142//---------------------------------------------------------------------------- 159void LLImageDecodeThread::ImageRequest::finishRequest(bool completed)
143
144
145BOOL LLImageWorker::requestDecodedAuxData(LLPointer<LLImageRaw>& raw, S32 channel, S32 discard)
146{ 160{
147 // For most codecs, only mDiscardLevel data is available. 161 if (mResponder.notNull())
148 // (see LLImageDXT for exception)
149 if (discard >= 0 && discard != mFormattedImage->getDiscardLevel())
150 {
151 llerrs << "Request for invalid discard level" << llendl;
152 }
153 checkWork();
154 if (mDecodedType == -2)
155 { 162 {
156 return TRUE; // aborted, done 163 bool success = completed && mDecodedRaw && (!mNeedsAux || mDecodedAux);
157 } 164 mResponder->completed(success, mDecodedImageRaw, mDecodedImageAux);
158 if (mDecodedType != channel)
159 {
160 if (!haveWork())
161 {
162 addWork(channel, mPriority);
163 }
164 return FALSE;
165 }
166 else
167 {
168 llassert_always(!haveWork());
169 llassert_always(mDecodedType == channel);
170 raw = mDecodedImage; // smart pointer acquires ownership of data
171 mDecodedImage = NULL;
172 return TRUE;
173 } 165 }
166 // Will automatically be deleted
174} 167}
175 168
176BOOL LLImageWorker::requestDecodedData(LLPointer<LLImageRaw>& raw, S32 discard) 169// Used by unit test only
170// Checks that a responder exists for this instance so that something can happen when completion is reached
171bool LLImageDecodeThread::ImageRequest::tut_isOK()
177{ 172{
178 if (mFormattedImage->getCodec() == IMG_CODEC_DXT) 173 return mResponder.notNull();
179 {
180 // special case
181 LLImageDXT* imagedxt = (LLImageDXT*)((LLImageFormatted*)mFormattedImage);
182 return imagedxt->getMipData(raw, discard);
183 }
184 else
185 {
186 return requestDecodedAuxData(raw, 0, discard);
187 }
188} 174}
diff --git a/linden/indra/llimage/llimageworker.h b/linden/indra/llimage/llimageworker.h
index 879fcf5..fcd3039 100644
--- a/linden/indra/llimage/llimageworker.h
+++ b/linden/indra/llimage/llimageworker.h
@@ -34,51 +34,74 @@
34#define LL_LLIMAGEWORKER_H 34#define LL_LLIMAGEWORKER_H
35 35
36#include "llimage.h" 36#include "llimage.h"
37#include "llworkerthread.h" 37#include "llqueuedthread.h"
38 38
39class LLImageWorker : public LLWorkerClass 39class LLImageDecodeThread : public LLQueuedThread
40{ 40{
41public: 41public:
42 static void initImageWorker(LLWorkerThread* workerthread); 42 class Responder : public LLThreadSafeRefCount
43 static void cleanupImageWorker(); 43 {
44 44 protected:
45public: 45 virtual ~Responder();
46 static LLWorkerThread* getWorkerThread() { return sWorkerThread; } 46 public:
47 47 virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux) = 0;
48 // LLWorkerThread 48 };
49public:
50 LLImageWorker(LLImageFormatted* image, U32 priority, S32 discard,
51 LLPointer<LLResponder> responder);
52 ~LLImageWorker();
53
54 // called from WORKER THREAD, returns TRUE if done
55 /*virtual*/ bool doWork(S32 param);
56
57 BOOL requestDecodedData(LLPointer<LLImageRaw>& raw, S32 discard = -1);
58 BOOL requestDecodedAuxData(LLPointer<LLImageRaw>& raw, S32 channel, S32 discard = -1);
59 void releaseDecodedData();
60 void cancelDecode();
61 49
62private: 50 class ImageRequest : public LLQueuedThread::QueuedRequest
63 // called from MAIN THREAD 51 {
64 /*virtual*/ void startWork(S32 param); // called from addWork() 52 protected:
65 /*virtual*/ void endWork(S32 param, bool aborted); // called from doWork() 53 virtual ~ImageRequest(); // use deleteRequest()
54
55 public:
56 ImageRequest(handle_t handle, LLImageFormatted* image,
57 U32 priority, S32 discard, BOOL needs_aux,
58 LLImageDecodeThread::Responder* responder);
66 59
67protected: 60 /*virtual*/ bool processRequest();
68 LLPointer<LLImageFormatted> mFormattedImage; 61 /*virtual*/ void finishRequest(bool completed);
69 LLPointer<LLImageRaw> mDecodedImage;
70 S32 mDecodedType;
71 S32 mDiscardLevel;
72 62
73private: 63 // Used by unit tests to check the consitency of the request instance
74 U32 mPriority; 64 bool tut_isOK();
75 LLPointer<LLResponder> mResponder; 65
66 private:
67 // input
68 LLPointer<LLImageFormatted> mFormattedImage;
69 S32 mDiscardLevel;
70 BOOL mNeedsAux;
71 // output
72 LLPointer<LLImageRaw> mDecodedImageRaw;
73 LLPointer<LLImageRaw> mDecodedImageAux;
74 BOOL mDecodedRaw;
75 BOOL mDecodedAux;
76 LLPointer<LLImageDecodeThread::Responder> mResponder;
77 };
76 78
77protected:
78 static LLWorkerThread* sWorkerThread;
79
80public: 79public:
81 static S32 sCount; 80 LLImageDecodeThread(bool threaded = true);
81 handle_t decodeImage(LLImageFormatted* image,
82 U32 priority, S32 discard, BOOL needs_aux,
83 Responder* responder);
84 S32 update(U32 max_time_ms);
85
86 // Used by unit tests to check the consistency of the thread instance
87 S32 tut_size();
88
89private:
90 struct creation_info
91 {
92 handle_t handle;
93 LLImageFormatted* image;
94 U32 priority;
95 S32 discard;
96 BOOL needs_aux;
97 LLPointer<Responder> responder;
98 creation_info(handle_t h, LLImageFormatted* i, U32 p, S32 d, BOOL aux, Responder* r)
99 : handle(h), image(i), priority(p), discard(d), needs_aux(aux), responder(r)
100 {}
101 };
102 typedef std::list<creation_info> creation_list_t;
103 creation_list_t mCreationList;
104 LLMutex* mCreationMutex;
82}; 105};
83 106
84#endif 107#endif