llimageworker.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:5k
- /**
- * @file llimageworker.cpp
- * @brief Base class for images.
- *
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2010, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #include "linden_common.h"
- #include "llimageworker.h"
- #include "llimagedxt.h"
- //----------------------------------------------------------------------------
- // MAIN THREAD
- LLImageDecodeThread::LLImageDecodeThread(bool threaded)
- : LLQueuedThread("imagedecode", threaded)
- {
- mCreationMutex = new LLMutex(getAPRPool());
- }
- // MAIN THREAD
- // virtual
- S32 LLImageDecodeThread::update(U32 max_time_ms)
- {
- LLMutexLock lock(mCreationMutex);
- for (creation_list_t::iterator iter = mCreationList.begin();
- iter != mCreationList.end(); ++iter)
- {
- creation_info& info = *iter;
- ImageRequest* req = new ImageRequest(info.handle, info.image,
- info.priority, info.discard, info.needs_aux,
- info.responder);
- bool res = addRequest(req);
- if (!res)
- {
- llerrs << "request added after LLLFSThread::cleanupClass()" << llendl;
- }
- }
- mCreationList.clear();
- S32 res = LLQueuedThread::update(max_time_ms);
- return res;
- }
- LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image,
- U32 priority, S32 discard, BOOL needs_aux, Responder* responder)
- {
- LLMutexLock lock(mCreationMutex);
- handle_t handle = generateHandle();
- mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder));
- return handle;
- }
- // Used by unit test only
- // Returns the size of the mutex guarded list as an indication of sanity
- S32 LLImageDecodeThread::tut_size()
- {
- LLMutexLock lock(mCreationMutex);
- S32 res = mCreationList.size();
- return res;
- }
- LLImageDecodeThread::Responder::~Responder()
- {
- }
- //----------------------------------------------------------------------------
- LLImageDecodeThread::ImageRequest::ImageRequest(handle_t handle, LLImageFormatted* image,
- U32 priority, S32 discard, BOOL needs_aux,
- LLImageDecodeThread::Responder* responder)
- : LLQueuedThread::QueuedRequest(handle, priority, FLAG_AUTO_COMPLETE),
- mFormattedImage(image),
- mDiscardLevel(discard),
- mNeedsAux(needs_aux),
- mDecodedRaw(FALSE),
- mDecodedAux(FALSE),
- mResponder(responder)
- {
- }
- LLImageDecodeThread::ImageRequest::~ImageRequest()
- {
- mDecodedImageRaw = NULL;
- mDecodedImageAux = NULL;
- mFormattedImage = NULL;
- }
- //----------------------------------------------------------------------------
- // Returns true when done, whether or not decode was successful.
- bool LLImageDecodeThread::ImageRequest::processRequest()
- {
- const F32 decode_time_slice = .1f;
- bool done = true;
- if (!mDecodedRaw && mFormattedImage.notNull())
- {
- // Decode primary channels
- if (mDecodedImageRaw.isNull())
- {
- // parse formatted header
- if (!mFormattedImage->updateData())
- {
- return true; // done (failed)
- }
- if (!(mFormattedImage->getWidth() * mFormattedImage->getHeight() * mFormattedImage->getComponents()))
- {
- return true; // done (failed)
- }
- if (mDiscardLevel >= 0)
- {
- mFormattedImage->setDiscardLevel(mDiscardLevel);
- }
- mDecodedImageRaw = new LLImageRaw(mFormattedImage->getWidth(),
- mFormattedImage->getHeight(),
- mFormattedImage->getComponents());
- }
- done = mFormattedImage->decode(mDecodedImageRaw, decode_time_slice); // 1ms
- mDecodedRaw = done;
- }
- if (done && mNeedsAux && !mDecodedAux && mFormattedImage.notNull())
- {
- // Decode aux channel
- if (!mDecodedImageAux)
- {
- mDecodedImageAux = new LLImageRaw(mFormattedImage->getWidth(),
- mFormattedImage->getHeight(),
- 1);
- }
- done = mFormattedImage->decodeChannels(mDecodedImageAux, decode_time_slice, 4, 4); // 1ms
- mDecodedAux = done;
- }
- return done;
- }
- void LLImageDecodeThread::ImageRequest::finishRequest(bool completed)
- {
- if (mResponder.notNull())
- {
- bool success = completed && mDecodedRaw && (!mNeedsAux || mDecodedAux);
- mResponder->completed(success, mDecodedImageRaw, mDecodedImageAux);
- }
- // Will automatically be deleted
- }
- // Used by unit test only
- // Checks that a responder exists for this instance so that something can happen when completion is reached
- bool LLImageDecodeThread::ImageRequest::tut_isOK()
- {
- return mResponder.notNull();
- }