llimageworker.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 
00034 #include "llimageworker.h"
00035 #include "llimagedxt.h"
00036 
00037 //----------------------------------------------------------------------------
00038 
00039 //static
00040 LLWorkerThread* LLImageWorker::sWorkerThread = NULL;
00041 S32 LLImageWorker::sCount = 0;
00042 
00043 //static
00044 void LLImageWorker::initClass(LLWorkerThread* workerthread)
00045 {
00046         sWorkerThread = workerthread;
00047 }
00048 
00049 //static
00050 void LLImageWorker::cleanupClass()
00051 {
00052 }
00053 
00054 //----------------------------------------------------------------------------
00055 
00056 LLImageWorker::LLImageWorker(LLImageFormatted* image, U32 priority,
00057                                                          S32 discard,
00058                                                          LLPointer<LLResponder> responder)
00059         : LLWorkerClass(sWorkerThread, "Image"),
00060           mFormattedImage(image),
00061           mDecodedType(-1),
00062           mDiscardLevel(discard),
00063           mPriority(priority),
00064           mResponder(responder)
00065 {
00066         ++sCount;
00067 }
00068 
00069 LLImageWorker::~LLImageWorker()
00070 {
00071         mDecodedImage = NULL;
00072         mFormattedImage = NULL;
00073         --sCount;
00074 }
00075 
00076 //----------------------------------------------------------------------------
00077 
00078 //virtual, main thread
00079 void LLImageWorker::startWork(S32 param)
00080 {
00081         llassert_always(mDecodedImage.isNull());
00082         mDecodedType = -1;
00083 }
00084 
00085 bool LLImageWorker::doWork(S32 param)
00086 {
00087         bool decoded = false;
00088         if(mDecodedImage.isNull())
00089         {
00090                 if (!mFormattedImage->updateData())
00091                 {
00092                         mDecodedType = -2; // failed
00093                         return true;
00094                 }
00095                 if (mDiscardLevel >= 0)
00096                 {
00097                         mFormattedImage->setDiscardLevel(mDiscardLevel);
00098                 }
00099                 if (!(mFormattedImage->getWidth() * mFormattedImage->getHeight() * mFormattedImage->getComponents()))
00100                 {
00101                         decoded = true; // failed
00102                 }
00103                 else
00104                 {
00105                         mDecodedImage = new LLImageRaw(); // allow possibly smaller size set during decoding
00106                 }
00107         }
00108         if (!decoded)
00109         {
00110                 if (param == 0)
00111                 {
00112                         // Decode primary channels
00113                         decoded = mFormattedImage->decode(mDecodedImage, .1f); // 1ms
00114                 }
00115                 else
00116                 {
00117                         // Decode aux channel
00118                         decoded = mFormattedImage->decode(mDecodedImage, .1f, param, param); // 1ms
00119                 }
00120         }
00121         if (decoded)
00122         {
00123                 // Call the callback immediately; endWork doesn't get called until ckeckWork
00124                 if (mResponder.notNull())
00125                 {
00126                         bool success = (!wasAborted() && mDecodedImage.notNull() && mDecodedImage->getDataSize() != 0);
00127                         mResponder->completed(success);
00128                 }
00129         }
00130         return decoded;
00131 }
00132 
00133 void LLImageWorker::endWork(S32 param, bool aborted)
00134 {
00135         if (mDecodedType != -2)
00136         {
00137                 mDecodedType = aborted ? -2 : param;
00138         }
00139 }
00140 
00141 //----------------------------------------------------------------------------
00142 
00143 
00144 BOOL LLImageWorker::requestDecodedAuxData(LLPointer<LLImageRaw>& raw, S32 channel, S32 discard)
00145 {
00146         // For most codecs, only mDiscardLevel data is available.
00147         //  (see LLImageDXT for exception)
00148         if (discard >= 0 && discard != mFormattedImage->getDiscardLevel())
00149         {
00150                 llerrs << "Request for invalid discard level" << llendl;
00151         }
00152         checkWork();
00153         if (mDecodedType == -2)
00154         {
00155                 return TRUE; // aborted, done
00156         }
00157         if (mDecodedType != channel)
00158         {
00159                 if (!haveWork())
00160                 {
00161                         addWork(channel, mPriority);
00162                 }
00163                 return FALSE;
00164         }
00165         else
00166         {
00167                 llassert_always(!haveWork());
00168                 llassert_always(mDecodedType == channel);
00169                 raw = mDecodedImage; // smart pointer acquires ownership of data
00170                 mDecodedImage = NULL;
00171                 return TRUE;
00172         }
00173 }
00174 
00175 BOOL LLImageWorker::requestDecodedData(LLPointer<LLImageRaw>& raw, S32 discard)
00176 {
00177         if (mFormattedImage->getCodec() == IMG_CODEC_DXT)
00178         {
00179                 // special case
00180                 LLImageDXT* imagedxt = (LLImageDXT*)((LLImageFormatted*)mFormattedImage);
00181                 return imagedxt->getMipData(raw, discard);
00182         }
00183         else
00184         {
00185                 return requestDecodedAuxData(raw, 0, discard);
00186         }
00187 }

Generated on Thu Jul 1 06:08:44 2010 for Second Life Viewer by  doxygen 1.4.7