PageRenderTime 364ms CodeModel.GetById 181ms app.highlight 15ms RepoModel.GetById 166ms app.codeStats 0ms

/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
 27#include "linden_common.h"
 28
 29#include "llimageworker.h"
 30#include "llimagedxt.h"
 31
 32//----------------------------------------------------------------------------
 33
 34// MAIN THREAD
 35LLImageDecodeThread::LLImageDecodeThread(bool threaded)
 36	: LLQueuedThread("imagedecode", threaded)
 37{
 38	mCreationMutex = new LLMutex(getAPRPool());
 39}
 40
 41//virtual 
 42LLImageDecodeThread::~LLImageDecodeThread()
 43{
 44	delete mCreationMutex ;
 45}
 46
 47// MAIN THREAD
 48// virtual
 49S32 LLImageDecodeThread::update(F32 max_time_ms)
 50{
 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
 60		bool res = addRequest(req);
 61		if (!res)
 62		{
 63			llerrs << "request added after LLLFSThread::cleanupClass()" << llendl;
 64		}
 65	}
 66	mCreationList.clear();
 67	S32 res = LLQueuedThread::update(max_time_ms);
 68	return res;
 69}
 70
 71LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image, 
 72	U32 priority, S32 discard, BOOL needs_aux, Responder* responder)
 73{
 74	LLMutexLock lock(mCreationMutex);
 75	handle_t handle = generateHandle();
 76	mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder));
 77	return handle;
 78}
 79
 80// Used by unit test only
 81// Returns the size of the mutex guarded list as an indication of sanity
 82S32 LLImageDecodeThread::tut_size()
 83{
 84	LLMutexLock lock(mCreationMutex);
 85	S32 res = mCreationList.size();
 86	return res;
 87}
 88
 89LLImageDecodeThread::Responder::~Responder()
 90{
 91}
 92
 93//----------------------------------------------------------------------------
 94
 95LLImageDecodeThread::ImageRequest::ImageRequest(handle_t handle, LLImageFormatted* image, 
 96												U32 priority, S32 discard, BOOL needs_aux,
 97												LLImageDecodeThread::Responder* responder)
 98	: LLQueuedThread::QueuedRequest(handle, priority, FLAG_AUTO_COMPLETE),
 99	  mFormattedImage(image),
100	  mDiscardLevel(discard),
101	  mNeedsAux(needs_aux),
102	  mDecodedRaw(FALSE),
103	  mDecodedAux(FALSE),
104	  mResponder(responder)
105{
106}
107
108LLImageDecodeThread::ImageRequest::~ImageRequest()
109{
110	mDecodedImageRaw = NULL;
111	mDecodedImageAux = NULL;
112	mFormattedImage = NULL;
113}
114
115//----------------------------------------------------------------------------
116
117
118// Returns true when done, whether or not decode was successful.
119bool LLImageDecodeThread::ImageRequest::processRequest()
120{
121	const F32 decode_time_slice = .1f;
122	bool done = true;
123	if (!mDecodedRaw && mFormattedImage.notNull())
124	{
125		// Decode primary channels
126		if (mDecodedImageRaw.isNull())
127		{
128			// parse formatted header
129			if (!mFormattedImage->updateData())
130			{
131				return true; // done (failed)
132			}
133			if (!(mFormattedImage->getWidth() * mFormattedImage->getHeight() * mFormattedImage->getComponents()))
134			{
135				return true; // done (failed)
136			}
137			if (mDiscardLevel >= 0)
138			{
139				mFormattedImage->setDiscardLevel(mDiscardLevel);
140			}
141			mDecodedImageRaw = new LLImageRaw(mFormattedImage->getWidth(),
142											  mFormattedImage->getHeight(),
143											  mFormattedImage->getComponents());
144		}
145		done = mFormattedImage->decode(mDecodedImageRaw, decode_time_slice); // 1ms
146		mDecodedRaw = done;
147	}
148	if (done && mNeedsAux && !mDecodedAux && mFormattedImage.notNull())
149	{
150		// Decode aux channel
151		if (!mDecodedImageAux)
152		{
153			mDecodedImageAux = new LLImageRaw(mFormattedImage->getWidth(),
154											  mFormattedImage->getHeight(),
155											  1);
156		}
157		done = mFormattedImage->decodeChannels(mDecodedImageAux, decode_time_slice, 4, 4); // 1ms
158		mDecodedAux = done;
159	}
160
161	return done;
162}
163
164void LLImageDecodeThread::ImageRequest::finishRequest(bool completed)
165{
166	if (mResponder.notNull())
167	{
168		bool success = completed && mDecodedRaw && (!mNeedsAux || mDecodedAux);
169		mResponder->completed(success, mDecodedImageRaw, mDecodedImageAux);
170	}
171	// Will automatically be deleted
172}
173
174// Used by unit test only
175// Checks that a responder exists for this instance so that something can happen when completion is reached
176bool LLImageDecodeThread::ImageRequest::tut_isOK()
177{
178	return mResponder.notNull();
179}