llimageworker.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:5k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llimageworker.cpp
  3.  * @brief Base class for images.
  4.  *
  5.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2001-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "linden_common.h"
  33. #include "llimageworker.h"
  34. #include "llimagedxt.h"
  35. //----------------------------------------------------------------------------
  36. // MAIN THREAD
  37. LLImageDecodeThread::LLImageDecodeThread(bool threaded)
  38. : LLQueuedThread("imagedecode", threaded)
  39. {
  40. mCreationMutex = new LLMutex(getAPRPool());
  41. }
  42. // MAIN THREAD
  43. // virtual
  44. S32 LLImageDecodeThread::update(U32 max_time_ms)
  45. {
  46. LLMutexLock lock(mCreationMutex);
  47. for (creation_list_t::iterator iter = mCreationList.begin();
  48.  iter != mCreationList.end(); ++iter)
  49. {
  50. creation_info& info = *iter;
  51. ImageRequest* req = new ImageRequest(info.handle, info.image,
  52.      info.priority, info.discard, info.needs_aux,
  53.      info.responder);
  54. bool res = addRequest(req);
  55. if (!res)
  56. {
  57. llerrs << "request added after LLLFSThread::cleanupClass()" << llendl;
  58. }
  59. }
  60. mCreationList.clear();
  61. S32 res = LLQueuedThread::update(max_time_ms);
  62. return res;
  63. }
  64. LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image, 
  65. U32 priority, S32 discard, BOOL needs_aux, Responder* responder)
  66. {
  67. LLMutexLock lock(mCreationMutex);
  68. handle_t handle = generateHandle();
  69. mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder));
  70. return handle;
  71. }
  72. // Used by unit test only
  73. // Returns the size of the mutex guarded list as an indication of sanity
  74. S32 LLImageDecodeThread::tut_size()
  75. {
  76. LLMutexLock lock(mCreationMutex);
  77. S32 res = mCreationList.size();
  78. return res;
  79. }
  80. LLImageDecodeThread::Responder::~Responder()
  81. {
  82. }
  83. //----------------------------------------------------------------------------
  84. LLImageDecodeThread::ImageRequest::ImageRequest(handle_t handle, LLImageFormatted* image, 
  85. U32 priority, S32 discard, BOOL needs_aux,
  86. LLImageDecodeThread::Responder* responder)
  87. : LLQueuedThread::QueuedRequest(handle, priority, FLAG_AUTO_COMPLETE),
  88.   mFormattedImage(image),
  89.   mDiscardLevel(discard),
  90.   mNeedsAux(needs_aux),
  91.   mDecodedRaw(FALSE),
  92.   mDecodedAux(FALSE),
  93.   mResponder(responder)
  94. {
  95. }
  96. LLImageDecodeThread::ImageRequest::~ImageRequest()
  97. {
  98. mDecodedImageRaw = NULL;
  99. mDecodedImageAux = NULL;
  100. mFormattedImage = NULL;
  101. }
  102. //----------------------------------------------------------------------------
  103. // Returns true when done, whether or not decode was successful.
  104. bool LLImageDecodeThread::ImageRequest::processRequest()
  105. {
  106. const F32 decode_time_slice = .1f;
  107. bool done = true;
  108. if (!mDecodedRaw && mFormattedImage.notNull())
  109. {
  110. // Decode primary channels
  111. if (mDecodedImageRaw.isNull())
  112. {
  113. // parse formatted header
  114. if (!mFormattedImage->updateData())
  115. {
  116. return true; // done (failed)
  117. }
  118. if (!(mFormattedImage->getWidth() * mFormattedImage->getHeight() * mFormattedImage->getComponents()))
  119. {
  120. return true; // done (failed)
  121. }
  122. if (mDiscardLevel >= 0)
  123. {
  124. mFormattedImage->setDiscardLevel(mDiscardLevel);
  125. }
  126. mDecodedImageRaw = new LLImageRaw(mFormattedImage->getWidth(),
  127.   mFormattedImage->getHeight(),
  128.   mFormattedImage->getComponents());
  129. }
  130. done = mFormattedImage->decode(mDecodedImageRaw, decode_time_slice); // 1ms
  131. mDecodedRaw = done;
  132. }
  133. if (done && mNeedsAux && !mDecodedAux && mFormattedImage.notNull())
  134. {
  135. // Decode aux channel
  136. if (!mDecodedImageAux)
  137. {
  138. mDecodedImageAux = new LLImageRaw(mFormattedImage->getWidth(),
  139.   mFormattedImage->getHeight(),
  140.   1);
  141. }
  142. done = mFormattedImage->decodeChannels(mDecodedImageAux, decode_time_slice, 4, 4); // 1ms
  143. mDecodedAux = done;
  144. }
  145. return done;
  146. }
  147. void LLImageDecodeThread::ImageRequest::finishRequest(bool completed)
  148. {
  149. if (mResponder.notNull())
  150. {
  151. bool success = completed && mDecodedRaw && (!mNeedsAux || mDecodedAux);
  152. mResponder->completed(success, mDecodedImageRaw, mDecodedImageAux);
  153. }
  154. // Will automatically be deleted
  155. }
  156. // Used by unit test only
  157. // Checks that a responder exists for this instance so that something can happen when completion is reached
  158. bool LLImageDecodeThread::ImageRequest::tut_isOK()
  159. {
  160. return mResponder.notNull();
  161. }