/indra/llimage/llimageworker.cpp

https://bitbucket.org/lindenlab/viewer-beta/ · C++ · 179 lines · 119 code · 19 blank · 41 comment · 18 complexity · 9175ab073e83e2c84c452168806902eb MD5 · raw file

  1. /**
  2. * @file llimageworker.cpp
  3. * @brief Base class for images.
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "linden_common.h"
  27. #include "llimageworker.h"
  28. #include "llimagedxt.h"
  29. //----------------------------------------------------------------------------
  30. // MAIN THREAD
  31. LLImageDecodeThread::LLImageDecodeThread(bool threaded)
  32. : LLQueuedThread("imagedecode", threaded)
  33. {
  34. mCreationMutex = new LLMutex(getAPRPool());
  35. }
  36. //virtual
  37. LLImageDecodeThread::~LLImageDecodeThread()
  38. {
  39. delete mCreationMutex ;
  40. }
  41. // MAIN THREAD
  42. // virtual
  43. S32 LLImageDecodeThread::update(F32 max_time_ms)
  44. {
  45. LLMutexLock lock(mCreationMutex);
  46. for (creation_list_t::iterator iter = mCreationList.begin();
  47. iter != mCreationList.end(); ++iter)
  48. {
  49. creation_info& info = *iter;
  50. ImageRequest* req = new ImageRequest(info.handle, info.image,
  51. info.priority, info.discard, info.needs_aux,
  52. info.responder);
  53. bool res = addRequest(req);
  54. if (!res)
  55. {
  56. llerrs << "request added after LLLFSThread::cleanupClass()" << llendl;
  57. }
  58. }
  59. mCreationList.clear();
  60. S32 res = LLQueuedThread::update(max_time_ms);
  61. return res;
  62. }
  63. LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image,
  64. U32 priority, S32 discard, BOOL needs_aux, Responder* responder)
  65. {
  66. LLMutexLock lock(mCreationMutex);
  67. handle_t handle = generateHandle();
  68. mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder));
  69. return handle;
  70. }
  71. // Used by unit test only
  72. // Returns the size of the mutex guarded list as an indication of sanity
  73. S32 LLImageDecodeThread::tut_size()
  74. {
  75. LLMutexLock lock(mCreationMutex);
  76. S32 res = mCreationList.size();
  77. return res;
  78. }
  79. LLImageDecodeThread::Responder::~Responder()
  80. {
  81. }
  82. //----------------------------------------------------------------------------
  83. LLImageDecodeThread::ImageRequest::ImageRequest(handle_t handle, LLImageFormatted* image,
  84. U32 priority, S32 discard, BOOL needs_aux,
  85. LLImageDecodeThread::Responder* responder)
  86. : LLQueuedThread::QueuedRequest(handle, priority, FLAG_AUTO_COMPLETE),
  87. mFormattedImage(image),
  88. mDiscardLevel(discard),
  89. mNeedsAux(needs_aux),
  90. mDecodedRaw(FALSE),
  91. mDecodedAux(FALSE),
  92. mResponder(responder)
  93. {
  94. }
  95. LLImageDecodeThread::ImageRequest::~ImageRequest()
  96. {
  97. mDecodedImageRaw = NULL;
  98. mDecodedImageAux = NULL;
  99. mFormattedImage = NULL;
  100. }
  101. //----------------------------------------------------------------------------
  102. // Returns true when done, whether or not decode was successful.
  103. bool LLImageDecodeThread::ImageRequest::processRequest()
  104. {
  105. const F32 decode_time_slice = .1f;
  106. bool done = true;
  107. if (!mDecodedRaw && mFormattedImage.notNull())
  108. {
  109. // Decode primary channels
  110. if (mDecodedImageRaw.isNull())
  111. {
  112. // parse formatted header
  113. if (!mFormattedImage->updateData())
  114. {
  115. return true; // done (failed)
  116. }
  117. if (!(mFormattedImage->getWidth() * mFormattedImage->getHeight() * mFormattedImage->getComponents()))
  118. {
  119. return true; // done (failed)
  120. }
  121. if (mDiscardLevel >= 0)
  122. {
  123. mFormattedImage->setDiscardLevel(mDiscardLevel);
  124. }
  125. mDecodedImageRaw = new LLImageRaw(mFormattedImage->getWidth(),
  126. mFormattedImage->getHeight(),
  127. mFormattedImage->getComponents());
  128. }
  129. done = mFormattedImage->decode(mDecodedImageRaw, decode_time_slice); // 1ms
  130. mDecodedRaw = done;
  131. }
  132. if (done && mNeedsAux && !mDecodedAux && mFormattedImage.notNull())
  133. {
  134. // Decode aux channel
  135. if (!mDecodedImageAux)
  136. {
  137. mDecodedImageAux = new LLImageRaw(mFormattedImage->getWidth(),
  138. mFormattedImage->getHeight(),
  139. 1);
  140. }
  141. done = mFormattedImage->decodeChannels(mDecodedImageAux, decode_time_slice, 4, 4); // 1ms
  142. mDecodedAux = done;
  143. }
  144. return done;
  145. }
  146. void LLImageDecodeThread::ImageRequest::finishRequest(bool completed)
  147. {
  148. if (mResponder.notNull())
  149. {
  150. bool success = completed && mDecodedRaw && (!mNeedsAux || mDecodedAux);
  151. mResponder->completed(success, mDecodedImageRaw, mDecodedImageAux);
  152. }
  153. // Will automatically be deleted
  154. }
  155. // Used by unit test only
  156. // Checks that a responder exists for this instance so that something can happen when completion is reached
  157. bool LLImageDecodeThread::ImageRequest::tut_isOK()
  158. {
  159. return mResponder.notNull();
  160. }