diff options
| author | Josh Bell <josh@lindenlab.com> | 2007-03-09 01:09:20 +0000 | 
|---|---|---|
| committer | Josh Bell <josh@lindenlab.com> | 2007-03-09 01:09:20 +0000 | 
| commit | b36dc363061ec5bf6b092c14193198e9a5eef816 (patch) | |
| tree | b067586bd545dfa6dce9dd0b1243b9c0aa143f33 | |
| parent | 6fa974fc64b172a7324b28d40f08f2a861d87f8d (diff) | |
svn merge -r 58902:58986 svn+ssh://svn.lindenlab.com/svn/linden/branches/maintenance --> release
55 files changed, 2754 insertions, 2654 deletions
| diff --git a/indra/llcommon/llavatarconstants.h b/indra/llcommon/llavatarconstants.h index 67bd329732..d66627c4b0 100644 --- a/indra/llcommon/llavatarconstants.h +++ b/indra/llcommon/llavatarconstants.h @@ -20,16 +20,16 @@ const char* const BLACKLIST_PROFILE_WEB_URL = "http://secondlife.com/app/webdisa  // Maximum number of avatar picks  const S32 MAX_AVATAR_PICKS = 10; -// For Flags in AvatarPropertiesReply
 -const U32 AVATAR_ALLOW_PUBLISH			= 0x1 << 0;	// whether profile is externally visible or not
 -const U32 AVATAR_MATURE_PUBLISH			= 0x1 << 1;	// profile is "mature"
 -const U32 AVATAR_IDENTIFIED				= 0x1 << 2;	// whether avatar has provided payment info
 +// For Flags in AvatarPropertiesReply +const U32 AVATAR_ALLOW_PUBLISH			= 0x1 << 0;	// whether profile is externally visible or not +const U32 AVATAR_MATURE_PUBLISH			= 0x1 << 1;	// profile is "mature" +const U32 AVATAR_IDENTIFIED				= 0x1 << 2;	// whether avatar has provided payment info  const U32 AVATAR_TRANSACTED				= 0x1 << 3;	// whether avatar has actively used payment info  const U32 AVATAR_ONLINE					= 0x1 << 4; // the online status of this avatar, if known. -static const std::string VISIBILITY_DEFAULT("default");
 +static const std::string VISIBILITY_DEFAULT("default");  static const std::string VISIBILITY_HIDDEN("hidden"); -static const std::string VISIBILITY_VISIBLE("visible");
 +static const std::string VISIBILITY_VISIBLE("visible");  static const std::string VISIBILITY_INVISIBLE("invisible");  #endif diff --git a/indra/llcommon/llbase64.cpp b/indra/llcommon/llbase64.cpp index 88e9d960a2..6c4bc59e68 100644 --- a/indra/llcommon/llbase64.cpp +++ b/indra/llcommon/llbase64.cpp @@ -1,43 +1,43 @@ -/** 
 - * @file llbase64.cpp
 - * @brief Wrapper for apr base64 encoding that returns a std::string
 - * @author James Cook
 - *
 - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
 - * $License$
 - */
 -
 -#include "linden_common.h"
 -
 -#include "llbase64.h"
 -
 -#include <string>
 -
 -#include "apr-1/apr_base64.h"
 -
 -
 -// static
 -std::string LLBase64::encode(const U8* input, size_t input_size)
 -{
 -	std::string output;
 -	if (input
 -		&& input_size > 0)
 -	{
 -		// Yes, it returns int.
 -		int b64_buffer_length = apr_base64_encode_len(input_size);
 -		char* b64_buffer = new char[b64_buffer_length];
 -		
 -		// This is faster than apr_base64_encode() if you know
 -		// you're not on an EBCDIC machine.  Also, the output is
 -		// null terminated, even though the documentation doesn't
 -		// specify.  See apr_base64.c for details. JC
 -		b64_buffer_length = apr_base64_encode_binary(
 -			b64_buffer,
 -			input,
 -			input_size);
 -		output.assign(b64_buffer);
 -		delete[] b64_buffer;
 -	}
 -	return output;
 -}
 -
 +/**  + * @file llbase64.cpp + * @brief Wrapper for apr base64 encoding that returns a std::string + * @author James Cook + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "linden_common.h" + +#include "llbase64.h" + +#include <string> + +#include "apr-1/apr_base64.h" + + +// static +std::string LLBase64::encode(const U8* input, size_t input_size) +{ +	std::string output; +	if (input +		&& input_size > 0) +	{ +		// Yes, it returns int. +		int b64_buffer_length = apr_base64_encode_len(input_size); +		char* b64_buffer = new char[b64_buffer_length]; +		 +		// This is faster than apr_base64_encode() if you know +		// you're not on an EBCDIC machine.  Also, the output is +		// null terminated, even though the documentation doesn't +		// specify.  See apr_base64.c for details. JC +		b64_buffer_length = apr_base64_encode_binary( +			b64_buffer, +			input, +			input_size); +		output.assign(b64_buffer); +		delete[] b64_buffer; +	} +	return output; +} + diff --git a/indra/llcommon/llbase64.h b/indra/llcommon/llbase64.h index 6e8b817ba7..4f59ceded6 100644 --- a/indra/llcommon/llbase64.h +++ b/indra/llcommon/llbase64.h @@ -1,19 +1,19 @@ -/** 
 - * @file llbase64.h
 - * @brief Wrapper for apr base64 encoding that returns a std::string
 - * @author James Cook
 - *
 - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
 - * $License$
 - */
 -
 -#ifndef LLBASE64_H
 -#define LLBASE64_h
 -
 -class LLBase64
 -{
 -public:
 -	static std::string encode(const U8* input, size_t input_size);
 -};
 -
 -#endif
 +/**  + * @file llbase64.h + * @brief Wrapper for apr base64 encoding that returns a std::string + * @author James Cook + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#ifndef LLBASE64_H +#define LLBASE64_h + +class LLBase64 +{ +public: +	static std::string encode(const U8* input, size_t input_size); +}; + +#endif diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index 16af098ed5..3e88784d3c 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -25,6 +25,7 @@ public:  		FTM_UPDATE,  		FTM_RENDER,  		FTM_SWAP, +		FTM_CLIENT_COPY,  		FTM_IDLE,  		FTM_SLEEP, diff --git a/indra/llcommon/llliveappconfig.cpp b/indra/llcommon/llliveappconfig.cpp index 8bcaeb898f..b446c1f18e 100644 --- a/indra/llcommon/llliveappconfig.cpp +++ b/indra/llcommon/llliveappconfig.cpp @@ -1,46 +1,46 @@ -/** 
 - * @file llliveappconfig.cpp
 - * @brief Configuration information for an LLApp that overrides indra.xml
 - *
 - * Copyright (c) 2003-$CurrentYear$, Linden Research, Inc.
 - * $License$
 - */
 -
 -#include "linden_common.h"
 -
 -#include "llliveappconfig.h"
 -
 -#include "llapp.h"
 -#include "llsd.h"
 -#include "llsdserialize.h"
 -
 -LLLiveAppConfig::LLLiveAppConfig(LLApp* app, const std::string& filename, F32 refresh_period)
 -:	LLLiveFile(filename, refresh_period),
 -	mApp(app)
 -{ }
 -
 -
 -LLLiveAppConfig::~LLLiveAppConfig()
 -{ }
 -
 -// virtual 
 -void LLLiveAppConfig::loadFile()
 -{
 -	llinfos << "LLLiveAppConfig::loadFile(): reading from "
 -		<< filename() << llendl;
 -    llifstream file(filename().c_str());
 -	LLSD config;
 -    if (file.is_open())
 -    {
 -        LLSDSerialize::fromXML(config, file);
 -		if(!config.isMap())
 -		{
 -			llinfos << "LLDataserverConfig::loadFile(): not an map!"
 -				<< " Ignoring the data." << llendl;
 -			return;
 -		}
 -		file.close();
 -    }
 -	mApp->setOptionData(
 -		LLApp::PRIORITY_SPECIFIC_CONFIGURATION, config);
 -}
 +/**  + * @file llliveappconfig.cpp + * @brief Configuration information for an LLApp that overrides indra.xml + * + * Copyright (c) 2003-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "linden_common.h" + +#include "llliveappconfig.h" + +#include "llapp.h" +#include "llsd.h" +#include "llsdserialize.h" + +LLLiveAppConfig::LLLiveAppConfig(LLApp* app, const std::string& filename, F32 refresh_period) +:	LLLiveFile(filename, refresh_period), +	mApp(app) +{ } + + +LLLiveAppConfig::~LLLiveAppConfig() +{ } + +// virtual  +void LLLiveAppConfig::loadFile() +{ +	llinfos << "LLLiveAppConfig::loadFile(): reading from " +		<< filename() << llendl; +    llifstream file(filename().c_str()); +	LLSD config; +    if (file.is_open()) +    { +        LLSDSerialize::fromXML(config, file); +		if(!config.isMap()) +		{ +			llinfos << "LLDataserverConfig::loadFile(): not an map!" +				<< " Ignoring the data." << llendl; +			return; +		} +		file.close(); +    } +	mApp->setOptionData( +		LLApp::PRIORITY_SPECIFIC_CONFIGURATION, config); +} diff --git a/indra/llcommon/llliveappconfig.h b/indra/llcommon/llliveappconfig.h index ceceda5b18..8875f3adc3 100644 --- a/indra/llcommon/llliveappconfig.h +++ b/indra/llcommon/llliveappconfig.h @@ -1,33 +1,33 @@ -/** 
 - * @file llliveappconfig.h
 - * @brief Configuration information for an LLApp that overrides indra.xml
 - *
 - * Copyright (c) 2003-$CurrentYear$, Linden Research, Inc.
 - * $License$
 - */
 -
 -#ifndef LLLIVEAPPCONFIG_H
 -#define LLLIVEAPPCONFIG_H
 -
 -#include "lllivefile.h"
 -
 -class LLApp;
 -
 -class LLLiveAppConfig : public LLLiveFile
 -{
 -public:
 -	// To use this, instantiate a LLLiveAppConfig object inside your main loop.
 -	// The traditional name for it is live_config.
 -	// Be sure to call live_config.checkAndReload() periodically.
 -
 -	LLLiveAppConfig(LLApp* app, const std::string& filename, F32 refresh_period);
 -	~LLLiveAppConfig();
 -
 -protected:
 -	/*virtual*/ void loadFile();
 -
 -private:
 -	LLApp* mApp;
 -};
 -
 -#endif
 +/**  + * @file llliveappconfig.h + * @brief Configuration information for an LLApp that overrides indra.xml + * + * Copyright (c) 2003-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#ifndef LLLIVEAPPCONFIG_H +#define LLLIVEAPPCONFIG_H + +#include "lllivefile.h" + +class LLApp; + +class LLLiveAppConfig : public LLLiveFile +{ +public: +	// To use this, instantiate a LLLiveAppConfig object inside your main loop. +	// The traditional name for it is live_config. +	// Be sure to call live_config.checkAndReload() periodically. + +	LLLiveAppConfig(LLApp* app, const std::string& filename, F32 refresh_period); +	~LLLiveAppConfig(); + +protected: +	/*virtual*/ void loadFile(); + +private: +	LLApp* mApp; +}; + +#endif diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp index cf06fe3f40..1f64c3bde3 100644 --- a/indra/llcommon/lluri.cpp +++ b/indra/llcommon/lluri.cpp @@ -359,8 +359,7 @@ LLURI LLURI::buildHTTP(const std::string& host_port,  	LLURI result;  	// TODO: deal with '/' '?' '#' in host_port -	S32 index = host_port.find("://"); -	if (index != host_port.npos) +	if (host_port.find("://") != host_port.npos)  	{  		// The scheme is part of the host_port  		result.mScheme = ""; diff --git a/indra/llcommon/metaproperty.cpp b/indra/llcommon/metaproperty.cpp index befee61a8a..adcda03389 100644 --- a/indra/llcommon/metaproperty.cpp +++ b/indra/llcommon/metaproperty.cpp @@ -25,7 +25,7 @@ const LLMetaClass& LLMetaProperty::getObjectMetaClass() const  {  	return mObjectClass;  } -
 +  void LLMetaProperty::checkObjectClass(const LLReflective* object) const  {  	if(! mObjectClass.isInstance(object)) diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp index b44bf19227..297482a222 100644 --- a/indra/llimage/llimageworker.cpp +++ b/indra/llimage/llimageworker.cpp @@ -1,165 +1,165 @@ -/** 
 - * @file llimage.cpp
 - * @brief Base class for images.
 - *
 - * Copyright (c) 2001-$CurrentYear$, Linden Research, Inc.
 - * $License$
 - */
 -
 -#include "linden_common.h"
 -
 -#include "llimageworker.h"
 -#include "llimagedxt.h"
 -
 -//----------------------------------------------------------------------------
 -
 -//static
 -LLWorkerThread* LLImageWorker::sWorkerThread = NULL;
 -S32 LLImageWorker::sCount = 0;
 -
 -//static
 -void LLImageWorker::initClass(LLWorkerThread* workerthread)
 -{
 -	sWorkerThread = workerthread;
 -}
 -
 -//static
 -void LLImageWorker::cleanupClass()
 -{
 -}
 -
 -//----------------------------------------------------------------------------
 -
 -LLImageWorker::LLImageWorker(LLImageFormatted* image, U32 priority, S32 discard, LLResponder* responder)
 -	: LLWorkerClass(sWorkerThread, "Image"),
 -	  mFormattedImage(image),
 -	  mDecodedType(-1),
 -	  mDiscardLevel(discard),
 -	  mPriority(priority),
 -	  mResponder(responder)
 -{
 -	++sCount;
 -}
 -
 -LLImageWorker::~LLImageWorker()
 -{
 -	mDecodedImage = NULL;
 -	mFormattedImage = NULL;
 -	--sCount;
 -}
 -
 -//----------------------------------------------------------------------------
 -
 -//virtual, main thread
 -void LLImageWorker::startWork(S32 param)
 -{
 -	llassert_always(mDecodedImage.isNull());
 -	mDecodedType = -1;
 -}
 -
 -bool LLImageWorker::doWork(S32 param)
 -{
 -	bool decoded = false;
 -	if(mDecodedImage.isNull())
 -	{
 -		if (!mFormattedImage->updateData())
 -		{
 -			mDecodedType = -2; // failed
 -			return true;
 -		}
 -		if (mDiscardLevel >= 0)
 -		{
 -			mFormattedImage->setDiscardLevel(mDiscardLevel);
 -		}
 -		if (!(mFormattedImage->getWidth() * mFormattedImage->getHeight() * mFormattedImage->getComponents()))
 -		{
 -			decoded = true; // failed
 -		}
 -		else
 -		{
 -			S32 nc = param ? 1 : mFormattedImage->getComponents();
 -			mDecodedImage = new LLImageRaw(mFormattedImage->getWidth(),
 -										   mFormattedImage->getHeight(),
 -										   nc);
 -		}
 -	}
 -	if (!decoded)
 -	{
 -		if (param == 0)
 -		{
 -			// Decode primary channels
 -			decoded = mFormattedImage->decode(mDecodedImage, .1f); // 1ms
 -		}
 -		else
 -		{
 -			// Decode aux channel
 -			decoded = mFormattedImage->decode(mDecodedImage, .1f, param, param); // 1ms
 -		}
 -	}
 -	if (decoded)
 -	{
 -		// Call the callback immediately; endWork doesn't get called until ckeckWork
 -		if (mResponder.notNull())
 -		{
 -			bool success = (!wasAborted() && mDecodedImage.notNull() && mDecodedImage->getDataSize() != 0);
 -			mResponder->completed(success);
 -		}
 -	}
 -	return decoded;
 -}
 -
 -void LLImageWorker::endWork(S32 param, bool aborted)
 -{
 -	if (mDecodedType != -2)
 -	{
 -		mDecodedType = aborted ? -2 : param;
 -	}
 -}
 -
 -//----------------------------------------------------------------------------
 -
 -
 -BOOL LLImageWorker::requestDecodedAuxData(LLPointer<LLImageRaw>& raw, S32 channel, S32 discard)
 -{
 -	// For most codecs, only mDiscardLevel data is available.
 -	//  (see LLImageDXT for exception)
 -	if (discard >= 0 && discard != mFormattedImage->getDiscardLevel())
 -	{
 -		llerrs << "Request for invalid discard level" << llendl;
 -	}
 -	checkWork();
 -	if (mDecodedType == -2)
 -	{
 -		return TRUE; // aborted, done
 -	}
 -	if (mDecodedType != channel)
 -	{
 -		if (!haveWork())
 -		{
 -			addWork(channel, mPriority);
 -		}
 -		return FALSE;
 -	}
 -	else
 -	{
 -		llassert_always(!haveWork());
 -		llassert_always(mDecodedType == channel);
 -		raw = mDecodedImage; // smart pointer acquires ownership of data
 -		mDecodedImage = NULL;
 -		return TRUE;
 -	}
 -}
 -
 -BOOL LLImageWorker::requestDecodedData(LLPointer<LLImageRaw>& raw, S32 discard)
 -{
 -	if (mFormattedImage->getCodec() == IMG_CODEC_DXT)
 -	{
 -		// special case
 -		LLImageDXT* imagedxt = (LLImageDXT*)((LLImageFormatted*)mFormattedImage);
 -		return imagedxt->getMipData(raw, discard);
 -	}
 -	else
 -	{
 -		return requestDecodedAuxData(raw, 0, discard);
 -	}
 -}
 +/**  + * @file llimage.cpp + * @brief Base class for images. + * + * Copyright (c) 2001-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "linden_common.h" + +#include "llimageworker.h" +#include "llimagedxt.h" + +//---------------------------------------------------------------------------- + +//static +LLWorkerThread* LLImageWorker::sWorkerThread = NULL; +S32 LLImageWorker::sCount = 0; + +//static +void LLImageWorker::initClass(LLWorkerThread* workerthread) +{ +	sWorkerThread = workerthread; +} + +//static +void LLImageWorker::cleanupClass() +{ +} + +//---------------------------------------------------------------------------- + +LLImageWorker::LLImageWorker(LLImageFormatted* image, U32 priority, S32 discard, LLResponder* responder) +	: LLWorkerClass(sWorkerThread, "Image"), +	  mFormattedImage(image), +	  mDecodedType(-1), +	  mDiscardLevel(discard), +	  mPriority(priority), +	  mResponder(responder) +{ +	++sCount; +} + +LLImageWorker::~LLImageWorker() +{ +	mDecodedImage = NULL; +	mFormattedImage = NULL; +	--sCount; +} + +//---------------------------------------------------------------------------- + +//virtual, main thread +void LLImageWorker::startWork(S32 param) +{ +	llassert_always(mDecodedImage.isNull()); +	mDecodedType = -1; +} + +bool LLImageWorker::doWork(S32 param) +{ +	bool decoded = false; +	if(mDecodedImage.isNull()) +	{ +		if (!mFormattedImage->updateData()) +		{ +			mDecodedType = -2; // failed +			return true; +		} +		if (mDiscardLevel >= 0) +		{ +			mFormattedImage->setDiscardLevel(mDiscardLevel); +		} +		if (!(mFormattedImage->getWidth() * mFormattedImage->getHeight() * mFormattedImage->getComponents())) +		{ +			decoded = true; // failed +		} +		else +		{ +			S32 nc = param ? 1 : mFormattedImage->getComponents(); +			mDecodedImage = new LLImageRaw(mFormattedImage->getWidth(), +										   mFormattedImage->getHeight(), +										   nc); +		} +	} +	if (!decoded) +	{ +		if (param == 0) +		{ +			// Decode primary channels +			decoded = mFormattedImage->decode(mDecodedImage, .1f); // 1ms +		} +		else +		{ +			// Decode aux channel +			decoded = mFormattedImage->decode(mDecodedImage, .1f, param, param); // 1ms +		} +	} +	if (decoded) +	{ +		// Call the callback immediately; endWork doesn't get called until ckeckWork +		if (mResponder.notNull()) +		{ +			bool success = (!wasAborted() && mDecodedImage.notNull() && mDecodedImage->getDataSize() != 0); +			mResponder->completed(success); +		} +	} +	return decoded; +} + +void LLImageWorker::endWork(S32 param, bool aborted) +{ +	if (mDecodedType != -2) +	{ +		mDecodedType = aborted ? -2 : param; +	} +} + +//---------------------------------------------------------------------------- + + +BOOL LLImageWorker::requestDecodedAuxData(LLPointer<LLImageRaw>& raw, S32 channel, S32 discard) +{ +	// For most codecs, only mDiscardLevel data is available. +	//  (see LLImageDXT for exception) +	if (discard >= 0 && discard != mFormattedImage->getDiscardLevel()) +	{ +		llerrs << "Request for invalid discard level" << llendl; +	} +	checkWork(); +	if (mDecodedType == -2) +	{ +		return TRUE; // aborted, done +	} +	if (mDecodedType != channel) +	{ +		if (!haveWork()) +		{ +			addWork(channel, mPriority); +		} +		return FALSE; +	} +	else +	{ +		llassert_always(!haveWork()); +		llassert_always(mDecodedType == channel); +		raw = mDecodedImage; // smart pointer acquires ownership of data +		mDecodedImage = NULL; +		return TRUE; +	} +} + +BOOL LLImageWorker::requestDecodedData(LLPointer<LLImageRaw>& raw, S32 discard) +{ +	if (mFormattedImage->getCodec() == IMG_CODEC_DXT) +	{ +		// special case +		LLImageDXT* imagedxt = (LLImageDXT*)((LLImageFormatted*)mFormattedImage); +		return imagedxt->getMipData(raw, discard); +	} +	else +	{ +		return requestDecodedAuxData(raw, 0, discard); +	} +} diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h index cdd30417ce..6e9ecacc89 100644 --- a/indra/llimage/llimageworker.h +++ b/indra/llimage/llimageworker.h @@ -1,57 +1,57 @@ -/** 
 - * @file llimageworker.h
 - * @brief Object for managing images and their textures.
 - *
 - * Copyright (c) 2000-$CurrentYear$, Linden Research, Inc.
 - * $License$
 - */
 -
 -#ifndef LL_LLIMAGEWORKER_H
 -#define LL_LLIMAGEWORKER_H
 -
 -#include "llimage.h"
 -#include "llworkerthread.h"
 -
 -class LLImageWorker : public LLWorkerClass
 -{
 -public:
 -	static void initClass(LLWorkerThread* workerthread);
 -	static void cleanupClass();
 -	static LLWorkerThread* getWorkerThread() { return sWorkerThread; }
 -
 -	// LLWorkerThread
 -public:
 -	LLImageWorker(LLImageFormatted* image, U32 priority, S32 discard, LLResponder* responder = NULL);
 -	~LLImageWorker();
 -
 -	// called from WORKER THREAD, returns TRUE if done
 -	/*virtual*/ bool doWork(S32 param);
 -	
 -	BOOL requestDecodedData(LLPointer<LLImageRaw>& raw, S32 discard = -1);
 -	BOOL requestDecodedAuxData(LLPointer<LLImageRaw>& raw, S32 channel, S32 discard = -1);
 -	void releaseDecodedData();
 -	void cancelDecode();
 -
 -private:
 -	// called from MAIN THREAD
 -	/*virtual*/ void startWork(S32 param); // called from addWork()
 -	/*virtual*/ void endWork(S32 param, bool aborted); // called from doWork()
 -
 -protected:
 -	LLPointer<LLImageFormatted> mFormattedImage;
 -	LLPointer<LLImageRaw> mDecodedImage;
 -	S32 mDecodedType;
 -	S32 mDiscardLevel;
 -
 -private:
 -	U32 mPriority;
 -	LLPointer<LLResponder> mResponder;
 -	
 -protected:
 -	static LLWorkerThread* sWorkerThread;
 -
 -public:
 -	static S32 sCount;
 -};
 -
 -#endif
 +/**  + * @file llimageworker.h + * @brief Object for managing images and their textures. + * + * Copyright (c) 2000-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#ifndef LL_LLIMAGEWORKER_H +#define LL_LLIMAGEWORKER_H + +#include "llimage.h" +#include "llworkerthread.h" + +class LLImageWorker : public LLWorkerClass +{ +public: +	static void initClass(LLWorkerThread* workerthread); +	static void cleanupClass(); +	static LLWorkerThread* getWorkerThread() { return sWorkerThread; } + +	// LLWorkerThread +public: +	LLImageWorker(LLImageFormatted* image, U32 priority, S32 discard, LLResponder* responder = NULL); +	~LLImageWorker(); + +	// called from WORKER THREAD, returns TRUE if done +	/*virtual*/ bool doWork(S32 param); +	 +	BOOL requestDecodedData(LLPointer<LLImageRaw>& raw, S32 discard = -1); +	BOOL requestDecodedAuxData(LLPointer<LLImageRaw>& raw, S32 channel, S32 discard = -1); +	void releaseDecodedData(); +	void cancelDecode(); + +private: +	// called from MAIN THREAD +	/*virtual*/ void startWork(S32 param); // called from addWork() +	/*virtual*/ void endWork(S32 param, bool aborted); // called from doWork() + +protected: +	LLPointer<LLImageFormatted> mFormattedImage; +	LLPointer<LLImageRaw> mDecodedImage; +	S32 mDecodedType; +	S32 mDiscardLevel; + +private: +	U32 mPriority; +	LLPointer<LLResponder> mResponder; +	 +protected: +	static LLWorkerThread* sWorkerThread; + +public: +	static S32 sCount; +}; + +#endif diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index e5b2a5f312..f7ad363206 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -21,7 +21,11 @@  #endif  #define LL_OCTREE_PARANOIA_CHECK 0 +#if LL_DARWIN +#define LL_OCTREE_MAX_CAPACITY 32 +#else  #define LL_OCTREE_MAX_CAPACITY 256 +#endif  template <class T> class LLOctreeState;  template <class T> class LLOctreeNode; diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 9c1178b9f7..1196db18fa 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -713,6 +713,8 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3  		if (!res) llerrs << "LLImageGL::setSubImage(): bindTexture failed" << llendl;  		stop_glerror(); +		LLGLEnable tex( GL_TEXTURE_2D );  +  		glTexSubImage2D(mTarget, 0, x_pos, y_pos,   						width, height, mFormatPrimary, mFormatType, datap);  		stop_glerror(); diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index d6477d69ec..b94f593d7f 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -12,8 +12,8 @@  S32 LLVertexBuffer::sCount = 0;  S32 LLVertexBuffer::sGLCount = 0;  BOOL LLVertexBuffer::sEnableVBOs = TRUE; -S32 LLVertexBuffer::sGLRenderBuffer = 0; -S32 LLVertexBuffer::sGLRenderIndices = 0; +U32 LLVertexBuffer::sGLRenderBuffer = 0; +U32 LLVertexBuffer::sGLRenderIndices = 0;  U32 LLVertexBuffer::sLastMask = 0;  BOOL LLVertexBuffer::sVBOActive = FALSE;  BOOL LLVertexBuffer::sIBOActive = FALSE; @@ -92,7 +92,7 @@ void LLVertexBuffer::stopRender()  	sRenderActive = FALSE;  } -void LLVertexBuffer::clientCopy() +void LLVertexBuffer::clientCopy(F64 max_time)  {  	if (!sDeleteList.empty())  	{ @@ -122,7 +122,7 @@ void LLVertexBuffer::clientCopy()  			}  			else  			{ -				if (timer.getElapsedTimeF64() > 0.005) +				if (timer.getElapsedTimeF64() > max_time)  				{  					break;  				} @@ -191,7 +191,10 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :  	mNumVerts(0), mNumIndices(0), mUsage(usage), mGLBuffer(0), mGLIndices(0),   	mMappedData(NULL),  	mMappedIndexData(NULL), mLocked(FALSE), -	mResized(FALSE), mEmpty(TRUE), mFinal(FALSE), mFilthy(FALSE) +	mFinal(FALSE), +	mFilthy(FALSE), +	mEmpty(TRUE), +	mResized(FALSE)  {  	LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);  	if (!sEnableVBOs) @@ -614,7 +617,6 @@ void LLVertexBuffer::unmapBuffer()  						{  							DirtyRegion& region = *i;  							glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, region.mIndex*mStride, region.mCount*mStride, mMappedData + region.mIndex*mStride); -							glFlush();  						}  					}  				} @@ -639,7 +641,6 @@ void LLVertexBuffer::unmapBuffer()  							DirtyRegion& region = *i;  							glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, region.mIndicesIndex*sizeof(U32),   								region.mIndicesCount*sizeof(U32), mMappedIndexData + region.mIndicesIndex*sizeof(U32)); -							glFlush();  						}  					}  				} @@ -786,13 +787,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)  		unmapBuffer();  	}  	else -	{ -		if (!mDirtyRegions.empty()) -		{ -			mFilthy = TRUE; -			mDirtyRegions.clear(); -		} -		 +	{		  		if (mGLBuffer)  		{  			if (sEnableVBOs && sVBOActive) @@ -890,6 +885,15 @@ void LLVertexBuffer::markDirty(U32 vert_index, U32 vert_count, U32 indices_index  		if (!mDirtyRegions.empty())  		{  			DirtyRegion& region = *(mDirtyRegions.rbegin()); +			 +			if (region.mIndex+region.mCount > vert_index) +			{ +				//this buffer has received multiple updates since the last copy, mark it filthy +				mFilthy = TRUE; +				mDirtyRegions.clear(); +				return; +			} +			  			if (region.mIndex + region.mCount == vert_index &&  				region.mIndicesIndex + region.mIndicesCount == indices_index)  			{ diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index e672321e76..b221d35ee3 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -29,7 +29,7 @@ public:  	static void cleanupClass();   	static void startRender(); //between start and stop render, no client copies will occur  	static void stopRender(); //any buffer not copied to GL will be rendered from client memory -	static void clientCopy(); //copy data from client to GL +	static void clientCopy(F64 max_time = 0.005); //copy data from client to GL  	static void unbind(); //unbind any bound vertex buffer  	enum { @@ -167,8 +167,8 @@ public:  	static BOOL sEnableVBOs;  	static S32 sTypeOffsets[TYPE_MAX]; -	static S32 sGLRenderBuffer; -	static S32 sGLRenderIndices; +	static U32 sGLRenderBuffer; +	static U32 sGLRenderIndices;  	static BOOL sVBOActive;  	static BOOL sIBOActive;  	static U32 sLastMask; diff --git a/indra/llui/llctrlselectioninterface.cpp b/indra/llui/llctrlselectioninterface.cpp index a58fb88e75..61044aa7da 100644 --- a/indra/llui/llctrlselectioninterface.cpp +++ b/indra/llui/llctrlselectioninterface.cpp @@ -1,44 +1,44 @@ -/** 
 - * @file llctrlselectioninterface.cpp
 - * @brief Programmatic selection of items in a list.
 - *
 - * Copyright (c) 2006-$CurrentYear$, Linden Research, Inc.
 - * $License$
 - */
 -
 -#include "llctrlselectioninterface.h"
 -
 -#include "llsd.h"
 -
 -// virtual
 -LLCtrlSelectionInterface::~LLCtrlSelectionInterface()
 -{ }
 -
 -BOOL LLCtrlSelectionInterface::selectByValue(LLSD value)
 -{
 -	return setSelectedByValue(value, TRUE);
 -}
 -
 -BOOL LLCtrlSelectionInterface::deselectByValue(LLSD value)
 -{ 
 -	return setSelectedByValue(value, FALSE); 
 -}
 -
 -
 -// virtual
 -LLCtrlListInterface::~LLCtrlListInterface()
 -{ }
 -
 -LLScrollListItem* LLCtrlListInterface::addSimpleElement(const LLString& value)
 -{
 -	return addSimpleElement(value, ADD_BOTTOM, LLSD());
 -}
 -
 -LLScrollListItem* LLCtrlListInterface::addSimpleElement(const LLString& value, EAddPosition pos)
 -{
 -	return addSimpleElement(value, pos, LLSD());
 -}
 -
 -// virtual
 -LLCtrlScrollInterface::~LLCtrlScrollInterface()
 -{ }
 +/**  + * @file llctrlselectioninterface.cpp + * @brief Programmatic selection of items in a list. + * + * Copyright (c) 2006-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "llctrlselectioninterface.h" + +#include "llsd.h" + +// virtual +LLCtrlSelectionInterface::~LLCtrlSelectionInterface() +{ } + +BOOL LLCtrlSelectionInterface::selectByValue(LLSD value) +{ +	return setSelectedByValue(value, TRUE); +} + +BOOL LLCtrlSelectionInterface::deselectByValue(LLSD value) +{  +	return setSelectedByValue(value, FALSE);  +} + + +// virtual +LLCtrlListInterface::~LLCtrlListInterface() +{ } + +LLScrollListItem* LLCtrlListInterface::addSimpleElement(const LLString& value) +{ +	return addSimpleElement(value, ADD_BOTTOM, LLSD()); +} + +LLScrollListItem* LLCtrlListInterface::addSimpleElement(const LLString& value, EAddPosition pos) +{ +	return addSimpleElement(value, pos, LLSD()); +} + +// virtual +LLCtrlScrollInterface::~LLCtrlScrollInterface() +{ } diff --git a/indra/llui/llctrlselectioninterface.h b/indra/llui/llctrlselectioninterface.h index 4e2807e9a1..698d609593 100644 --- a/indra/llui/llctrlselectioninterface.h +++ b/indra/llui/llctrlselectioninterface.h @@ -1,84 +1,84 @@ -/** 
 - * @file llctrlselectioninterface.h
 - * @brief Programmatic selection of items in a list.
 - *
 - * Copyright (c) 2006-$CurrentYear$, Linden Research, Inc.
 - * $License$
 - */
 -
 -#ifndef LLCTRLSELECTIONINTERFACE_H
 -#define LLCTRLSELECTIONINTERFACE_H
 -
 -#include "stdtypes.h"
 -#include "stdenums.h"
 -#include "llstring.h"
 -
 -class LLSD;
 -class LLUUID;
 -class LLScrollListItem;
 -
 -class LLCtrlSelectionInterface
 -{
 -public:
 -	virtual ~LLCtrlSelectionInterface();
 -	
 -	enum EOperation
 -	{
 -		OP_DELETE = 1,
 -		OP_SELECT,
 -		OP_DESELECT,
 -	};
 -
 -	virtual BOOL	getCanSelect() const = 0;
 -
 -	virtual BOOL	selectFirstItem() = 0;
 -	virtual BOOL	selectNthItem( S32 index ) = 0;
 -
 -	virtual S32		getFirstSelectedIndex() = 0;
 -
 -	// TomY TODO: Simply cast the UUIDs to LLSDs, using the selectByValue function
 -	virtual BOOL	setCurrentByID( const LLUUID& id ) = 0;
 -	virtual LLUUID	getCurrentID() = 0;
 -
 -			BOOL	selectByValue(LLSD value);
 -			BOOL	deselectByValue(LLSD value);
 -	virtual BOOL	setSelectedByValue(LLSD value, BOOL selected) = 0;
 -	virtual LLSD	getSimpleSelectedValue() = 0;
 -
 -	virtual BOOL	isSelected(LLSD value) = 0;
 -
 -	virtual BOOL	operateOnSelection(EOperation op) = 0;
 -	virtual BOOL	operateOnAll(EOperation op) = 0;
 -};
 -
 -class LLCtrlListInterface : public LLCtrlSelectionInterface
 -{
 -public:
 -	virtual ~LLCtrlListInterface();
 -	
 -	virtual S32 getItemCount() const = 0;
 -	virtual void addColumn(const LLSD& column, EAddPosition pos = ADD_BOTTOM) = 0;
 -	virtual void clearColumns() = 0;
 -	virtual void setColumnLabel(const LLString& column, const LLString& label) = 0;
 -	// TomY TODO: Document this
 -	virtual LLScrollListItem* addElement(const LLSD& value, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL) = 0;
 -
 -	LLScrollListItem* addSimpleElement(const LLString& value); // defaults to bottom
 -	LLScrollListItem* addSimpleElement(const LLString& value, EAddPosition pos); // defaults to no LLSD() id
 -	virtual LLScrollListItem* addSimpleElement(const LLString& value, EAddPosition pos, const LLSD& id) = 0;
 -
 -	virtual void clearRows() = 0;
 -	virtual void sortByColumn(LLString name, BOOL ascending) = 0;
 -};
 -
 -class LLCtrlScrollInterface
 -{
 -public:
 -	virtual ~LLCtrlScrollInterface();
 -	
 -	virtual S32 getScrollPos() = 0;
 -	virtual void setScrollPos( S32 pos ) = 0;
 -	virtual void scrollToShowSelected() = 0;
 -};
 -
 -#endif
 +/**  + * @file llctrlselectioninterface.h + * @brief Programmatic selection of items in a list. + * + * Copyright (c) 2006-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#ifndef LLCTRLSELECTIONINTERFACE_H +#define LLCTRLSELECTIONINTERFACE_H + +#include "stdtypes.h" +#include "stdenums.h" +#include "llstring.h" + +class LLSD; +class LLUUID; +class LLScrollListItem; + +class LLCtrlSelectionInterface +{ +public: +	virtual ~LLCtrlSelectionInterface(); +	 +	enum EOperation +	{ +		OP_DELETE = 1, +		OP_SELECT, +		OP_DESELECT, +	}; + +	virtual BOOL	getCanSelect() const = 0; + +	virtual BOOL	selectFirstItem() = 0; +	virtual BOOL	selectNthItem( S32 index ) = 0; + +	virtual S32		getFirstSelectedIndex() = 0; + +	// TomY TODO: Simply cast the UUIDs to LLSDs, using the selectByValue function +	virtual BOOL	setCurrentByID( const LLUUID& id ) = 0; +	virtual LLUUID	getCurrentID() = 0; + +			BOOL	selectByValue(LLSD value); +			BOOL	deselectByValue(LLSD value); +	virtual BOOL	setSelectedByValue(LLSD value, BOOL selected) = 0; +	virtual LLSD	getSimpleSelectedValue() = 0; + +	virtual BOOL	isSelected(LLSD value) = 0; + +	virtual BOOL	operateOnSelection(EOperation op) = 0; +	virtual BOOL	operateOnAll(EOperation op) = 0; +}; + +class LLCtrlListInterface : public LLCtrlSelectionInterface +{ +public: +	virtual ~LLCtrlListInterface(); +	 +	virtual S32 getItemCount() const = 0; +	virtual void addColumn(const LLSD& column, EAddPosition pos = ADD_BOTTOM) = 0; +	virtual void clearColumns() = 0; +	virtual void setColumnLabel(const LLString& column, const LLString& label) = 0; +	// TomY TODO: Document this +	virtual LLScrollListItem* addElement(const LLSD& value, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL) = 0; + +	LLScrollListItem* addSimpleElement(const LLString& value); // defaults to bottom +	LLScrollListItem* addSimpleElement(const LLString& value, EAddPosition pos); // defaults to no LLSD() id +	virtual LLScrollListItem* addSimpleElement(const LLString& value, EAddPosition pos, const LLSD& id) = 0; + +	virtual void clearRows() = 0; +	virtual void sortByColumn(LLString name, BOOL ascending) = 0; +}; + +class LLCtrlScrollInterface +{ +public: +	virtual ~LLCtrlScrollInterface(); +	 +	virtual S32 getScrollPos() = 0; +	virtual void setScrollPos( S32 pos ) = 0; +	virtual void scrollToShowSelected() = 0; +}; + +#endif diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index f2ae318dca..35d5affa5d 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -377,20 +377,21 @@ LLScrollListCtrl::LLScrollListCtrl(const LLString& name, const LLRect& rect,  	mFgUnselectedColor( LLUI::sColorsGroup->getColor("ScrollUnselectedColor") ),  	mFgDisabledColor( LLUI::sColorsGroup->getColor("ScrollDisabledColor") ),  	mHighlightedColor( LLUI::sColorsGroup->getColor("ScrollHighlightedColor") ), -	mHighlightedItem(-1),  	mBorderThickness( 2 ),  	mOnDoubleClickCallback( NULL ),  	mOnMaximumSelectCallback( NULL ),  	mOnSortChangedCallback( NULL ), -	mDrewSelected(FALSE), +	mHighlightedItem(-1),  	mBorder(NULL), -	mSearchColumn(0),  	mDefaultColumn("SIMPLE"), +	mSearchColumn(0),  	mNumDynamicWidthColumns(0),  	mTotalStaticColumnWidth(0),  	mSortColumn(0), -	mSortAscending(TRUE) +	mSortAscending(TRUE), + +	mDrewSelected(FALSE)  {  	mItemListRect.setOriginAndSize(  		mBorderThickness + LIST_BORDER_PAD, diff --git a/indra/llui/llviewquery.cpp b/indra/llui/llviewquery.cpp index 416ca623bc..650125d486 100644 --- a/indra/llui/llviewquery.cpp +++ b/indra/llui/llviewquery.cpp @@ -1,126 +1,126 @@ -/** 
 - * @file llviewquery.cpp
 - * @brief Implementation of view query class.
 - *
 - * Copyright (c) 2001-$CurrentYear$, Linden Research, Inc.
 - * $License$
 - */
 -
 -#include "llview.h"
 -#include "lluictrl.h"
 -#include "llviewquery.h"
 -
 -void LLQuerySorter::operator() (LLView * parent, viewList_t &children) const {}
 -
 -filterResult_t LLNoLeavesFilter::operator() (const LLView* const view, const viewList_t & children) const 
 -{
 -	return filterResult_t(!(view->getChildList()->size() == 0), TRUE);
 -}
 -
 -filterResult_t LLVisibleFilter::operator() (const LLView* const view, const viewList_t & children) const 
 -{
 -	return filterResult_t(view->getVisible(), view->getVisible());
 -}
 -filterResult_t LLEnabledFilter::operator() (const LLView* const view, const viewList_t & children) const 
 -{
 -	return filterResult_t(view->getEnabled(), view->getEnabled());
 -}
 -filterResult_t LLTabStopFilter::operator() (const LLView* const view, const viewList_t & children) const 
 -{
 -	return filterResult_t(view->isCtrl() && static_cast<const LLUICtrl* const>(view)->hasTabStop(),
 -						view->canFocusChildren());
 -}
 -
 -// LLViewQuery
 -
 -LLViewQuery::LLViewQuery(): mPreFilters(), mPostFilters(), mSorterp() 
 -{
 -}
 -
 -void LLViewQuery::addPreFilter(const LLQueryFilter* prefilter) { mPreFilters.push_back(prefilter); }
 -
 -void LLViewQuery::addPostFilter(const LLQueryFilter* postfilter) {	mPostFilters.push_back(postfilter); }
 -
 -const LLViewQuery::filterList_t & LLViewQuery::getPreFilters() const { return mPreFilters; }
 -
 -const LLViewQuery::filterList_t & LLViewQuery::getPostFilters() const { return mPostFilters; }
 -
 -void LLViewQuery::setSorter(const LLQuerySorter* sorterp) { mSorterp = sorterp; }
 -const LLQuerySorter* LLViewQuery::getSorter() const { return mSorterp; }
 -
 -viewList_t LLViewQuery::run(LLView * view) const
 -{
 -	viewList_t result;
 -
 -	filterResult_t pre = runFilters(view, viewList_t(), mPreFilters);
 -	if(!pre.first && !pre.second)
 -	{
 -		// skip post filters completely if we're not including ourselves or the children
 -		return result;
 -	}
 -	if(pre.second)
 -	{
 -		// run filters on children
 -		viewList_t filtered_children;
 -		filterChildren(view, filtered_children);
 -		filterResult_t post = runFilters(view, filtered_children, mPostFilters);
 -		if(pre.first && post.first)
 -		{
 -			result.push_back(view);
 -		}
 -		if(post.second)
 -		{
 -			result.insert(result.end(), filtered_children.begin(), filtered_children.end());
 -		}
 -	}
 -	else 
 -	{
 -		if(pre.first) 
 -		{
 -			result.push_back(view);
 -		}
 -	}
 -	return result;
 -}
 -
 -void LLViewQuery::filterChildren(LLView * view, viewList_t & filtered_children) const
 -{
 -	LLView::child_list_t views(*(view->getChildList()));
 -	(*mSorterp)(view, views); // sort the children per the sorter
 -	for(LLView::child_list_iter_t iter = views.begin();
 -			iter != views.end();
 -			iter++)
 -		{
 -			viewList_t indiv_children = this->run(*iter);
 -			filtered_children.insert(filtered_children.end(), indiv_children.begin(), indiv_children.end());
 -		}
 -}
 -
 -filterResult_t LLViewQuery::runFilters(LLView * view, const viewList_t children, const filterList_t filters) const
 -{
 -	filterResult_t result = filterResult_t(TRUE, TRUE);
 -	for(filterList_const_iter_t iter = filters.begin();
 -		iter != filters.end();
 -		iter++)
 -	{
 -		filterResult_t filtered = (**iter)(view, children);
 -		result.first = result.first && filtered.first;
 -		result.second = result.second && filtered.second;
 -	}
 -	return result;
 -}
 -
 -class SortByTabOrder : public LLQuerySorter, public LLSingleton<SortByTabOrder>
 -{
 -	/*virtual*/ void operator() (LLView * parent, LLView::child_list_t &children) const 
 -	{
 -		children.sort(LLCompareByTabOrder(parent->getCtrlOrder()));
 -	}
 -};
 -
 -LLCtrlQuery::LLCtrlQuery() : 
 -	LLViewQuery()
 -{
 -	setSorter(SortByTabOrder::getInstance());
 -}
 -
 +/**  + * @file llviewquery.cpp + * @brief Implementation of view query class. + * + * Copyright (c) 2001-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "llview.h" +#include "lluictrl.h" +#include "llviewquery.h" + +void LLQuerySorter::operator() (LLView * parent, viewList_t &children) const {} + +filterResult_t LLNoLeavesFilter::operator() (const LLView* const view, const viewList_t & children) const  +{ +	return filterResult_t(!(view->getChildList()->size() == 0), TRUE); +} + +filterResult_t LLVisibleFilter::operator() (const LLView* const view, const viewList_t & children) const  +{ +	return filterResult_t(view->getVisible(), view->getVisible()); +} +filterResult_t LLEnabledFilter::operator() (const LLView* const view, const viewList_t & children) const  +{ +	return filterResult_t(view->getEnabled(), view->getEnabled()); +} +filterResult_t LLTabStopFilter::operator() (const LLView* const view, const viewList_t & children) const  +{ +	return filterResult_t(view->isCtrl() && static_cast<const LLUICtrl* const>(view)->hasTabStop(), +						view->canFocusChildren()); +} + +// LLViewQuery + +LLViewQuery::LLViewQuery(): mPreFilters(), mPostFilters(), mSorterp()  +{ +} + +void LLViewQuery::addPreFilter(const LLQueryFilter* prefilter) { mPreFilters.push_back(prefilter); } + +void LLViewQuery::addPostFilter(const LLQueryFilter* postfilter) {	mPostFilters.push_back(postfilter); } + +const LLViewQuery::filterList_t & LLViewQuery::getPreFilters() const { return mPreFilters; } + +const LLViewQuery::filterList_t & LLViewQuery::getPostFilters() const { return mPostFilters; } + +void LLViewQuery::setSorter(const LLQuerySorter* sorterp) { mSorterp = sorterp; } +const LLQuerySorter* LLViewQuery::getSorter() const { return mSorterp; } + +viewList_t LLViewQuery::run(LLView * view) const +{ +	viewList_t result; + +	filterResult_t pre = runFilters(view, viewList_t(), mPreFilters); +	if(!pre.first && !pre.second) +	{ +		// skip post filters completely if we're not including ourselves or the children +		return result; +	} +	if(pre.second) +	{ +		// run filters on children +		viewList_t filtered_children; +		filterChildren(view, filtered_children); +		filterResult_t post = runFilters(view, filtered_children, mPostFilters); +		if(pre.first && post.first) +		{ +			result.push_back(view); +		} +		if(post.second) +		{ +			result.insert(result.end(), filtered_children.begin(), filtered_children.end()); +		} +	} +	else  +	{ +		if(pre.first)  +		{ +			result.push_back(view); +		} +	} +	return result; +} + +void LLViewQuery::filterChildren(LLView * view, viewList_t & filtered_children) const +{ +	LLView::child_list_t views(*(view->getChildList())); +	(*mSorterp)(view, views); // sort the children per the sorter +	for(LLView::child_list_iter_t iter = views.begin(); +			iter != views.end(); +			iter++) +		{ +			viewList_t indiv_children = this->run(*iter); +			filtered_children.insert(filtered_children.end(), indiv_children.begin(), indiv_children.end()); +		} +} + +filterResult_t LLViewQuery::runFilters(LLView * view, const viewList_t children, const filterList_t filters) const +{ +	filterResult_t result = filterResult_t(TRUE, TRUE); +	for(filterList_const_iter_t iter = filters.begin(); +		iter != filters.end(); +		iter++) +	{ +		filterResult_t filtered = (**iter)(view, children); +		result.first = result.first && filtered.first; +		result.second = result.second && filtered.second; +	} +	return result; +} + +class SortByTabOrder : public LLQuerySorter, public LLSingleton<SortByTabOrder> +{ +	/*virtual*/ void operator() (LLView * parent, LLView::child_list_t &children) const  +	{ +		children.sort(LLCompareByTabOrder(parent->getCtrlOrder())); +	} +}; + +LLCtrlQuery::LLCtrlQuery() :  +	LLViewQuery() +{ +	setSorter(SortByTabOrder::getInstance()); +} + diff --git a/indra/llui/llviewquery.h b/indra/llui/llviewquery.h index ba59965c59..32852791af 100644 --- a/indra/llui/llviewquery.h +++ b/indra/llui/llviewquery.h @@ -1,89 +1,89 @@ -/** 
 - * @file llviewquery.h
 - * @brief Query algorithm for flattening and filtering the view hierarchy.
 - *
 - * Copyright (c) 2001-$CurrentYear$, Linden Research, Inc.
 - * $License$
 - */
 -
 -#ifndef LL_LLVIEWQUERY_H
 -#define LL_LLVIEWQUERY_H
 -
 -#include <list>	
 -
 -#include "llmemory.h"
 -
 -class LLView;
 -
 -typedef std::list<LLView *>			viewList_t;
 -typedef std::pair<BOOL, BOOL>		filterResult_t;
 -
 -// Abstract base class for all filters.
 -class LLQueryFilter : public LLRefCount
 -{
 -public:
 -	virtual filterResult_t operator() (const LLView* const view, const viewList_t & children) const =0;
 -};
 -
 -class LLQuerySorter : public LLRefCount
 -{
 -public:
 -	virtual void operator() (LLView * parent, viewList_t &children) const;
 -};
 -
 -class LLNoLeavesFilter : public LLQueryFilter, public LLSingleton<LLNoLeavesFilter>
 -{
 -	/*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const;
 -};
 -class LLVisibleFilter : public LLQueryFilter, public LLSingleton<LLVisibleFilter>
 -{
 -	/*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const;
 -};
 -class LLEnabledFilter : public LLQueryFilter, public LLSingleton<LLEnabledFilter>
 -{
 -	/*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const;
 -};
 -class LLTabStopFilter : public LLQueryFilter, public LLSingleton<LLTabStopFilter>
 -{
 -	/*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const;
 -};
 -
 -// Algorithm for flattening
 -class LLViewQuery
 -{
 -public:
 -	typedef std::list<const LLQueryFilter*>		filterList_t;
 -	typedef filterList_t::iterator				filterList_iter_t;
 -	typedef filterList_t::const_iterator		filterList_const_iter_t;
 -
 -	LLViewQuery();
 -	virtual ~LLViewQuery() {}
 -
 -	void addPreFilter(const LLQueryFilter* prefilter);
 -	void addPostFilter(const LLQueryFilter* postfilter);
 -	const filterList_t & getPreFilters() const;
 -	const filterList_t & getPostFilters() const;
 -
 -	void setSorter(const LLQuerySorter* sorter);
 -	const LLQuerySorter* getSorter() const;
 -
 -	viewList_t run(LLView * view) const;
 -	// syntactic sugar
 -	viewList_t operator () (LLView * view) const { return run(view); }
 -protected:
 -	// override this method to provide iteration over other types of children
 -	virtual void filterChildren(LLView * view, viewList_t & filtered_children) const;
 -	filterResult_t runFilters(LLView * view, const viewList_t children, const filterList_t filters) const;
 -protected:
 -	filterList_t mPreFilters;
 -	filterList_t mPostFilters;
 -	const LLQuerySorter* mSorterp;
 -};
 -
 -class LLCtrlQuery : public LLViewQuery
 -{
 -public:
 -	LLCtrlQuery();
 -};
 -
 -#endif
 +/**  + * @file llviewquery.h + * @brief Query algorithm for flattening and filtering the view hierarchy. + * + * Copyright (c) 2001-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#ifndef LL_LLVIEWQUERY_H +#define LL_LLVIEWQUERY_H + +#include <list>	 + +#include "llmemory.h" + +class LLView; + +typedef std::list<LLView *>			viewList_t; +typedef std::pair<BOOL, BOOL>		filterResult_t; + +// Abstract base class for all filters. +class LLQueryFilter : public LLRefCount +{ +public: +	virtual filterResult_t operator() (const LLView* const view, const viewList_t & children) const =0; +}; + +class LLQuerySorter : public LLRefCount +{ +public: +	virtual void operator() (LLView * parent, viewList_t &children) const; +}; + +class LLNoLeavesFilter : public LLQueryFilter, public LLSingleton<LLNoLeavesFilter> +{ +	/*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; +}; +class LLVisibleFilter : public LLQueryFilter, public LLSingleton<LLVisibleFilter> +{ +	/*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; +}; +class LLEnabledFilter : public LLQueryFilter, public LLSingleton<LLEnabledFilter> +{ +	/*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; +}; +class LLTabStopFilter : public LLQueryFilter, public LLSingleton<LLTabStopFilter> +{ +	/*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const; +}; + +// Algorithm for flattening +class LLViewQuery +{ +public: +	typedef std::list<const LLQueryFilter*>		filterList_t; +	typedef filterList_t::iterator				filterList_iter_t; +	typedef filterList_t::const_iterator		filterList_const_iter_t; + +	LLViewQuery(); +	virtual ~LLViewQuery() {} + +	void addPreFilter(const LLQueryFilter* prefilter); +	void addPostFilter(const LLQueryFilter* postfilter); +	const filterList_t & getPreFilters() const; +	const filterList_t & getPostFilters() const; + +	void setSorter(const LLQuerySorter* sorter); +	const LLQuerySorter* getSorter() const; + +	viewList_t run(LLView * view) const; +	// syntactic sugar +	viewList_t operator () (LLView * view) const { return run(view); } +protected: +	// override this method to provide iteration over other types of children +	virtual void filterChildren(LLView * view, viewList_t & filtered_children) const; +	filterResult_t runFilters(LLView * view, const viewList_t children, const filterList_t filters) const; +protected: +	filterList_t mPreFilters; +	filterList_t mPostFilters; +	const LLQuerySorter* mSorterp; +}; + +class LLCtrlQuery : public LLViewQuery +{ +public: +	LLCtrlQuery(); +}; + +#endif diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 868d61942d..3418007d41 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -908,8 +908,8 @@ void LLDrawable::updateLightSet()  		// mLightSet points to nearby lights  		mLightSet.clear();  		part->getLights(getPositionAgent(), getRadius(), mLightSet); -		const S32 max_lights = 16; -		if (mLightSet.size() > max_lights) +		const drawable_set_t::size_type MAX_LIGHTS = 16; +		if (mLightSet.size() > MAX_LIGHTS)  		{  			typedef std::set<std::pair<F32,LLPointer<LLDrawable> > > sorted_pair_set_t;  			sorted_pair_set_t sorted_set; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 64edcecdc6..bb76957da1 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -711,11 +711,13 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  	const LLVolumeFace &face = volume.getVolumeFace(f);  	//get bounding box -	if (mDrawablep->isState(LLDrawable::REBUILD_ALL)) +	if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION))  	{ -		//vertex buffer no longer valid -		mVertexBuffer = NULL; -		mLastVertexBuffer = NULL; +		if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME)) +		{ //vertex buffer no longer valid +			mVertexBuffer = NULL; +			mLastVertexBuffer = NULL; +		}  		LLVector3 min,max; diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 85b8bbebd4..cbcdfaa55c 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -159,7 +159,7 @@ static struct ft_display_info ft_display_table[] =  //	{ LLFastTimer::FTM_RENDER_FONTS,		"   Fonts",			&LLColor4::pink1, 0 },  //	{ LLFastTimer::FTM_UPDATE_TEXTURES,		"  Textures",		&LLColor4::pink2, 0 },  	{ LLFastTimer::FTM_SWAP,				"  Swap",			&LLColor4::pink1, 0 }, -// 	{ LLFastTimer::FTM_TEMP6,				"  Client Copy",	&LLColor4::red1, 1}, +	{ LLFastTimer::FTM_CLIENT_COPY,			"  Client Copy",	&LLColor4::red1, 1},  //	{ LLFastTimer::FTM_TEMP1,				" Temp1",			&LLColor4::red1, 0 },  // 	{ LLFastTimer::FTM_TEMP2,				" Temp2",			&LLColor4::magenta1, 0 }, diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index 4e03e34663..020ce00bab 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -216,12 +216,6 @@ void LLVolumeImplFlexible::setAttributesOfAllSections()  void LLVolumeImplFlexible::onSetVolume(const LLVolumeParams &volume_params, const S32 detail)  { -	if (mVO && mVO->mDrawable.notNull()) -	{ -		LLVOVolume* volume = (LLVOVolume*) mVO; -		volume->regenFaces(); -	} -  	/*doIdleUpdate(gAgent, *gWorldp, 0.0);  	if (mVO && mVO->mDrawable.notNull())  	{ @@ -615,11 +609,19 @@ BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable)  	{  		LLVolumeParams volume_params = volume->getVolume()->getParams();  		volume->setVolume(volume_params, 0); +		mUpdated = FALSE;  	}  	volume->updateRelativeXform();  	doFlexibleUpdate(); -	if (!mUpdated || volume->mFaceMappingChanged) +	 +	if (volume->mLODChanged || volume->mFaceMappingChanged || +		volume->mVolumeChanged) +	{ +		volume->regenFaces(); +	} + +	if (!mUpdated || volume->mFaceMappingChanged || volume->mVolumeChanged)  	{  		doFlexibleRebuild();  		volume->genBBoxes(isVolumeGlobal()); @@ -629,6 +631,7 @@ BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable)  	volume->mLODChanged = FALSE;  	volume->mFaceMappingChanged = FALSE; +  	// clear UV flag  	drawable->clearState(LLDrawable::UV); diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp index 0b9d836a1a..8bb73e3a9b 100644 --- a/indra/newview/llfloaterinspect.cpp +++ b/indra/newview/llfloaterinspect.cpp @@ -1,220 +1,221 @@ -#include "llviewerprecompiledheaders.h"
 -#include "llfloateravatarinfo.h"
 -#include "llfloaterinspect.h"
 -#include "llfloatertools.h"
 -#include "llcachename.h"
 -#include "llscrolllistctrl.h"
 -#include "llselectmgr.h"
 -#include "lltoolcomp.h"
 -#include "lltoolmgr.h"
 -#include "llviewercontrol.h"
 -#include "llviewerobject.h"
 -#include "llvieweruictrlfactory.h"
 -
 -LLFloaterInspect* LLFloaterInspect::sInstance = NULL;
 -
 -LLFloaterInspect::LLFloaterInspect(void) :
 -	LLFloater("Inspect Object"),
 -	mDirty(FALSE)
 -{
 -	sInstance = this;
 -	gUICtrlFactory->buildFloater(this, "floater_inspect.xml");
 -}
 -
 -LLFloaterInspect::~LLFloaterInspect(void)
 -{
 -	if(!gFloaterTools->getVisible())
 -	{
 -		if(gToolMgr->getBaseTool() == gToolInspect)
 -		{
 -			select_tool(gToolNull);
 -		}
 -		// Switch back to basic toolset
 -		gToolMgr->setCurrentToolset(gBasicToolset);
 -	}
 -	else
 -	{
 -		gFloaterTools->setFocus(TRUE);
 -	}
 -	sInstance = NULL;
 -}
 -
 -BOOL LLFloaterInspect::isVisible()
 -{
 -	return (!!sInstance);
 -}
 -
 -void LLFloaterInspect::show(void* ignored)
 -{
 -	if(sInstance)
 -	{
 -		sInstance->open();
 -	}
 -	else
 -	{
 -		LLFloaterInspect* self = new LLFloaterInspect;
 -		self->open();
 -	}
 -
 -	sInstance->mObjectSelection = gSelectMgr->getSelection();
 -	select_tool(gToolInspect);
 -	sInstance->refresh();
 -}
 -
 -void LLFloaterInspect::onClickCreatorProfile(void* ctrl)
 -{
 -	if(sInstance->mObjectList->getAllSelected().size() == 0) return;
 -	LLSelectNode* obj = sInstance->mObjectSelection->getFirstNode();
 -	LLUUID obj_id, creator_id;
 -	obj_id = sInstance->mObjectList->getFirstSelected()->getUUID();
 -	while(obj)
 -	{
 -		if(obj_id == obj->getObject()->getID())
 -		{
 -			creator_id = obj->mPermissions->getCreator();
 -			break;
 -		}
 -		obj = sInstance->mObjectSelection->getNextNode();
 -	}
 -	if(obj)
 -	{
 -		LLFloaterAvatarInfo::showFromDirectory(creator_id);
 -	}
 -}
 -
 -void LLFloaterInspect::onClickOwnerProfile(void* ctrl)
 -{
 -	if(sInstance->mObjectList->getAllSelected().size() == 0) return;
 -	LLSelectNode* obj = sInstance->mObjectSelection->getFirstNode();
 -	LLUUID obj_id, owner_id;
 -	obj_id = sInstance->mObjectList->getFirstSelected()->getUUID();
 -	while(obj)
 -	{
 -		if(obj_id == obj->getObject()->getID())
 -		{
 -			owner_id = obj->mPermissions->getOwner();
 -			break;
 -		}
 -		obj = sInstance->mObjectSelection->getNextNode();
 -	}
 -	if(obj)
 -	{
 -		LLFloaterAvatarInfo::showFromDirectory(owner_id);
 -	}
 -}
 -
 -BOOL LLFloaterInspect::postBuild()
 -{
 -	mObjectList = LLUICtrlFactory::getScrollListByName(this, "object_list");
 -	childSetAction("button owner",onClickOwnerProfile, this);
 -	childSetAction("button creator",onClickCreatorProfile, this);
 -	childSetCommitCallback("object_list", onSelectObject);
 -	return TRUE;
 -}
 -
 -void LLFloaterInspect::onSelectObject(LLUICtrl* ctrl, void* user_data)
 -{
 -	if(LLFloaterInspect::getSelectedUUID() != LLUUID::null)
 -	{
 -		sInstance->childSetEnabled("button owner", true);
 -		sInstance->childSetEnabled("button creator", true);
 -	}
 -}
 -
 -LLUUID LLFloaterInspect::getSelectedUUID()
 -{
 -	if(sInstance)
 -	{
 -		if(sInstance->mObjectList->getAllSelected().size() > 0) return sInstance->mObjectList->getFirstSelected()->getUUID();
 -	}
 -	return LLUUID::null;
 -}
 -
 -void LLFloaterInspect::refresh()
 -{
 -	LLUUID creator_id;
 -	LLString creator_name;
 -	S32 pos = mObjectList->getScrollPos();
 -	childSetEnabled("button owner", false);
 -	childSetEnabled("button creator", false);
 -	LLUUID selected_uuid;
 -	S32 selected_index = mObjectList->getFirstSelectedIndex();
 -	if(selected_index > -1) selected_uuid = mObjectList->getFirstSelected()->getUUID();
 -	mObjectList->operateOnAll(LLScrollListCtrl::OP_DELETE);
 -	//List all transient objects, then all linked objects
 -	LLSelectNode* obj = mObjectSelection->getFirstNode();
 -	LLSD row;
 -	while(obj)
 -	{
 -		char owner_first_name[MAX_STRING], owner_last_name[MAX_STRING];
 -		char creator_first_name[MAX_STRING], creator_last_name[MAX_STRING];
 -		char time[MAX_STRING];
 -		std::ostringstream owner_name, creator_name, date;
 -		time_t timestamp = (time_t) (obj->mCreationDate/1000000);
 -		LLString::copy(time, ctime(×tamp), MAX_STRING);
 -		time[24] = '\0';
 -		date << obj->mCreationDate;
 -		gCacheName->getName(obj->mPermissions->getOwner(), owner_first_name, owner_last_name);
 -		owner_name << owner_first_name << " " << owner_last_name;
 -		gCacheName->getName(obj->mPermissions->getCreator(), creator_first_name, creator_last_name);
 -		creator_name << creator_first_name << " " << creator_last_name;
 -		row["id"] = obj->getObject()->getID();
 -		row["columns"][0]["column"] = "object_name";
 -		row["columns"][0]["type"] = "text";
 -		// make sure we're either at the top of the link chain
 -		// or top of the editable chain, for attachments
 -		if(!(obj->getObject()->isRoot() || obj->getObject()->isRootEdit()))
 -		{
 -			row["columns"][0]["value"] = LLString("   ") + obj->mName;
 -		}
 -		else
 -		{
 -			row["columns"][0]["value"] = obj->mName;
 -		}
 -		row["columns"][1]["column"] = "owner_name";
 -		row["columns"][1]["type"] = "text";
 -		row["columns"][1]["value"] = owner_name.str().c_str();
 -		row["columns"][2]["column"] = "creator_name";
 -		row["columns"][2]["type"] = "text";
 -		row["columns"][2]["value"] = creator_name.str().c_str();
 -		row["columns"][3]["column"] = "creation_date";
 -		row["columns"][3]["type"] = "text";
 -		row["columns"][3]["value"] = time;
 -		mObjectList->addElement(row, ADD_TOP);
 -		obj = mObjectSelection->getNextNode();
 -	}
 -	if(selected_index > -1 && mObjectList->getItemIndex(selected_uuid) == selected_index)
 -	{
 -		mObjectList->selectNthItem(selected_index);
 -	}
 -	else
 -	{
 -		mObjectList->selectNthItem(0);
 -	}
 -	onSelectObject(this, NULL);
 -	mObjectList->setScrollPos(pos);
 -}
 -
 -void LLFloaterInspect::onFocusReceived()
 -{
 -	select_tool(gToolInspect);
 -}
 -
 -void LLFloaterInspect::dirty()
 -{
 -	if(sInstance)
 -	{
 -		sInstance->setDirty();
 -	}
 -}
 -
 -void LLFloaterInspect::draw()
 -{
 -	if (mDirty)
 -	{
 -		refresh();
 -		mDirty = FALSE;
 -	}
 -
 -	LLFloater::draw();
 -}
\ No newline at end of file +#include "llviewerprecompiledheaders.h" +#include "llfloateravatarinfo.h" +#include "llfloaterinspect.h" +#include "llfloatertools.h" +#include "llcachename.h" +#include "llscrolllistctrl.h" +#include "llselectmgr.h" +#include "lltoolcomp.h" +#include "lltoolmgr.h" +#include "llviewercontrol.h" +#include "llviewerobject.h" +#include "llvieweruictrlfactory.h" + +LLFloaterInspect* LLFloaterInspect::sInstance = NULL; + +LLFloaterInspect::LLFloaterInspect(void) : +	LLFloater("Inspect Object"), +	mDirty(FALSE) +{ +	sInstance = this; +	gUICtrlFactory->buildFloater(this, "floater_inspect.xml"); +} + +LLFloaterInspect::~LLFloaterInspect(void) +{ +	if(!gFloaterTools->getVisible()) +	{ +		if(gToolMgr->getBaseTool() == gToolInspect) +		{ +			select_tool(gToolNull); +		} +		// Switch back to basic toolset +		gToolMgr->setCurrentToolset(gBasicToolset); +	} +	else +	{ +		gFloaterTools->setFocus(TRUE); +	} +	sInstance = NULL; +} + +BOOL LLFloaterInspect::isVisible() +{ +	return (!!sInstance); +} + +void LLFloaterInspect::show(void* ignored) +{ +	if(sInstance) +	{ +		sInstance->open(); +	} +	else +	{ +		LLFloaterInspect* self = new LLFloaterInspect; +		self->open(); +	} + +	sInstance->mObjectSelection = gSelectMgr->getSelection(); +	select_tool(gToolInspect); +	sInstance->refresh(); +} + +void LLFloaterInspect::onClickCreatorProfile(void* ctrl) +{ +	if(sInstance->mObjectList->getAllSelected().size() == 0) return; +	LLSelectNode* obj = sInstance->mObjectSelection->getFirstNode(); +	LLUUID obj_id, creator_id; +	obj_id = sInstance->mObjectList->getFirstSelected()->getUUID(); +	while(obj) +	{ +		if(obj_id == obj->getObject()->getID()) +		{ +			creator_id = obj->mPermissions->getCreator(); +			break; +		} +		obj = sInstance->mObjectSelection->getNextNode(); +	} +	if(obj) +	{ +		LLFloaterAvatarInfo::showFromDirectory(creator_id); +	} +} + +void LLFloaterInspect::onClickOwnerProfile(void* ctrl) +{ +	if(sInstance->mObjectList->getAllSelected().size() == 0) return; +	LLSelectNode* obj = sInstance->mObjectSelection->getFirstNode(); +	LLUUID obj_id, owner_id; +	obj_id = sInstance->mObjectList->getFirstSelected()->getUUID(); +	while(obj) +	{ +		if(obj_id == obj->getObject()->getID()) +		{ +			owner_id = obj->mPermissions->getOwner(); +			break; +		} +		obj = sInstance->mObjectSelection->getNextNode(); +	} +	if(obj) +	{ +		LLFloaterAvatarInfo::showFromDirectory(owner_id); +	} +} + +BOOL LLFloaterInspect::postBuild() +{ +	mObjectList = LLUICtrlFactory::getScrollListByName(this, "object_list"); +	childSetAction("button owner",onClickOwnerProfile, this); +	childSetAction("button creator",onClickCreatorProfile, this); +	childSetCommitCallback("object_list", onSelectObject); +	return TRUE; +} + +void LLFloaterInspect::onSelectObject(LLUICtrl* ctrl, void* user_data) +{ +	if(LLFloaterInspect::getSelectedUUID() != LLUUID::null) +	{ +		sInstance->childSetEnabled("button owner", true); +		sInstance->childSetEnabled("button creator", true); +	} +} + +LLUUID LLFloaterInspect::getSelectedUUID() +{ +	if(sInstance) +	{ +		if(sInstance->mObjectList->getAllSelected().size() > 0) return sInstance->mObjectList->getFirstSelected()->getUUID(); +	} +	return LLUUID::null; +} + +void LLFloaterInspect::refresh() +{ +	LLUUID creator_id; +	LLString creator_name; +	S32 pos = mObjectList->getScrollPos(); +	childSetEnabled("button owner", false); +	childSetEnabled("button creator", false); +	LLUUID selected_uuid; +	S32 selected_index = mObjectList->getFirstSelectedIndex(); +	if(selected_index > -1) selected_uuid = mObjectList->getFirstSelected()->getUUID(); +	mObjectList->operateOnAll(LLScrollListCtrl::OP_DELETE); +	//List all transient objects, then all linked objects +	LLSelectNode* obj = mObjectSelection->getFirstNode(); +	LLSD row; +	while(obj) +	{ +		char owner_first_name[MAX_STRING], owner_last_name[MAX_STRING]; +		char creator_first_name[MAX_STRING], creator_last_name[MAX_STRING]; +		char time[MAX_STRING]; +		std::ostringstream owner_name, creator_name, date; +		time_t timestamp = (time_t) (obj->mCreationDate/1000000); +		LLString::copy(time, ctime(×tamp), MAX_STRING); +		time[24] = '\0'; +		date << obj->mCreationDate; +		gCacheName->getName(obj->mPermissions->getOwner(), owner_first_name, owner_last_name); +		owner_name << owner_first_name << " " << owner_last_name; +		gCacheName->getName(obj->mPermissions->getCreator(), creator_first_name, creator_last_name); +		creator_name << creator_first_name << " " << creator_last_name; +		row["id"] = obj->getObject()->getID(); +		row["columns"][0]["column"] = "object_name"; +		row["columns"][0]["type"] = "text"; +		// make sure we're either at the top of the link chain +		// or top of the editable chain, for attachments +		if(!(obj->getObject()->isRoot() || obj->getObject()->isRootEdit())) +		{ +			row["columns"][0]["value"] = LLString("   ") + obj->mName; +		} +		else +		{ +			row["columns"][0]["value"] = obj->mName; +		} +		row["columns"][1]["column"] = "owner_name"; +		row["columns"][1]["type"] = "text"; +		row["columns"][1]["value"] = owner_name.str().c_str(); +		row["columns"][2]["column"] = "creator_name"; +		row["columns"][2]["type"] = "text"; +		row["columns"][2]["value"] = creator_name.str().c_str(); +		row["columns"][3]["column"] = "creation_date"; +		row["columns"][3]["type"] = "text"; +		row["columns"][3]["value"] = time; +		mObjectList->addElement(row, ADD_TOP); +		obj = mObjectSelection->getNextNode(); +	} +	if(selected_index > -1 && mObjectList->getItemIndex(selected_uuid) == selected_index) +	{ +		mObjectList->selectNthItem(selected_index); +	} +	else +	{ +		mObjectList->selectNthItem(0); +	} +	onSelectObject(this, NULL); +	mObjectList->setScrollPos(pos); +} + +void LLFloaterInspect::onFocusReceived() +{ +	select_tool(gToolInspect); +} + +void LLFloaterInspect::dirty() +{ +	if(sInstance) +	{ +		sInstance->setDirty(); +	} +} + +void LLFloaterInspect::draw() +{ +	if (mDirty) +	{ +		refresh(); +		mDirty = FALSE; +	} + +	LLFloater::draw(); +} + diff --git a/indra/newview/llfloaterinspect.h b/indra/newview/llfloaterinspect.h index 6a3f494978..d221879d0e 100644 --- a/indra/newview/llfloaterinspect.h +++ b/indra/newview/llfloaterinspect.h @@ -1,50 +1,50 @@ -/** 
 -* @file llfloaterfriends.h
 -* @author Cube
 -* @date 2006-12-16
 -* @brief Declaration of class for displaying object attributes
 -*
 -* Copyright (c) 2005-$CurrentYear$, Linden Research, Inc.
 -* $License$
 -*/
 -
 -#ifndef LL_LLFLOATERINSPECT_H
 -#define LL_LLFLOATERINSPECT_H
 -
 -#include "llfloater.h"
 -
 -//class LLTool;
 -class LLObjectSelection;
 -class LLScrollListCtrl;
 -class LLUICtrl;
 -
 -class LLFloaterInspect : public LLFloater
 -{
 -public:
 -	virtual ~LLFloaterInspect(void);
 -	static void show(void* ignored = NULL);
 -	virtual BOOL postBuild();
 -	static void dirty();
 -	static LLUUID getSelectedUUID();
 -	virtual void draw();
 -	virtual void refresh();
 -	static BOOL isVisible();
 -	virtual void onFocusReceived();
 -	static void onClickCreatorProfile(void* ctrl);
 -	static void onClickOwnerProfile(void* ctrl);
 -	static void onSelectObject(LLUICtrl* ctrl, void* user_data);
 -	LLScrollListCtrl* mObjectList;
 -protected:
 -	// protected members
 -	LLFloaterInspect();
 -	void setDirty() { mDirty = TRUE; }
 -	bool mDirty;
 -
 -private:
 -	// static data
 -	static LLFloaterInspect* sInstance;
 -
 -	LLHandle<LLObjectSelection> mObjectSelection;
 -};
 -
 -#endif //LL_LLFLOATERINSPECT_H
\ No newline at end of file +/**  +* @file llfloaterfriends.h +* @author Cube +* @date 2006-12-16 +* @brief Declaration of class for displaying object attributes +* +* Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. +* $License$ +*/ + +#ifndef LL_LLFLOATERINSPECT_H +#define LL_LLFLOATERINSPECT_H + +#include "llfloater.h" + +//class LLTool; +class LLObjectSelection; +class LLScrollListCtrl; +class LLUICtrl; + +class LLFloaterInspect : public LLFloater +{ +public: +	virtual ~LLFloaterInspect(void); +	static void show(void* ignored = NULL); +	virtual BOOL postBuild(); +	static void dirty(); +	static LLUUID getSelectedUUID(); +	virtual void draw(); +	virtual void refresh(); +	static BOOL isVisible(); +	virtual void onFocusReceived(); +	static void onClickCreatorProfile(void* ctrl); +	static void onClickOwnerProfile(void* ctrl); +	static void onSelectObject(LLUICtrl* ctrl, void* user_data); +	LLScrollListCtrl* mObjectList; +protected: +	// protected members +	LLFloaterInspect(); +	void setDirty() { mDirty = TRUE; } +	bool mDirty; + +private: +	// static data +	static LLFloaterInspect* sInstance; + +	LLHandle<LLObjectSelection> mObjectSelection; +}; + +#endif //LL_LLFLOATERINSPECT_H diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 6f698d2734..3492f4fff8 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -346,8 +346,8 @@ void* LLFloaterLand::createPanelLandBan(void* data)  LLPanelLandGeneral::LLPanelLandGeneral(LLParcelSelectionHandle& parcel)  :	LLPanel("land_general_panel"), -	mParcel(parcel), -	mUncheckedSell(FALSE) +	mUncheckedSell(FALSE), +	mParcel(parcel)  {  } diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp index f6fcda29a3..f82978c5fc 100644 --- a/indra/newview/llfloaterpostcard.cpp +++ b/indra/newview/llfloaterpostcard.cpp @@ -51,8 +51,8 @@ LLLinkedList<LLFloaterPostcard> LLFloaterPostcard::sInstances;  LLFloaterPostcard::LLFloaterPostcard(LLImageJPEG* jpeg, LLImageGL *img, const LLVector2& img_scale, const LLVector3d& pos_taken_global)  :	LLFloater("Postcard Floater"), -	mViewerImage(img),  	mJPEGImage(jpeg), +	mViewerImage(img),  	mImageScale(img_scale),  	mPosTakenGlobal(pos_taken_global)  { diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp index 793884e008..feeedc5190 100644 --- a/indra/newview/llfloaterproperties.cpp +++ b/indra/newview/llfloaterproperties.cpp @@ -214,7 +214,7 @@ void LLFloaterProperties::refresh()  			"RadioSaleType",  			"EditPrice"  		}; -		for(int t=0;t<sizeof(enableNames)/sizeof(char*);t++) +		for(size_t t=0; t<sizeof(enableNames)/sizeof(char*); ++t)  		{  			childSetEnabled(enableNames[t],false);  		} @@ -225,7 +225,7 @@ void LLFloaterProperties::refresh()  			"EveryoneMaskDebug",  			"NextMaskDebug"  		}; -		for(int t=0;t<sizeof(hideNames)/sizeof(char*);t++) +		for(size_t t=0; t<sizeof(hideNames)/sizeof(char*); ++t)  		{  			childSetVisible(hideNames[t],false);  		} diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 34eb841568..63b1734642 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -245,7 +245,7 @@ BOOL	LLFloaterTools::postBuild()  			&LLToolPlacerPanel::sTriangleTorus,  			&LLToolPlacerPanel::sTree,  			&LLToolPlacerPanel::sGrass}; -	for(int t=0;t<sizeof(toolNames)/sizeof(toolNames[0]);t++) +	for(size_t t=0; t<sizeof(toolNames)/sizeof(toolNames[0]); ++t)  	{  		LLButton *found = LLViewerUICtrlFactory::getButtonByName(this,toolNames[t]);  		if(found) diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index 33a675b59e..00108650ef 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -843,7 +843,7 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)  		}  	} -	if (group_datap->mMembers.size() ==  group_datap->mMemberCount) +	if (group_datap->mMembers.size() ==  (U32)group_datap->mMemberCount)  	{  		group_datap->mMemberDataComplete = TRUE;  		group_datap->mMemberRequestID.setNull(); @@ -979,7 +979,7 @@ void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data)  		group_data->mRoles[role_id] = rd;  	} -	if (group_data->mRoles.size() == group_data->mRoleCount) +	if (group_data->mRoles.size() == (U32)group_data->mRoleCount)  	{  		group_data->mRoleDataComplete = TRUE;  		group_data->mRoleDataRequestID.setNull(); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index f090cea5f2..4de746fd4f 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2174,6 +2174,8 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,  		case LLAssetType::AT_CATEGORY:  			is_movable = ( LLAssetType::AT_NONE == ((LLInventoryCategory*)inv_item)->getPreferredType() );  			break; +		default: +			break;  		}  		LLUUID trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH); @@ -2190,6 +2192,8 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,  			case LLAssetType::AT_OBJECT:  				is_movable = !avatar->isWearingAttachment(inv_item->getUUID());  				break; +			default: +				break;  			}  		} @@ -2759,6 +2763,8 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop,  				}  				break;  			} +		default: +			break;  		}  	}  	return rv; @@ -3407,8 +3413,8 @@ struct LLFoundData  				LLAssetType::EType asset_type) :  		mItemID(item_id),  		mAssetID(asset_id), -		mAssetType(asset_type),  		mName(name), +		mAssetType(asset_type),  		mWearable( NULL ) {}  	LLUUID mItemID; diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index 93ae74db22..9e26d951bc 100644 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -1120,6 +1120,8 @@ void LLManipTranslate::renderSnapGuides()  			inner_color.setVec(1,1,0,line_alpha);  			mManipPart = LL_XY_PLANE;  			break; +		default: +			break;  		}  		highlightIntersection(normal, selection_center, grid_rotation, inner_color); diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 810e026d2a..3ec14b6117 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -512,25 +512,25 @@ BOOL LLPanelAvatarPicks::postBuild(void)  	return TRUE;  } -BOOL	LLPanelAvatarAdvanced::postBuild() +BOOL LLPanelAvatarAdvanced::postBuild()  { -	for( S32 i = 0; i < kArraySize(mWantToCheck); i++ ) -		mWantToCheck[i] = NULL; -	for( S32 i = 0; i < kArraySize(mSkillsCheck); i++ ) -		mSkillsCheck[i] = NULL; +	for(size_t ii = 0; ii < kArraySize(mWantToCheck); ++ii) +		mWantToCheck[ii] = NULL; +	for(size_t ii = 0; ii < kArraySize(mSkillsCheck); ++ii) +		mSkillsCheck[ii] = NULL;  	mWantToCount = (8>kArraySize(mWantToCheck))?kArraySize(mWantToCheck):8; -	for(int t=0;t < mWantToCount ;t++) +	for(S32 tt=0; tt < mWantToCount; ++tt)  	{	 -		LLString ctlname = llformat("chk%d",t); -		mWantToCheck[t] = LLUICtrlFactory::getCheckBoxByName(this,ctlname); +		LLString ctlname = llformat("chk%d", tt); +		mWantToCheck[tt] = LLUICtrlFactory::getCheckBoxByName(this,ctlname);  	}	  	mSkillsCount = (6>kArraySize(mSkillsCheck))?kArraySize(mSkillsCheck):6; -	for(int t=0;t<mSkillsCount;t++) +	for(S32 tt=0; tt < mSkillsCount; ++tt)  	{  		//Find the Skills checkboxes and save off thier controls -		LLString ctlname = llformat("schk%d",t); -		mSkillsCheck[t] = LLUICtrlFactory::getCheckBoxByName(this,ctlname); +		LLString ctlname = llformat("schk%d",tt); +		mSkillsCheck[tt] = LLUICtrlFactory::getCheckBoxByName(this,ctlname);  	}  	mWantToEdit = LLUICtrlFactory::getLineEditorByName(this,"want_to_edit"); diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index 2c6cbb9c08..9adc737aab 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -83,16 +83,17 @@ LLPanelClassified::LLPanelClassified(BOOL in_finder)  	mDataRequested(FALSE),  	mEnableCommit(FALSE),  	mPaidFor(FALSE), -	mParcelID(),      mPosGlobal(),      mSnapshotCtrl(NULL),      mNameEditor(NULL), -    mLocationEditor(NULL),      mDescEditor(NULL), +    mLocationEditor(NULL), +	mCategoryCombo(NULL), +	mUpdateBtn(NULL),      mTeleportBtn(NULL),      mMapBtn(NULL), -    //mLandmarkBtn(NULL), -    //mEnabledCheck(NULL), +	mProfileBtn(NULL), +	mInfoText(NULL),  	mMatureCheck(NULL),  	mAutoRenewCheck(NULL),      mSetBtn(NULL), diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index 9ad5855b8e..121dc4c67e 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -132,8 +132,8 @@ LLPanelGroup::LLPanelGroup(const std::string& filename,  	mCurrentTab( NULL ),  	mRequestedTab( NULL ),  	mTabContainer( NULL ), -	mForceClose( FALSE ),  	mIgnoreTransition( FALSE ), +	mForceClose( FALSE ),  	mInitialTab(initial_tab_selected),  	mAllowEdit( TRUE ),  	mShowingNotifyDialog( FALSE ) diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 0e295df94a..bda962ca56 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -1101,7 +1101,10 @@ void LLPanelGroupMembersSubTab::handleMemberSelect()  				check->setCommitCallback(onRoleCheck);  				check->setCallbackUserData(this);  				check->set( count > 0 ); -				check->setTentative(0 != count && selected_members.size() != count); +				check->setTentative( +					(0 != count) +					&& (selected_members.size() != +						(std::vector<LLUUID>::size_type)count));  				//NOTE: as of right now a user can break the group  				//by removing himself from a role if he is the @@ -1996,7 +1999,7 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc)  		mRolesList->sortByColumn("name", TRUE); -		if ( (gdatap->mRoles.size() < MAX_ROLES) +		if ( (gdatap->mRoles.size() < (U32)MAX_ROLES)  			&& gAgent.hasPowerInGroup(mGroupID, GP_ROLE_CREATE) )  		{  			mCreateRoleButton->setEnabled(TRUE); diff --git a/indra/newview/llpreview.cpp b/indra/newview/llpreview.cpp index c5e589529c..91df61ca91 100644 --- a/indra/newview/llpreview.cpp +++ b/indra/newview/llpreview.cpp @@ -513,4 +513,4 @@ void LLMultiPreview::setAutoOpenInstance(LLMultiPreview* previewp, const LLUUID&  	{  		sAutoOpenPreviewHandles[id] = previewp->getHandle();  	} -}
\ No newline at end of file +} diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 950ed61b25..3eddc04259 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -5770,8 +5770,8 @@ BOOL LLSelectMgr::canSelectObject(LLViewerObject* object)  LLObjectSelection::LLObjectSelection() :   	std::list<LLSelectNode*>(),   	LLRefCount(), -	mCurrentTE(-1),  	mCurrentNode(end()), +	mCurrentTE(-1),  	mSelectType(SELECT_TYPE_WORLD)  {  } diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 739d30bfe6..62903011cf 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -289,6 +289,7 @@ void LLSpatialGroup::validateDrawMap()  void LLSpatialGroup::makeStatic()  { +#if !LL_DARWIN  	if (isState(GEOM_DIRTY | ALPHA_DIRTY))  	{  		return; @@ -309,6 +310,7 @@ void LLSpatialGroup::makeStatic()  		mBuilt = 1.f;  	} +#endif  }  BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) @@ -318,7 +320,12 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate)  	drawablep->updateSpatialExtents();  	validate_drawable(drawablep); -	if (mOctreeNode->isInside(drawablep) && mOctreeNode->contains(drawablep)) +	OctreeNode* parent = mOctreeNode->getOctParent(); +	 +	if (mOctreeNode->isInside(drawablep->getPositionGroup()) &&  +		(mOctreeNode->contains(drawablep) || +		 (drawablep->getBinRadius() > mOctreeNode->getSize().mdV[0] && +				parent && parent->getElementCount() >= LL_OCTREE_MAX_CAPACITY)))  	{  		unbound();  		setState(OBJECT_DIRTY); @@ -697,14 +704,21 @@ void LLSpatialGroup::clearState(U32 state, S32 mode)  //		Octree Listener Implementation  //====================================== -LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) -: mOctreeNode(node), mState(0), mSpatialPartition(part), mVertexBuffer(NULL),  -  mDistance(0.f), mLastUpdateDistance(-1.f),  -  mViewAngle(0.f), mLastUpdateViewAngle(-1.f),  -  mDepth(0.f), mBuilt(0.f), -  mLastUpdateTime(gFrameTimeSeconds), mLastRenderTime(gFrameTimeSeconds), -  mLastAddTime(gFrameTimeSeconds), -  mBufferUsage(GL_STATIC_DRAW_ARB) +LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : +	mState(0), +	mBuilt(0.f), +	mOctreeNode(node), +	mSpatialPartition(part), +	mVertexBuffer(NULL),  +	mBufferUsage(GL_STATIC_DRAW_ARB), +	mDistance(0.f), +	mDepth(0.f), +	mLastUpdateDistance(-1.f),  +	mLastUpdateTime(gFrameTimeSeconds), +	mLastAddTime(gFrameTimeSeconds), +	mLastRenderTime(gFrameTimeSeconds), +	mViewAngle(0.f), +	mLastUpdateViewAngle(-1.f)  {  	LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); @@ -898,6 +912,31 @@ void LLSpatialGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNo  	unbound();  } +void LLSpatialGroup::destroyGL()  +{ +	setState(LLSpatialGroup::GEOM_DIRTY |  +					LLSpatialGroup::OCCLUSION_DIRTY | +					LLSpatialGroup::IMAGE_DIRTY); +	mLastUpdateTime = gFrameTimeSeconds; +	mVertexBuffer = NULL; +	mBufferMap.clear(); + +	mOcclusionVerts = NULL; +	mReflectionMap = NULL; +	clearDrawMap(); + +	for (LLSpatialGroup::element_iter i = getData().begin(); i != getData().end(); ++i) +	{ +		LLDrawable* drawable = *i; +		for (S32 j = 0; j < drawable->getNumFaces(); j++) +		{ +			LLFace* facep = drawable->getFace(j); +			facep->mVertexBuffer = NULL; +			facep->mLastVertexBuffer = NULL; +		} +	} +} +  BOOL LLSpatialGroup::rebound()  {  	if (!isState(DIRTY)) @@ -1423,28 +1462,11 @@ public:  	virtual void visit(const LLOctreeState<LLDrawable>* state)  	{  		LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); +		group->destroyGL(); -		group->setState(LLSpatialGroup::GEOM_DIRTY |  -						LLSpatialGroup::OCCLUSION_DIRTY | -						LLSpatialGroup::IMAGE_DIRTY); -		group->mLastUpdateTime = gFrameTimeSeconds; -		group->mVertexBuffer = NULL; -		group->mBufferMap.clear(); - -		group->mOcclusionVerts = NULL; -		group->mReflectionMap = NULL; -		group->clearDrawMap(); -	  		for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)  		{  			LLDrawable* drawable = *i; -			for (S32 j = 0; j < drawable->getNumFaces(); j++) -			{ -				LLFace* facep = drawable->getFace(j); -				facep->mVertexBuffer = NULL; -				facep->mLastVertexBuffer = NULL; -			} -  			if (drawable->getVObj() && !group->mSpatialPartition->mRenderByGroup)  			{  				gPipeline.markRebuild(drawable, LLDrawable::REBUILD_ALL, TRUE); @@ -1458,6 +1480,7 @@ public:  		}  	}  }; +  void LLSpatialPartition::restoreGL()  {  	LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); @@ -1597,7 +1620,7 @@ void LLSpatialPartition::processGeometry(LLCamera* camera)  	U32 process_count = 8;  	LLSpatialGroup* root = (LLSpatialGroup*) mOctree->getListener(0); -	if (!root->isState(LLSpatialGroup::IN_GEOMETRY_QUEUE)) +	if (mUpdateQueue.empty())  	{  		root->setState(LLSpatialGroup::IN_GEOMETRY_QUEUE);  		mUpdateQueue.push(root); @@ -1628,18 +1651,19 @@ void LLSpatialPartition::processGeometry(LLCamera* camera)  			}  		} -		if (!group->isDead() &&  -			!group->isVisible() &&  -			!group->isState(LLSpatialGroup::OBJECT_DIRTY) &&  -			group->mBufferUsage != GL_STREAM_DRAW_ARB) +		if (!group->isDead() && !group->isVisible())  		{ -			group->updateDistance(*camera); -			for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) +			if (!group->isState(LLSpatialGroup::OBJECT_DIRTY) &&  +				group->mBufferUsage != GL_STREAM_DRAW_ARB)  			{ -				LLDrawable* drawablep = *i; -				if (!drawablep->isDead()) +				group->updateDistance(*camera); +				for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)  				{ -					drawablep->updateDistance(*camera); +					LLDrawable* drawablep = *i; +					if (!drawablep->isDead()) +					{ +						drawablep->updateDistance(*camera); +					}  				}  			}  		} @@ -1703,7 +1727,7 @@ void LLSpatialPartition::processImagery(LLCamera* camera)  			}  			gPipeline.generateReflectionMap(gPipeline.mCubeBuffer, cube_cam, 128); -			gPipeline.blurReflectionMap(gPipeline.mCubeBuffer, cube_map, 32); +			gPipeline.blurReflectionMap(gPipeline.mCubeBuffer, cube_map, 64);  			group->mReflectionMap = cube_map;  			group->setState(LLSpatialGroup::GEOM_DIRTY);  			gPipeline.markRebuild(group); @@ -2821,11 +2845,19 @@ LLDrawable*	LLSpatialPartition::pickDrawable(const LLVector3& start, const LLVec  LLDrawInfo::LLDrawInfo(U32 start, U32 end, U32 count, U32 offset,   					   LLViewerImage* texture, LLVertexBuffer* buffer,  					   BOOL fullbright, U8 bump, BOOL particle, F32 part_size) -: mStart(start), mEnd(end), mCount(count), mOffset(offset),  -  mTexture(texture), mVertexBuffer(buffer), -  mFullbright(fullbright), mBump(bump), -  mParticle(particle), mPartSize(part_size), -  mVSize(0.f), mTextureMatrix(NULL) +: +	mVertexBuffer(buffer), +	mTexture(texture), +	mTextureMatrix(NULL), +	mStart(start), +	mEnd(end), +	mCount(count), +	mOffset(offset),  +	mFullbright(fullbright), +	mBump(bump), +	mParticle(particle), +	mPartSize(part_size), +	mVSize(0.f)  {  } diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index ea0802985e..6a795d4c6c 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -173,6 +173,7 @@ public:  	BOOL boundObjects(BOOL empty, LLVector3& newMin, LLVector3& newMax);  	void unbound();  	BOOL rebound(); +	void destroyGL();  	void updateDistance(LLCamera& camera);  	BOOL changeLOD(); @@ -273,6 +274,8 @@ public:  	BOOL isVolatile() const { return mVolatile; }  	virtual LLSpatialBridge* asBridge() { return NULL; } +	virtual BOOL isBridge() { return asBridge() != NULL; } +  	S32 getObjects(const LLVector3& pos,  F32 rad,  LLDrawable::drawable_set_t &results );  	S32 getLights(const LLVector3& pos,  F32 rad,  LLDrawable::drawable_set_t &results ); diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 13efadf213..cb846a43fe 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -1,1365 +1,1365 @@ -/** 
 - * @file texturecache.cpp
 - * @brief Object which handles local texture caching
 - *
 - * Copyright (c) 2000-$CurrentYear$, Linden Research, Inc.
 - * $License$
 - */
 -
 -#include "llviewerprecompiledheaders.h"
 -
 -#include "lltexturecache.h"
 -
 -#include "llapr.h"
 -#include "lldir.h"
 -#include "llimage.h"
 -#include "lllfsthread.h"
 -#include "llviewercontrol.h"
 -
 -#define USE_LFS_READ 0
 -#define USE_LFS_WRITE 0
 -
 -// Note: first 4 bytes store file size, rest is j2c data
 -const S32 TEXTURE_CACHE_ENTRY_SIZE = FIRST_PACKET_SIZE; //1024;
 -
 -class LLTextureCacheWorker : public LLWorkerClass
 -{
 -	friend class LLTextureCache;
 -
 -private:
 -	enum e_state
 -	{
 -		INIT = 0,
 -		LOCAL = 1,
 -		CACHE = 2,
 -		HEADER = 3,
 -		BODY = 4
 -	};
 -
 -	class ReadResponder : public LLLFSThread::Responder
 -	{
 -	public:
 -		ReadResponder(LLTextureCache* cache, handle_t handle) : mCache(cache), mHandle(handle) {}
 -		~ReadResponder() {}
 -		void completed(S32 bytes)
 -		{
 -			mCache->lockWorkers();
 -			LLTextureCacheWorker* reader = mCache->getReader(mHandle);
 -			if (reader) reader->ioComplete(bytes);
 -			mCache->unlockWorkers();
 -		}
 -		LLTextureCache* mCache;
 -		LLTextureCacheWorker::handle_t mHandle;
 -	};
 -
 -	class WriteResponder : public LLLFSThread::Responder
 -	{
 -	public:
 -		WriteResponder(LLTextureCache* cache, handle_t handle) : mCache(cache), mHandle(handle) {}
 -		~WriteResponder() {}
 -		void completed(S32 bytes)
 -		{
 -			mCache->lockWorkers();
 -			LLTextureCacheWorker* writer = mCache->getWriter(mHandle);
 -			if (writer) writer->ioComplete(bytes);
 -			mCache->unlockWorkers();
 -		}
 -		LLTextureCache* mCache;
 -		LLTextureCacheWorker::handle_t mHandle;
 -	};
 -	
 -public:
 -	LLTextureCacheWorker(LLTextureCache* cache, U32 priority, const LLUUID& id,
 -						 U8* data, S32 datasize, S32 offset,
 -						 S32 imagesize, // for writes
 -						 LLTextureCache::Responder* responder)
 -		: LLWorkerClass(cache, "LLTextureCacheWorker"),
 -		  mCache(cache),
 -		  mPriority(priority),
 -		  mID(id),
 -		  mState(INIT),
 -		  mReadData(NULL),
 -		  mWriteData(data),
 -		  mDataSize(datasize),
 -		  mOffset(offset),
 -		  mImageSize(imagesize),
 -		  mImageFormat(IMG_CODEC_J2C),
 -		  mImageLocal(FALSE),
 -		  mResponder(responder),
 -		  mFileHandle(LLLFSThread::nullHandle()),
 -		  mBytesToRead(0),
 -		  mBytesRead(0)
 -	{
 -		mPriority &= LLWorkerThread::PRIORITY_LOWBITS;
 -	}
 -	~LLTextureCacheWorker()
 -	{
 -		llassert_always(!haveWork());
 -		delete[] mReadData;
 -	}
 -
 -	bool doRead();
 -	bool doWrite();
 -	virtual bool doWork(S32 param); // Called from LLWorkerThread::processRequest()
 -
 -	handle_t read() { addWork(0, LLWorkerThread::PRIORITY_HIGH | mPriority); return mRequestHandle; }
 -	handle_t write() { addWork(1, LLWorkerThread::PRIORITY_HIGH | mPriority); return mRequestHandle; }
 -	bool complete() { return checkWork(); }
 -	void ioComplete(S32 bytes)
 -	{
 -		mBytesRead = bytes;
 -		setPriority(LLWorkerThread::PRIORITY_HIGH | mPriority);
 -	}
 -	
 -private:
 -	virtual void startWork(S32 param); // called from addWork() (MAIN THREAD)
 -	virtual void finishWork(S32 param, bool completed); // called from finishRequest() (WORK THREAD)
 -	virtual void endWork(S32 param, bool aborted); // called from doWork() (MAIN THREAD)
 -
 -private:
 -	LLTextureCache* mCache;
 -	U32 mPriority;
 -	LLUUID mID;
 -	e_state mState;
 -	
 -	U8* mReadData;
 -	U8* mWriteData;
 -	S32 mDataSize;
 -	S32 mOffset;
 -	S32 mImageSize;
 -	S32 mImageFormat;
 -	BOOL mImageLocal;
 -	LLPointer<LLTextureCache::Responder> mResponder;
 -	LLLFSThread::handle_t mFileHandle;
 -	S32 mBytesToRead;
 -	LLAtomicS32 mBytesRead;
 -};
 -
 -//virtual
 -void LLTextureCacheWorker::startWork(S32 param)
 -{
 -}
 -
 -bool LLTextureCacheWorker::doRead()
 -{
 -	S32 local_size = 0;
 -	std::string local_filename;
 -	
 -	if (mState == INIT)
 -	{
 -		std::string filename = mCache->getLocalFileName(mID);
 -		local_filename = filename + ".j2c";
 -		local_size = ll_apr_file_size(local_filename, mCache->getFileAPRPool());
 -		if (local_size == 0)
 -		{
 -			local_filename = filename + ".tga";
 -			local_size = ll_apr_file_size(local_filename, mCache->getFileAPRPool());
 -			if (local_size > 0)
 -			{
 -				mImageFormat = IMG_CODEC_TGA;
 -				mDataSize = local_size; // Only a complete .tga file is valid
 -			}
 -		}
 -		if (local_size > 0)
 -		{
 -			mState = LOCAL;
 -		}
 -		else
 -		{
 -			mState = CACHE;
 -		}
 -	}
 -
 -	if (mState == LOCAL)
 -	{
 -#if USE_LFS_READ
 -		if (mFileHandle == LLLFSThread::nullHandle())
 -		{
 -			mImageLocal = TRUE;
 -			mImageSize = local_size;
 -			if (!mDataSize || mDataSize + mOffset > local_size)
 -			{
 -				mDataSize = local_size - mOffset;
 -			}
 -			if (mDataSize <= 0)
 -			{
 -				// no more data to read
 -				mDataSize = 0;
 -				return true;
 -			}
 -			mReadData = new U8[mDataSize];
 -			mBytesRead = -1;
 -			mBytesToRead = mDataSize;
 -			setPriority(LLWorkerThread::PRIORITY_LOW | mPriority);
 -			mFileHandle = LLLFSThread::sLocal->read(local_filename, mReadData, mOffset, mDataSize,
 -													new ReadResponder(mCache, mRequestHandle));
 -			return false;
 -		}
 -		else
 -		{
 -			if (mBytesRead >= 0)
 -			{
 -				if (mBytesRead != mBytesToRead)
 -				{
 -					llwarns << "Error reading file from local cache: " << local_filename
 -							<< " Bytes: " << mDataSize << " Offset: " << mOffset
 -							<< " / " << mDataSize << llendl;
 -					mDataSize = 0; // failed
 -					delete[] mReadData;
 -					mReadData = NULL;
 -				}
 -				return true;
 -			}
 -			else
 -			{
 -				return false;
 -			}
 -		}
 -#else
 -		if (!mDataSize || mDataSize > local_size)
 -		{
 -			mDataSize = local_size;
 -		}
 -		mReadData = new U8[mDataSize];
 -		S32 bytes_read = ll_apr_file_read_ex(local_filename, mCache->getFileAPRPool(),
 -											 mReadData, mOffset, mDataSize);
 -		if (bytes_read != mDataSize)
 -		{
 -			llwarns << "Error reading file from local cache: " << local_filename
 -					<< " Bytes: " << mDataSize << " Offset: " << mOffset
 -					<< " / " << mDataSize << llendl;
 -			mDataSize = 0;
 -			delete[] mReadData;
 -			mReadData = NULL;
 -		}
 -		else
 -		{
 -			mImageSize = local_size;
 -			mImageLocal = TRUE;
 -		}
 -		return true;
 -#endif
 -	}
 -
 -	S32 idx = -1;
 -	
 -	if (mState == CACHE)
 -	{
 -		llassert_always(mImageSize == 0);
 -		idx = mCache->getHeaderCacheEntry(mID, false, &mImageSize);
 -		if (idx >= 0 && mImageSize > mOffset)
 -		{
 -			llassert_always(mImageSize > 0);
 -			if (!mDataSize || mDataSize > mImageSize)
 -			{
 -				mDataSize = mImageSize;
 -			}
 -			mState = mOffset < TEXTURE_CACHE_ENTRY_SIZE ? HEADER : BODY;
 -		}
 -		else
 -		{
 -			mDataSize = 0; // no data
 -			return true;
 -		}
 -	}
 -
 -	if (mState == HEADER)
 -	{
 -#if USE_LFS_READ
 -		if (mFileHandle == LLLFSThread::nullHandle())
 -		{
 -			llassert_always(idx >= 0);
 -			llassert_always(mOffset < TEXTURE_CACHE_ENTRY_SIZE);
 -			S32 offset = idx * TEXTURE_CACHE_ENTRY_SIZE + mOffset;
 -			S32 size = TEXTURE_CACHE_ENTRY_SIZE - mOffset;
 -			llassert_always(mReadData == NULL);
 -			mReadData = new U8[size];
 -			mBytesRead = -1;
 -			mBytesToRead = size;
 -			setPriority(LLWorkerThread::PRIORITY_LOW | mPriority);
 -			mFileHandle = LLLFSThread::sLocal->read(mCache->mHeaderDataFileName,
 -													mReadData, offset, mBytesToRead,
 -													new ReadResponder(mCache, mRequestHandle));
 -			return false;
 -		}
 -		else
 -		{
 -			if (mBytesRead >= 0)
 -			{
 -				if (mBytesRead != mBytesToRead)
 -				{
 -					llwarns << "LLTextureCacheWorker: "  << mID
 -							<< " incorrect number of bytes read from header: " << mBytesRead
 -							<< " != " << mBytesToRead << llendl;
 -					mDataSize = -1; // failed
 -					return true;
 -				}
 -				if (mDataSize <= TEXTURE_CACHE_ENTRY_SIZE)
 -				{
 -					return true; // done
 -				}
 -				else
 -				{
 -					mFileHandle = LLLFSThread::nullHandle();
 -					mState = BODY;
 -				}
 -			}
 -			else
 -			{
 -				return false;
 -			}
 -		}
 -#else
 -		llassert_always(idx >= 0);
 -		llassert_always(mOffset < TEXTURE_CACHE_ENTRY_SIZE);
 -		S32 offset = idx * TEXTURE_CACHE_ENTRY_SIZE + mOffset;
 -		S32 size = TEXTURE_CACHE_ENTRY_SIZE - mOffset;
 -		mReadData = new U8[size];
 -		S32 bytes_read = ll_apr_file_read_ex(mCache->mHeaderDataFileName, mCache->getFileAPRPool(),
 -											 mReadData, offset, size);
 -		if (bytes_read != size)
 -		{
 -			llwarns << "LLTextureCacheWorker: "  << mID
 -					<< " incorrect number of bytes read from header: " << bytes_read
 -					<< " / " << size << llendl;
 -			mDataSize = -1; // failed
 -			return true;
 -		}
 -		if (mDataSize <= TEXTURE_CACHE_ENTRY_SIZE)
 -		{
 -			return true; // done
 -		}
 -		else
 -		{
 -			mState = BODY;
 -		}
 -#endif
 -	}
 -
 -	if (mState == BODY)
 -	{
 -#if USE_LFS_READ
 -		if (mFileHandle == LLLFSThread::nullHandle())
 -		{
 -			std::string filename = mCache->getTextureFileName(mID);
 -			S32 filesize = ll_apr_file_size(filename, mCache->getFileAPRPool());
 -			if (filesize > mOffset)
 -			{
 -				S32 datasize = TEXTURE_CACHE_ENTRY_SIZE + filesize;
 -				mDataSize = llmin(datasize, mDataSize);
 -				S32 data_offset = TEXTURE_CACHE_ENTRY_SIZE - mOffset;
 -				data_offset = llmax(data_offset, 0);
 -				S32 file_size = mDataSize - data_offset;
 -				S32 file_offset = mOffset - TEXTURE_CACHE_ENTRY_SIZE;
 -				file_offset = llmax(file_offset, 0);
 -
 -				llassert_always(mDataSize > 0);
 -				U8* data = new U8[mDataSize];
 -				if (data_offset > 0)
 -				{
 -					llassert_always(mReadData);
 -					llassert_always(data_offset <= mDataSize);
 -					memcpy(data, mReadData, data_offset);
 -					delete[] mReadData;
 -					mReadData = NULL;
 -				}
 -				llassert_always(mReadData == NULL);
 -				mReadData = data;
 -
 -				mBytesRead = -1;
 -				mBytesToRead = file_size;
 -				setPriority(LLWorkerThread::PRIORITY_LOW | mPriority);
 -				llassert_always(data_offset + mBytesToRead <= mDataSize);
 -				mFileHandle = LLLFSThread::sLocal->read(filename,
 -														mReadData + data_offset, file_offset, mBytesToRead,
 -														new ReadResponder(mCache, mRequestHandle));
 -				return false;
 -			}
 -			else
 -			{
 -				mDataSize = TEXTURE_CACHE_ENTRY_SIZE;
 -				return true; // done
 -			}
 -		}
 -		else
 -		{
 -			if (mBytesRead >= 0)
 -			{
 -				if (mBytesRead != mBytesToRead)
 -				{
 -					llwarns << "LLTextureCacheWorker: "  << mID
 -							<< " incorrect number of bytes read from body: " << mBytesRead
 -							<< " != " << mBytesToRead << llendl;
 -					mDataSize = -1; // failed
 -				}
 -				return true;
 -			}
 -			else
 -			{
 -				return false;
 -			}
 -		}
 -#else
 -		std::string filename = mCache->getTextureFileName(mID);
 -		S32 filesize = ll_apr_file_size(filename, mCache->getFileAPRPool());
 -		S32 bytes_read = 0;
 -		if (filesize > mOffset)
 -		{
 -			S32 datasize = TEXTURE_CACHE_ENTRY_SIZE + filesize;
 -			mDataSize = llmin(datasize, mDataSize);
 -			S32 data_offset = TEXTURE_CACHE_ENTRY_SIZE - mOffset;
 -			data_offset = llmax(data_offset, 0);
 -			S32 file_size = mDataSize - data_offset;
 -			S32 file_offset = mOffset - TEXTURE_CACHE_ENTRY_SIZE;
 -			file_offset = llmax(file_offset, 0);
 -			
 -			U8* data = new U8[mDataSize];
 -			if (data_offset > 0)
 -			{
 -				llassert_always(mReadData);
 -				memcpy(data, mReadData, data_offset);
 -				delete[] mReadData;
 -			}
 -			mReadData = data;
 -			bytes_read = ll_apr_file_read_ex(filename, mCache->getFileAPRPool(),
 -											 mReadData + data_offset,
 -											 file_offset, file_size);
 -			if (bytes_read != file_size)
 -			{
 -				llwarns << "LLTextureCacheWorker: "  << mID
 -						<< " incorrect number of bytes read from body: " << bytes_read
 -						<< " / " << file_size << llendl;
 -				mDataSize = -1; // failed
 -				return true;
 -			}
 -		}
 -		else
 -		{
 -			mDataSize = TEXTURE_CACHE_ENTRY_SIZE;
 -		}
 -		
 -		return true;
 -#endif
 -	}
 -	
 -	return false;
 -}
 -
 -bool LLTextureCacheWorker::doWrite()
 -{
 -	S32 idx = -1;
 -
 -	if (mState == INIT)
 -	{
 -		llassert_always(mOffset == 0); // Currently don't support offsets
 -		mState = CACHE;
 -	}
 -
 -	// No LOCAL state for write()
 -	
 -	if (mState == CACHE)
 -	{
 -		S32 cur_imagesize = 0;
 -		S32 offset = mOffset;
 -		idx = mCache->getHeaderCacheEntry(mID, false, &cur_imagesize);
 -		if (idx >= 0 && cur_imagesize > 0)
 -		{
 -			offset = TEXTURE_CACHE_ENTRY_SIZE; // don't re-write header
 -		}
 -		idx = mCache->getHeaderCacheEntry(mID, true, &mImageSize); // touch entry
 -		if (idx >= 0)
 -		{
 -			llassert_always(cur_imagesize <= 0 || mImageSize == cur_imagesize);
 -			mState = offset < TEXTURE_CACHE_ENTRY_SIZE ? HEADER : BODY;
 -		}
 -		else
 -		{
 -			mDataSize = -1; // failed
 -			return true;
 -		}
 -	}
 -	
 -	if (mState == HEADER)
 -	{
 -#if USE_LFS_WRITE
 -		if (mFileHandle == LLLFSThread::nullHandle())
 -		{
 -			llassert_always(idx >= 0);
 -			llassert_always(mOffset < TEXTURE_CACHE_ENTRY_SIZE);
 -			S32 offset = idx * TEXTURE_CACHE_ENTRY_SIZE + mOffset;
 -			S32 size = TEXTURE_CACHE_ENTRY_SIZE - mOffset;
 -			mBytesRead = -1;
 -			mBytesToRead = size;
 -			setPriority(LLWorkerThread::PRIORITY_LOW | mPriority);
 -			mFileHandle = LLLFSThread::sLocal->write(mCache->mHeaderDataFileName,
 -													 mWriteData, offset, mBytesToRead,
 -													 new WriteResponder(mCache, mRequestHandle));
 -			return false;
 -		}
 -		else
 -		{
 -			if (mBytesRead >= 0)
 -			{
 -				if (mBytesRead != mBytesToRead)
 -				{
 -					llwarns << "LLTextureCacheWorker: "  << mID
 -							<< " incorrect number of bytes written to header: " << mBytesRead
 -							<< " != " << mBytesToRead << llendl;
 -					mDataSize = -1; // failed
 -					return true;
 -				}
 -				if (mDataSize <=  mBytesToRead)
 -				{
 -					return true; // done
 -				}
 -				else
 -				{
 -					mFileHandle = LLLFSThread::nullHandle();
 -					mState = BODY;
 -				}
 -			}
 -			else
 -			{
 -				return false;
 -			}
 -		}
 -#else
 -		llassert_always(idx >= 0);
 -		llassert_always(mOffset < TEXTURE_CACHE_ENTRY_SIZE);
 -		S32 offset = idx * TEXTURE_CACHE_ENTRY_SIZE + mOffset;
 -		S32 size = TEXTURE_CACHE_ENTRY_SIZE - mOffset;
 -		S32 bytes_written = ll_apr_file_write_ex(mCache->mHeaderDataFileName, mCache->getFileAPRPool(),
 -												 mWriteData, offset, size);
 -
 -		if (bytes_written <= 0)
 -		{
 -			llwarns << "LLTextureCacheWorker: missing entry: " << mID << llendl;
 -			mDataSize = -1; // failed
 -			return true;
 -		}
 -
 -		if (mDataSize <= size)
 -		{
 -			return true; // done
 -		}
 -		else
 -		{
 -			mState = BODY;
 -		}
 -#endif
 -	}
 -	
 -	if (mState == BODY)
 -	{
 -#if USE_LFS_WRITE
 -		if (mFileHandle == LLLFSThread::nullHandle())
 -		{
 -			S32 data_offset = TEXTURE_CACHE_ENTRY_SIZE - mOffset;
 -			data_offset = llmax(data_offset, 0);
 -			S32 file_size = mDataSize - data_offset;
 -			S32 file_offset = mOffset - TEXTURE_CACHE_ENTRY_SIZE;
 -			file_offset = llmax(file_offset, 0);
 -			if (file_size > 0 && mCache->appendToTextureEntryList(mID, file_size))
 -			{
 -				std::string filename = mCache->getTextureFileName(mID);
 -				mBytesRead = -1;
 -				mBytesToRead = file_size;
 -				setPriority(LLWorkerThread::PRIORITY_LOW | mPriority);
 -				mFileHandle = LLLFSThread::sLocal->write(filename,
 -														 mWriteData + data_offset, file_offset, mBytesToRead,
 -														 new WriteResponder(mCache, mRequestHandle));
 -				return false;
 -			}
 -			else
 -			{
 -				mDataSize = 0; // no data written
 -				return true; // done
 -			}
 -		}
 -		else
 -		{
 -			if (mBytesRead >= 0)
 -			{
 -				if (mBytesRead != mBytesToRead)
 -				{
 -					llwarns << "LLTextureCacheWorker: "  << mID
 -							<< " incorrect number of bytes written to body: " << mBytesRead
 -							<< " != " << mBytesToRead << llendl;
 -					mDataSize = -1; // failed
 -				}
 -				return true;
 -			}
 -			else
 -			{
 -				return false;
 -			}
 -		}
 -#else
 -		S32 data_offset = TEXTURE_CACHE_ENTRY_SIZE - mOffset;
 -		data_offset = llmax(data_offset, 0);
 -		S32 file_size = mDataSize - data_offset;
 -		S32 file_offset = mOffset - TEXTURE_CACHE_ENTRY_SIZE;
 -		file_offset = llmax(file_offset, 0);
 -		S32 bytes_written = 0;
 -		if (file_size > 0 && mCache->appendToTextureEntryList(mID, file_size))
 -		{
 -			std::string filename = mCache->getTextureFileName(mID);
 -			bytes_written = ll_apr_file_write_ex(filename, mCache->getFileAPRPool(),
 -												 mWriteData + data_offset,
 -												 file_offset, file_size);
 -			if (bytes_written <= 0)
 -			{
 -				mDataSize = -1; // failed
 -			}
 -		}
 -		else
 -		{
 -			mDataSize = 0; // no data written
 -		}
 -
 -		return true;
 -#endif
 -	}
 -	
 -	return false;
 -}
 -
 -//virtual
 -bool LLTextureCacheWorker::doWork(S32 param)
 -{
 -	bool res = false;
 -	if (param == 0) // read
 -	{
 -		res = doRead();
 -	}
 -	else if (param == 1) // write
 -	{
 -		res = doWrite();
 -	}
 -	else
 -	{
 -		llassert_always(0);
 -	}
 -	return res;
 -}
 -
 -//virtual (WORKER THREAD)
 -void LLTextureCacheWorker::finishWork(S32 param, bool completed)
 -{
 -	if (mResponder.notNull())
 -	{
 -		bool success = (completed && mDataSize > 0);
 -		if (param == 0)
 -		{
 -			// read
 -			if (success)
 -			{
 -				mResponder->setData(mReadData, mDataSize, mImageSize, mImageFormat, mImageLocal);
 -				mReadData = NULL; // responder owns data
 -				mDataSize = 0;
 -			}
 -			else
 -			{
 -				delete[] mReadData;
 -				mReadData = NULL;
 -				
 -			}
 -		}
 -		else
 -		{
 -			// write
 -			mWriteData = NULL; // we never owned data
 -			mDataSize = 0;
 -		}
 -		mResponder->completed(success);
 -	}
 -}
 -
 -//virtual (MAIN THREAD)
 -void LLTextureCacheWorker::endWork(S32 param, bool aborted)
 -{
 -	if (aborted)
 -	{
 -		// Let the destructor handle any cleanup
 -		return;
 -	}
 -	switch(param)
 -	{
 -	  default:
 -	  case 0: // read
 -	  case 1: // write
 -	  {
 -		  if (mDataSize < 0)
 -		  {
 -			  // failed
 -			  mCache->removeFromCache(mID);
 -		  }
 -		  break;
 -	  }
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////
 -
 -LLTextureCache::LLTextureCache(bool threaded)
 -	: LLWorkerThread("TextureCache", threaded),
 -	  mWorkersMutex(getAPRPool()),
 -	  mHeaderMutex(getAPRPool()),
 -	  mFileAPRPool(NULL),
 -	  mReadOnly(FALSE),
 -	  mTexturesSizeTotal(0),
 -	  mDoPurge(FALSE)
 -{
 -	apr_pool_create(&mFileAPRPool, NULL);
 -}
 -
 -LLTextureCache::~LLTextureCache()
 -{
 -	apr_pool_destroy(mFileAPRPool);
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////
 -
 -//virtual
 -S32 LLTextureCache::update(U32 max_time_ms)
 -{
 -	S32 res;
 -	res = LLWorkerThread::update(max_time_ms);
 -
 -	lockWorkers();
 -	for (std::vector<handle_t>::iterator iter1 = mPrioritizeWriteList.begin();
 -		 iter1 != mPrioritizeWriteList.end(); ++iter1)
 -	{
 -		handle_t handle = *iter1;
 -		handle_map_t::iterator iter2 = mWriters.find(handle);
 -		if(iter2 != mWriters.end())
 -		{
 -			LLTextureCacheWorker* worker = iter2->second;
 -			worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mPriority);
 -		}
 -	}
 -	mPrioritizeWriteList.clear();
 -	unlockWorkers();
 -	return res;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////
 -
 -std::string LLTextureCache::getLocalFileName(const LLUUID& id)
 -{
 -	// Does not include extension
 -	std::string idstr = id.asString();
 -	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, "textures", idstr);
 -	return filename;
 -}
 -
 -std::string LLTextureCache::getTextureFileName(const LLUUID& id)
 -{
 -	std::string idstr = id.asString();
 -	std::string delem = gDirUtilp->getDirDelimiter();
 -	std::string filename = mTexturesDirName + delem + idstr[0] + delem + idstr;
 -	return filename;
 -}
 -
 -bool LLTextureCache::appendToTextureEntryList(const LLUUID& id, S32 bodysize)
 -{
 -	bool res = false;
 -	bool purge = false;
 -	// Append UUID to end of texture entries
 -	{
 -		LLMutexLock lock(&mHeaderMutex);
 -		size_map_t::iterator iter = mTexturesSizeMap.find(id);
 -		if (iter == mTexturesSizeMap.end() || iter->second < bodysize)
 -		{
 -			llassert_always(bodysize > 0);
 -			Entry* entry = new Entry(id, bodysize, time(NULL));
 -			ll_apr_file_write_ex(mTexturesDirEntriesFileName, getFileAPRPool(),
 -								 (U8*)entry, -1, 1*sizeof(Entry));
 -			delete entry;
 -			if (iter != mTexturesSizeMap.end())
 -			{
 -				mTexturesSizeTotal -= iter->second;
 -			}
 -			mTexturesSizeTotal += bodysize;
 -			mTexturesSizeMap[id] = bodysize;
 -			if (mTexturesSizeTotal > sCacheMaxTexturesSize)
 -			{
 -				purge = true;
 -			}
 -			res = true;
 -		}
 -	}
 -	if (purge)
 -	{
 -		mDoPurge = TRUE;
 -	}
 -	return res;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////
 -
 -//static
 -const S32 MAX_REASONABLE_FILE_SIZE = 512*1024*1024; // 512 MB
 -F32 LLTextureCache::sHeaderCacheVersion = 1.0f;
 -U32 LLTextureCache::sCacheMaxEntries = MAX_REASONABLE_FILE_SIZE / TEXTURE_CACHE_ENTRY_SIZE;
 -S64 LLTextureCache::sCacheMaxTexturesSize = 0; // no limit
 -const char* entries_filename = "texture.entries";
 -const char* cache_filename = "texture.cache";
 -const char* textures_dirname = "textures";
 -
 -void LLTextureCache::setDirNames(ELLPath location)
 -{
 -	std::string delem = gDirUtilp->getDirDelimiter();
 -	mHeaderEntriesFileName = gDirUtilp->getExpandedFilename(location, entries_filename);
 -	mHeaderDataFileName = gDirUtilp->getExpandedFilename(location, cache_filename);
 -	mTexturesDirName = gDirUtilp->getExpandedFilename(location, textures_dirname);
 -	mTexturesDirEntriesFileName = mTexturesDirName + delem + entries_filename;
 -}
 -
 -void LLTextureCache::purgeCache(ELLPath location)
 -{
 -	if (!mReadOnly)
 -	{
 -		setDirNames(location);
 -	
 -		ll_apr_file_remove(mHeaderEntriesFileName, NULL);
 -		ll_apr_file_remove(mHeaderDataFileName, NULL);
 -	}
 -	purgeAllTextures(true);
 -}
 -
 -S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL read_only)
 -{
 -	mReadOnly = read_only;
 -	
 -	S64 header_size = (max_size * 2) / 10;
 -	S64 max_entries = header_size / TEXTURE_CACHE_ENTRY_SIZE;
 -	sCacheMaxEntries = (S32)(llmin((S64)sCacheMaxEntries, max_entries));
 -	header_size = sCacheMaxEntries * TEXTURE_CACHE_ENTRY_SIZE;
 -	max_size -= header_size;
 -	if (sCacheMaxTexturesSize > 0)
 -		sCacheMaxTexturesSize = llmin(sCacheMaxTexturesSize, max_size);
 -	else
 -		sCacheMaxTexturesSize = max_size;
 -	max_size -= sCacheMaxTexturesSize;
 -	
 -	llinfos << "TEXTURE CACHE: Headers: " << sCacheMaxEntries
 -			<< " Textures size: " << sCacheMaxTexturesSize/(1024*1024) << " MB" << llendl;
 -
 -	setDirNames(location);
 -	
 -	if (!mReadOnly)
 -	{
 -		LLFile::mkdir(mTexturesDirName.c_str());
 -		const char* subdirs = "0123456789abcdef";
 -		for (S32 i=0; i<16; i++)
 -		{
 -			std::string dirname = mTexturesDirName + gDirUtilp->getDirDelimiter() + subdirs[i];
 -			LLFile::mkdir(dirname.c_str());
 -		}
 -	}
 -	readHeaderCache();
 -	purgeTextures(true); // calc mTexturesSize and make some room in the texture cache if we need it
 -
 -	return max_size; // unused cache space
 -}
 -
 -struct lru_data
 -{
 -	lru_data(U32 t, S32 i, const LLUUID& id) { time=t; index=i; uuid=id; }
 -	U32 time;
 -	S32 index;
 -	LLUUID uuid;
 -	struct Compare
 -	{
 -		// lhs < rhs
 -		typedef const lru_data* lru_data_ptr;
 -		bool operator()(const lru_data_ptr& a, const lru_data_ptr& b) const
 -		{
 -			if (!(a->time < b->time))
 -				return true;
 -			else if (!(b->time < a->time))
 -				return false;
 -			else
 -				return a->index < b->index;
 -		}
 -	};				
 -};
 -
 -// Called from either the main thread or the worker thread
 -void LLTextureCache::readHeaderCache(apr_pool_t* poolp)
 -{
 -	LLMutexLock lock(&mHeaderMutex);
 -	mHeaderEntriesInfo.mVersion = 0.f;
 -	mHeaderEntriesInfo.mEntries = 0;
 -	if (ll_apr_file_exists(mHeaderEntriesFileName, poolp))
 -	{
 -		ll_apr_file_read_ex(mHeaderEntriesFileName, poolp,
 -							(U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo));
 -	}
 -	if (mHeaderEntriesInfo.mVersion != sHeaderCacheVersion)
 -	{
 -		if (!mReadOnly)
 -		{
 -			// Info with 0 entries
 -			mHeaderEntriesInfo.mVersion = sHeaderCacheVersion;
 -			ll_apr_file_write_ex(mHeaderEntriesFileName, poolp,
 -								 (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo));
 -		}
 -	}
 -	else
 -	{
 -		S32 num_entries = mHeaderEntriesInfo.mEntries;
 -		if (num_entries)
 -		{
 -			Entry* entries = new Entry[num_entries];
 -			ll_apr_file_read_ex(mHeaderEntriesFileName, poolp,
 -								(U8*)entries, sizeof(EntriesInfo), num_entries*sizeof(Entry));
 -			typedef std::set<lru_data*, lru_data::Compare> lru_set_t;
 -			lru_set_t lru;
 -			for (S32 i=0; i<num_entries; i++)
 -			{
 -				if (entries[i].mSize >= 0) // -1 indicates erased entry, skip
 -				{
 -					const LLUUID& id = entries[i].mID;
 -					lru.insert(new lru_data(entries[i].mTime, i, id));
 -					mHeaderIDMap[id] = i;
 -				}
 -			}
 -			mLRU.clear();
 -			S32 lru_entries = sCacheMaxEntries / 10;
 -			for (lru_set_t::iterator iter = lru.begin(); iter != lru.end(); ++iter)
 -			{
 -				lru_data* data = *iter;
 -				mLRU[data->index] = data->uuid;
 -				if (--lru_entries <= 0)
 -					break;
 -			}
 -			for_each(lru.begin(), lru.end(), DeletePointer());
 -			delete[] entries;
 -		}
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////
 -
 -void LLTextureCache::purgeAllTextures(bool purge_directories)
 -{
 -	if (!mReadOnly)
 -	{
 -		const char* subdirs = "0123456789abcdef";
 -		std::string delem = gDirUtilp->getDirDelimiter();
 -		std::string mask = delem + "*";
 -		for (S32 i=0; i<16; i++)
 -		{
 -			std::string dirname = mTexturesDirName + delem + subdirs[i];
 -			gDirUtilp->deleteFilesInDir(dirname.c_str(),mask);
 -			if (purge_directories)
 -			{
 -				LLFile::rmdir(dirname.c_str());
 -			}
 -		}
 -		ll_apr_file_remove(mTexturesDirEntriesFileName, NULL);
 -		if (purge_directories)
 -		{
 -			LLFile::rmdir(mTexturesDirName.c_str());
 -		}
 -	}
 -	mTexturesSizeMap.clear();
 -}
 -
 -void LLTextureCache::purgeTextures(bool validate)
 -{
 -	if (mReadOnly)
 -	{
 -		return;
 -	}
 -
 -	LLMutexLock lock(&mHeaderMutex);
 -	
 -	S32 filesize = ll_apr_file_size(mTexturesDirEntriesFileName, NULL);
 -	S32 num_entries = filesize / sizeof(Entry);
 -	if (num_entries * sizeof(Entry) != filesize)
 -	{
 -		llwarns << "Bad cache file: " << mTexturesDirEntriesFileName << " Purging." << llendl;
 -		purgeAllTextures(false);
 -		return;
 -	}
 -	if (num_entries == 0)
 -	{
 -		return; // nothing to do
 -	}
 -	
 -	Entry* entries = new Entry[num_entries];
 -	S32 bytes_read = ll_apr_file_read_ex(mTexturesDirEntriesFileName, NULL,
 -										 (U8*)entries, 0, num_entries*sizeof(Entry));
 -	if (bytes_read != filesize)
 -	{
 -		llwarns << "Bad cache file (2): " << mTexturesDirEntriesFileName << " Purging." << llendl;
 -		purgeAllTextures(false);
 -		return;
 -	}
 -	
 -	llinfos << "TEXTURE CACHE: Reading Entries..." << llendl;
 -	
 -	std::map<LLUUID, S32> entry_idx_map;
 -	S64 total_size = 0;
 -	for (S32 idx=0; idx<num_entries; idx++)
 -	{
 -		const LLUUID& id = entries[idx].mID;
 -// 		llinfos << "Entry: " << id << " Size: " << entries[i].mSize << " Time: " << entries[i].mTime << llendl;
 -		std::map<LLUUID, S32>::iterator iter = entry_idx_map.find(id);
 -		if (iter != entry_idx_map.end())
 -		{
 -			// Newer entry replacing older entry
 -			S32 pidx = iter->second;
 -			total_size -= entries[pidx].mSize;
 -			entries[pidx].mSize = 0; // flag: skip older entry
 -		}
 -		entry_idx_map[id] = idx;
 -		total_size += entries[idx].mSize;
 -	}
 -
 -	U32 validate_idx = 0;
 -	if (validate)
 -	{
 -		validate_idx = gSavedSettings.getU32("CacheValidateCounter");
 -		U32 next_idx = (++validate_idx) % 256;
 -		gSavedSettings.setU32("CacheValidateCounter", next_idx);
 -		llinfos << "TEXTURE CACHE: Validating: " << validate_idx << llendl;
 -	}
 -	
 -	S64 min_cache_size = (sCacheMaxTexturesSize * 9) / 10;
 -	S32 purge_count = 0;
 -	S32 next_idx = 0;
 -	for (S32 idx=0; idx<num_entries; idx++)
 -	{
 -		if (entries[idx].mSize == 0)
 -		{
 -			continue;
 -		}
 -		bool purge_entry = false;
 -		std::string filename = getTextureFileName(entries[idx].mID);
 -		if (total_size >= min_cache_size)
 -		{
 -			purge_entry = true;
 -		}
 -		else if (validate)
 -		{
 -			// make sure file exists and is the correct size
 -			S32 uuididx = entries[idx].mID.mData[0];
 -			if (uuididx == validate_idx)
 -			{
 -// 				llinfos << "Validating: " << filename << "Size: " << entries[idx].mSize << llendl;
 -				S32 bodysize = ll_apr_file_size(filename, NULL);
 -				if (bodysize != entries[idx].mSize)
 -				{
 -					llwarns << "TEXTURE CACHE BODY HAS BAD SIZE: " << bodysize << " != " << entries[idx].mSize
 -							<< filename << llendl;
 -					purge_entry = true;
 -				}
 -			}
 -		}
 -		if (purge_entry)
 -		{
 -			purge_count++;
 -//	 		llinfos << "PURGING: " << filename << llendl;
 -			ll_apr_file_remove(filename, NULL);
 -			total_size -= entries[idx].mSize;
 -			entries[idx].mSize = 0;
 -		}
 -		else
 -		{
 -			if (next_idx != idx)
 -			{
 -				entries[next_idx] = entries[idx];
 -			}
 -			++next_idx;
 -		}
 -	}
 -	num_entries = next_idx;
 -
 -	llinfos << "TEXTURE CACHE: Writing Entries: " << num_entries << llendl;
 -	
 -	ll_apr_file_remove(mTexturesDirEntriesFileName, NULL);
 -	ll_apr_file_write_ex(mTexturesDirEntriesFileName, NULL,
 -						 (U8*)&entries[0], 0, num_entries*sizeof(Entry));
 -	
 -	mTexturesSizeTotal = 0;
 -	mTexturesSizeMap.clear();
 -	for (S32 idx=0; idx<num_entries; idx++)
 -	{
 -		mTexturesSizeMap[entries[idx].mID] = entries[idx].mSize;
 -		mTexturesSizeTotal += entries[idx].mSize;
 -	}
 -	llassert(mTexturesSizeTotal == total_size);
 -	
 -	delete[] entries;
 -	
 -	llinfos << "TEXTURE CACHE:"
 -			<< " PURGED: " << purge_count
 -			<< " ENTRIES: " << num_entries
 -			<< " CACHE SIZE: " << total_size / 1024*1024 << " MB"
 -			<< llendl;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////
 -
 -// call lockWorkers() first!
 -LLTextureCacheWorker* LLTextureCache::getReader(handle_t handle)
 -{
 -	LLTextureCacheWorker* res = NULL;
 -	handle_map_t::iterator iter = mReaders.find(handle);
 -	if (iter != mReaders.end())
 -	{
 -		res = iter->second;
 -	}
 -	return res;
 -}
 -
 -LLTextureCacheWorker* LLTextureCache::getWriter(handle_t handle)
 -{
 -	LLTextureCacheWorker* res = NULL;
 -	handle_map_t::iterator iter = mWriters.find(handle);
 -	if (iter != mWriters.end())
 -	{
 -		res = iter->second;
 -	}
 -	return res;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////
 -
 -// Called from work thread
 -S32 LLTextureCache::getHeaderCacheEntry(const LLUUID& id, bool touch, S32* imagesize)
 -{
 -	bool retry = false;
 -	S32 idx = -1;
 -
 -	{
 -		LLMutexLock lock(&mHeaderMutex);
 -		id_map_t::iterator iter = mHeaderIDMap.find(id);
 -		if (iter != mHeaderIDMap.end())
 -		{
 -			idx = iter->second;
 -		}
 -		else if (touch && !mReadOnly)
 -		{
 -			if (mHeaderEntriesInfo.mEntries < sCacheMaxEntries)
 -			{
 -				// Add an entry
 -				idx = mHeaderEntriesInfo.mEntries++;
 -				mHeaderIDMap[id] = idx;
 -				// Update Info
 -				ll_apr_file_write_ex(mHeaderEntriesFileName, getFileAPRPool(),
 -									(U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo));
 -			}
 -			else if (!mLRU.empty())
 -			{
 -				idx = mLRU.begin()->first; // will be erased below
 -				const LLUUID& oldid = mLRU.begin()->second;
 -				mHeaderIDMap.erase(oldid);
 -				mTexturesSizeMap.erase(oldid);
 -				mHeaderIDMap[id] = idx;
 -			}
 -			else
 -			{
 -				idx = -1;
 -				retry = true;
 -			}
 -		}
 -		if (idx >= 0)
 -		{
 -			if (touch && !mReadOnly)
 -			{
 -				// Update the lru entry
 -				mLRU.erase(idx);
 -				llassert_always(imagesize && *imagesize > 0);
 -				Entry* entry = new Entry(id, *imagesize, time(NULL));
 -				S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry);
 -				ll_apr_file_write_ex(mHeaderEntriesFileName, getFileAPRPool(),
 -									 (U8*)entry, offset, sizeof(Entry));
 -				delete entry;
 -			}
 -			else if (imagesize)
 -			{
 -				// Get the image size
 -				Entry entry;
 -				S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry);
 -				ll_apr_file_read_ex(mHeaderEntriesFileName, getFileAPRPool(),
 -									(U8*)&entry, offset, sizeof(Entry));
 -				*imagesize = entry.mSize;
 -			}
 -		}
 -	}
 -	if (retry)
 -	{
 -		readHeaderCache(getFileAPRPool()); // updates the lru
 -		llassert_always(!mLRU.empty() || mHeaderEntriesInfo.mEntries < sCacheMaxEntries);
 -		idx = getHeaderCacheEntry(id, touch, imagesize); // assert above ensures no inf. recursion
 -	}
 -	return idx;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////
 -
 -// Calls from texture pipeline thread (i.e. LLTextureFetch)
 -
 -LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id, U32 priority,
 -													   S32 offset, S32 size, ReadResponder* responder)
 -{
 -	// Note: checking to see if an entry exists can cause a stall,
 -	//  so let the thread handle it
 -	LLMutexLock lock(&mWorkersMutex);
 -	LLTextureCacheWorker* worker = new LLTextureCacheWorker(this, priority, id,
 -															NULL, size, offset, 0,
 -															responder);
 -	handle_t handle = worker->read();
 -	mReaders[handle] = worker;
 -	return handle;
 -}
 -
 -bool LLTextureCache::readComplete(handle_t handle, bool abort)
 -{
 -	lockWorkers();
 -	handle_map_t::iterator iter = mReaders.find(handle);
 -	llassert_always(iter != mReaders.end());
 -	LLTextureCacheWorker* worker = iter->second;
 -	bool res = worker->complete();
 -	if (res || abort)
 -	{
 -		mReaders.erase(handle);
 -		unlockWorkers();
 -		worker->scheduleDelete();
 -		return true;
 -	}
 -	else
 -	{
 -		unlockWorkers();
 -		return false;
 -	}
 -}
 -
 -LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 priority,
 -													  U8* data, S32 datasize, S32 imagesize,
 -													  WriteResponder* responder)
 -{
 -	if (mReadOnly)
 -	{
 -		return LLWorkerThread::nullHandle();
 -	}
 -	if (mDoPurge)
 -	{
 -		// NOTE: This may cause an occasional hiccup,
 -		//  but it really needs to be done on the control thread
 -		//  (i.e. here)
 -		purgeTextures(false);
 -		mDoPurge = FALSE;
 -	}
 -	if (datasize >= TEXTURE_CACHE_ENTRY_SIZE)
 -	{
 -		LLMutexLock lock(&mWorkersMutex);
 -		llassert_always(imagesize > 0);
 -		LLTextureCacheWorker* worker = new LLTextureCacheWorker(this, priority, id,
 -																data, datasize, 0,
 -																imagesize, responder);
 -		handle_t handle = worker->write();
 -		mWriters[handle] = worker;
 -		return handle;
 -	}
 -	return LLWorkerThread::nullHandle();
 -}
 -
 -bool LLTextureCache::writeComplete(handle_t handle, bool abort)
 -{
 -	lockWorkers();
 -	handle_map_t::iterator iter = mWriters.find(handle);
 -	llassert_always(iter != mWriters.end());
 -	LLTextureCacheWorker* worker = iter->second;
 -	if (worker->complete() || abort)
 -	{
 -		mWriters.erase(handle);
 -		unlockWorkers();
 -		worker->scheduleDelete();
 -		return true;
 -	}
 -	else
 -	{
 -		unlockWorkers();
 -		return false;
 -	}
 -}
 -
 -void LLTextureCache::prioritizeWrite(handle_t handle)
 -{
 -	// Don't prioritize yet, we might be working on this now
 -	//   which could create a deadlock
 -	mPrioritizeWriteList.push_back(handle);
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////
 -
 -// Called from MAIN thread (endWork())
 -
 -bool LLTextureCache::removeHeaderCacheEntry(const LLUUID& id)
 -{
 -	if (mReadOnly)
 -	{
 -		return false;
 -	}
 -	LLMutexLock lock(&mHeaderMutex);
 -	id_map_t::iterator iter = mHeaderIDMap.find(id);
 -	if (iter != mHeaderIDMap.end())
 -	{
 -		S32 idx = iter->second;
 -		if (idx >= 0)
 -		{
 -			Entry* entry = new Entry(id, -1, time(NULL));
 -			S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry);
 -			ll_apr_file_write_ex(mHeaderEntriesFileName, NULL,
 -								 (U8*)entry, offset, sizeof(Entry));
 -			delete entry;
 -			mLRU[idx] = id;
 -			mHeaderIDMap.erase(id);
 -			mTexturesSizeMap.erase(id);
 -			return true;
 -		}
 -	}
 -	return false;
 -}
 -
 -void LLTextureCache::removeFromCache(const LLUUID& id)
 -{
 -	llwarns << "Removing texture from cache: " << id << llendl;
 -	if (!mReadOnly)
 -	{
 -		removeHeaderCacheEntry(id);
 -		ll_apr_file_remove(getTextureFileName(id), NULL);
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////
 -
 -LLTextureCache::ReadResponder::ReadResponder()
 -	: mImageSize(0),
 -	  mImageLocal(FALSE)
 -{
 -}
 -
 -void LLTextureCache::ReadResponder::setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal)
 -{
 -	if (mFormattedImage.notNull())
 -	{
 -		llassert_always(mFormattedImage->getCodec() == imageformat);
 -		mFormattedImage->appendData(data, datasize);
 -	}
 -	else
 -	{
 -		mFormattedImage = LLImageFormatted::createFromType(imageformat);
 -		mFormattedImage->setData(data,datasize);
 -	}
 -	mImageSize = imagesize;
 -	mImageLocal = imagelocal;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////
 +/**  + * @file texturecache.cpp + * @brief Object which handles local texture caching + * + * Copyright (c) 2000-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "lltexturecache.h" + +#include "llapr.h" +#include "lldir.h" +#include "llimage.h" +#include "lllfsthread.h" +#include "llviewercontrol.h" + +#define USE_LFS_READ 0 +#define USE_LFS_WRITE 0 + +// Note: first 4 bytes store file size, rest is j2c data +const S32 TEXTURE_CACHE_ENTRY_SIZE = FIRST_PACKET_SIZE; //1024; + +class LLTextureCacheWorker : public LLWorkerClass +{ +	friend class LLTextureCache; + +private: +	enum e_state +	{ +		INIT = 0, +		LOCAL = 1, +		CACHE = 2, +		HEADER = 3, +		BODY = 4 +	}; + +	class ReadResponder : public LLLFSThread::Responder +	{ +	public: +		ReadResponder(LLTextureCache* cache, handle_t handle) : mCache(cache), mHandle(handle) {} +		~ReadResponder() {} +		void completed(S32 bytes) +		{ +			mCache->lockWorkers(); +			LLTextureCacheWorker* reader = mCache->getReader(mHandle); +			if (reader) reader->ioComplete(bytes); +			mCache->unlockWorkers(); +		} +		LLTextureCache* mCache; +		LLTextureCacheWorker::handle_t mHandle; +	}; + +	class WriteResponder : public LLLFSThread::Responder +	{ +	public: +		WriteResponder(LLTextureCache* cache, handle_t handle) : mCache(cache), mHandle(handle) {} +		~WriteResponder() {} +		void completed(S32 bytes) +		{ +			mCache->lockWorkers(); +			LLTextureCacheWorker* writer = mCache->getWriter(mHandle); +			if (writer) writer->ioComplete(bytes); +			mCache->unlockWorkers(); +		} +		LLTextureCache* mCache; +		LLTextureCacheWorker::handle_t mHandle; +	}; +	 +public: +	LLTextureCacheWorker(LLTextureCache* cache, U32 priority, const LLUUID& id, +						 U8* data, S32 datasize, S32 offset, +						 S32 imagesize, // for writes +						 LLTextureCache::Responder* responder) +		: LLWorkerClass(cache, "LLTextureCacheWorker"), +		  mCache(cache), +		  mPriority(priority), +		  mID(id), +		  mState(INIT), +		  mReadData(NULL), +		  mWriteData(data), +		  mDataSize(datasize), +		  mOffset(offset), +		  mImageSize(imagesize), +		  mImageFormat(IMG_CODEC_J2C), +		  mImageLocal(FALSE), +		  mResponder(responder), +		  mFileHandle(LLLFSThread::nullHandle()), +		  mBytesToRead(0), +		  mBytesRead(0) +	{ +		mPriority &= LLWorkerThread::PRIORITY_LOWBITS; +	} +	~LLTextureCacheWorker() +	{ +		llassert_always(!haveWork()); +		delete[] mReadData; +	} + +	bool doRead(); +	bool doWrite(); +	virtual bool doWork(S32 param); // Called from LLWorkerThread::processRequest() + +	handle_t read() { addWork(0, LLWorkerThread::PRIORITY_HIGH | mPriority); return mRequestHandle; } +	handle_t write() { addWork(1, LLWorkerThread::PRIORITY_HIGH | mPriority); return mRequestHandle; } +	bool complete() { return checkWork(); } +	void ioComplete(S32 bytes) +	{ +		mBytesRead = bytes; +		setPriority(LLWorkerThread::PRIORITY_HIGH | mPriority); +	} +	 +private: +	virtual void startWork(S32 param); // called from addWork() (MAIN THREAD) +	virtual void finishWork(S32 param, bool completed); // called from finishRequest() (WORK THREAD) +	virtual void endWork(S32 param, bool aborted); // called from doWork() (MAIN THREAD) + +private: +	LLTextureCache* mCache; +	U32 mPriority; +	LLUUID mID; +	e_state mState; +	 +	U8* mReadData; +	U8* mWriteData; +	S32 mDataSize; +	S32 mOffset; +	S32 mImageSize; +	S32 mImageFormat; +	BOOL mImageLocal; +	LLPointer<LLTextureCache::Responder> mResponder; +	LLLFSThread::handle_t mFileHandle; +	S32 mBytesToRead; +	LLAtomicS32 mBytesRead; +}; + +//virtual +void LLTextureCacheWorker::startWork(S32 param) +{ +} + +bool LLTextureCacheWorker::doRead() +{ +	S32 local_size = 0; +	std::string local_filename; +	 +	if (mState == INIT) +	{ +		std::string filename = mCache->getLocalFileName(mID); +		local_filename = filename + ".j2c"; +		local_size = ll_apr_file_size(local_filename, mCache->getFileAPRPool()); +		if (local_size == 0) +		{ +			local_filename = filename + ".tga"; +			local_size = ll_apr_file_size(local_filename, mCache->getFileAPRPool()); +			if (local_size > 0) +			{ +				mImageFormat = IMG_CODEC_TGA; +				mDataSize = local_size; // Only a complete .tga file is valid +			} +		} +		if (local_size > 0) +		{ +			mState = LOCAL; +		} +		else +		{ +			mState = CACHE; +		} +	} + +	if (mState == LOCAL) +	{ +#if USE_LFS_READ +		if (mFileHandle == LLLFSThread::nullHandle()) +		{ +			mImageLocal = TRUE; +			mImageSize = local_size; +			if (!mDataSize || mDataSize + mOffset > local_size) +			{ +				mDataSize = local_size - mOffset; +			} +			if (mDataSize <= 0) +			{ +				// no more data to read +				mDataSize = 0; +				return true; +			} +			mReadData = new U8[mDataSize]; +			mBytesRead = -1; +			mBytesToRead = mDataSize; +			setPriority(LLWorkerThread::PRIORITY_LOW | mPriority); +			mFileHandle = LLLFSThread::sLocal->read(local_filename, mReadData, mOffset, mDataSize, +													new ReadResponder(mCache, mRequestHandle)); +			return false; +		} +		else +		{ +			if (mBytesRead >= 0) +			{ +				if (mBytesRead != mBytesToRead) +				{ +					llwarns << "Error reading file from local cache: " << local_filename +							<< " Bytes: " << mDataSize << " Offset: " << mOffset +							<< " / " << mDataSize << llendl; +					mDataSize = 0; // failed +					delete[] mReadData; +					mReadData = NULL; +				} +				return true; +			} +			else +			{ +				return false; +			} +		} +#else +		if (!mDataSize || mDataSize > local_size) +		{ +			mDataSize = local_size; +		} +		mReadData = new U8[mDataSize]; +		S32 bytes_read = ll_apr_file_read_ex(local_filename, mCache->getFileAPRPool(), +											 mReadData, mOffset, mDataSize); +		if (bytes_read != mDataSize) +		{ +			llwarns << "Error reading file from local cache: " << local_filename +					<< " Bytes: " << mDataSize << " Offset: " << mOffset +					<< " / " << mDataSize << llendl; +			mDataSize = 0; +			delete[] mReadData; +			mReadData = NULL; +		} +		else +		{ +			mImageSize = local_size; +			mImageLocal = TRUE; +		} +		return true; +#endif +	} + +	S32 idx = -1; +	 +	if (mState == CACHE) +	{ +		llassert_always(mImageSize == 0); +		idx = mCache->getHeaderCacheEntry(mID, false, &mImageSize); +		if (idx >= 0 && mImageSize > mOffset) +		{ +			llassert_always(mImageSize > 0); +			if (!mDataSize || mDataSize > mImageSize) +			{ +				mDataSize = mImageSize; +			} +			mState = mOffset < TEXTURE_CACHE_ENTRY_SIZE ? HEADER : BODY; +		} +		else +		{ +			mDataSize = 0; // no data +			return true; +		} +	} + +	if (mState == HEADER) +	{ +#if USE_LFS_READ +		if (mFileHandle == LLLFSThread::nullHandle()) +		{ +			llassert_always(idx >= 0); +			llassert_always(mOffset < TEXTURE_CACHE_ENTRY_SIZE); +			S32 offset = idx * TEXTURE_CACHE_ENTRY_SIZE + mOffset; +			S32 size = TEXTURE_CACHE_ENTRY_SIZE - mOffset; +			llassert_always(mReadData == NULL); +			mReadData = new U8[size]; +			mBytesRead = -1; +			mBytesToRead = size; +			setPriority(LLWorkerThread::PRIORITY_LOW | mPriority); +			mFileHandle = LLLFSThread::sLocal->read(mCache->mHeaderDataFileName, +													mReadData, offset, mBytesToRead, +													new ReadResponder(mCache, mRequestHandle)); +			return false; +		} +		else +		{ +			if (mBytesRead >= 0) +			{ +				if (mBytesRead != mBytesToRead) +				{ +					llwarns << "LLTextureCacheWorker: "  << mID +							<< " incorrect number of bytes read from header: " << mBytesRead +							<< " != " << mBytesToRead << llendl; +					mDataSize = -1; // failed +					return true; +				} +				if (mDataSize <= TEXTURE_CACHE_ENTRY_SIZE) +				{ +					return true; // done +				} +				else +				{ +					mFileHandle = LLLFSThread::nullHandle(); +					mState = BODY; +				} +			} +			else +			{ +				return false; +			} +		} +#else +		llassert_always(idx >= 0); +		llassert_always(mOffset < TEXTURE_CACHE_ENTRY_SIZE); +		S32 offset = idx * TEXTURE_CACHE_ENTRY_SIZE + mOffset; +		S32 size = TEXTURE_CACHE_ENTRY_SIZE - mOffset; +		mReadData = new U8[size]; +		S32 bytes_read = ll_apr_file_read_ex(mCache->mHeaderDataFileName, mCache->getFileAPRPool(), +											 mReadData, offset, size); +		if (bytes_read != size) +		{ +			llwarns << "LLTextureCacheWorker: "  << mID +					<< " incorrect number of bytes read from header: " << bytes_read +					<< " / " << size << llendl; +			mDataSize = -1; // failed +			return true; +		} +		if (mDataSize <= TEXTURE_CACHE_ENTRY_SIZE) +		{ +			return true; // done +		} +		else +		{ +			mState = BODY; +		} +#endif +	} + +	if (mState == BODY) +	{ +#if USE_LFS_READ +		if (mFileHandle == LLLFSThread::nullHandle()) +		{ +			std::string filename = mCache->getTextureFileName(mID); +			S32 filesize = ll_apr_file_size(filename, mCache->getFileAPRPool()); +			if (filesize > mOffset) +			{ +				S32 datasize = TEXTURE_CACHE_ENTRY_SIZE + filesize; +				mDataSize = llmin(datasize, mDataSize); +				S32 data_offset = TEXTURE_CACHE_ENTRY_SIZE - mOffset; +				data_offset = llmax(data_offset, 0); +				S32 file_size = mDataSize - data_offset; +				S32 file_offset = mOffset - TEXTURE_CACHE_ENTRY_SIZE; +				file_offset = llmax(file_offset, 0); + +				llassert_always(mDataSize > 0); +				U8* data = new U8[mDataSize]; +				if (data_offset > 0) +				{ +					llassert_always(mReadData); +					llassert_always(data_offset <= mDataSize); +					memcpy(data, mReadData, data_offset); +					delete[] mReadData; +					mReadData = NULL; +				} +				llassert_always(mReadData == NULL); +				mReadData = data; + +				mBytesRead = -1; +				mBytesToRead = file_size; +				setPriority(LLWorkerThread::PRIORITY_LOW | mPriority); +				llassert_always(data_offset + mBytesToRead <= mDataSize); +				mFileHandle = LLLFSThread::sLocal->read(filename, +														mReadData + data_offset, file_offset, mBytesToRead, +														new ReadResponder(mCache, mRequestHandle)); +				return false; +			} +			else +			{ +				mDataSize = TEXTURE_CACHE_ENTRY_SIZE; +				return true; // done +			} +		} +		else +		{ +			if (mBytesRead >= 0) +			{ +				if (mBytesRead != mBytesToRead) +				{ +					llwarns << "LLTextureCacheWorker: "  << mID +							<< " incorrect number of bytes read from body: " << mBytesRead +							<< " != " << mBytesToRead << llendl; +					mDataSize = -1; // failed +				} +				return true; +			} +			else +			{ +				return false; +			} +		} +#else +		std::string filename = mCache->getTextureFileName(mID); +		S32 filesize = ll_apr_file_size(filename, mCache->getFileAPRPool()); +		S32 bytes_read = 0; +		if (filesize > mOffset) +		{ +			S32 datasize = TEXTURE_CACHE_ENTRY_SIZE + filesize; +			mDataSize = llmin(datasize, mDataSize); +			S32 data_offset = TEXTURE_CACHE_ENTRY_SIZE - mOffset; +			data_offset = llmax(data_offset, 0); +			S32 file_size = mDataSize - data_offset; +			S32 file_offset = mOffset - TEXTURE_CACHE_ENTRY_SIZE; +			file_offset = llmax(file_offset, 0); +			 +			U8* data = new U8[mDataSize]; +			if (data_offset > 0) +			{ +				llassert_always(mReadData); +				memcpy(data, mReadData, data_offset); +				delete[] mReadData; +			} +			mReadData = data; +			bytes_read = ll_apr_file_read_ex(filename, mCache->getFileAPRPool(), +											 mReadData + data_offset, +											 file_offset, file_size); +			if (bytes_read != file_size) +			{ +				llwarns << "LLTextureCacheWorker: "  << mID +						<< " incorrect number of bytes read from body: " << bytes_read +						<< " / " << file_size << llendl; +				mDataSize = -1; // failed +				return true; +			} +		} +		else +		{ +			mDataSize = TEXTURE_CACHE_ENTRY_SIZE; +		} +		 +		return true; +#endif +	} +	 +	return false; +} + +bool LLTextureCacheWorker::doWrite() +{ +	S32 idx = -1; + +	if (mState == INIT) +	{ +		llassert_always(mOffset == 0); // Currently don't support offsets +		mState = CACHE; +	} + +	// No LOCAL state for write() +	 +	if (mState == CACHE) +	{ +		S32 cur_imagesize = 0; +		S32 offset = mOffset; +		idx = mCache->getHeaderCacheEntry(mID, false, &cur_imagesize); +		if (idx >= 0 && cur_imagesize > 0) +		{ +			offset = TEXTURE_CACHE_ENTRY_SIZE; // don't re-write header +		} +		idx = mCache->getHeaderCacheEntry(mID, true, &mImageSize); // touch entry +		if (idx >= 0) +		{ +			llassert_always(cur_imagesize <= 0 || mImageSize == cur_imagesize); +			mState = offset < TEXTURE_CACHE_ENTRY_SIZE ? HEADER : BODY; +		} +		else +		{ +			mDataSize = -1; // failed +			return true; +		} +	} +	 +	if (mState == HEADER) +	{ +#if USE_LFS_WRITE +		if (mFileHandle == LLLFSThread::nullHandle()) +		{ +			llassert_always(idx >= 0); +			llassert_always(mOffset < TEXTURE_CACHE_ENTRY_SIZE); +			S32 offset = idx * TEXTURE_CACHE_ENTRY_SIZE + mOffset; +			S32 size = TEXTURE_CACHE_ENTRY_SIZE - mOffset; +			mBytesRead = -1; +			mBytesToRead = size; +			setPriority(LLWorkerThread::PRIORITY_LOW | mPriority); +			mFileHandle = LLLFSThread::sLocal->write(mCache->mHeaderDataFileName, +													 mWriteData, offset, mBytesToRead, +													 new WriteResponder(mCache, mRequestHandle)); +			return false; +		} +		else +		{ +			if (mBytesRead >= 0) +			{ +				if (mBytesRead != mBytesToRead) +				{ +					llwarns << "LLTextureCacheWorker: "  << mID +							<< " incorrect number of bytes written to header: " << mBytesRead +							<< " != " << mBytesToRead << llendl; +					mDataSize = -1; // failed +					return true; +				} +				if (mDataSize <=  mBytesToRead) +				{ +					return true; // done +				} +				else +				{ +					mFileHandle = LLLFSThread::nullHandle(); +					mState = BODY; +				} +			} +			else +			{ +				return false; +			} +		} +#else +		llassert_always(idx >= 0); +		llassert_always(mOffset < TEXTURE_CACHE_ENTRY_SIZE); +		S32 offset = idx * TEXTURE_CACHE_ENTRY_SIZE + mOffset; +		S32 size = TEXTURE_CACHE_ENTRY_SIZE - mOffset; +		S32 bytes_written = ll_apr_file_write_ex(mCache->mHeaderDataFileName, mCache->getFileAPRPool(), +												 mWriteData, offset, size); + +		if (bytes_written <= 0) +		{ +			llwarns << "LLTextureCacheWorker: missing entry: " << mID << llendl; +			mDataSize = -1; // failed +			return true; +		} + +		if (mDataSize <= size) +		{ +			return true; // done +		} +		else +		{ +			mState = BODY; +		} +#endif +	} +	 +	if (mState == BODY) +	{ +#if USE_LFS_WRITE +		if (mFileHandle == LLLFSThread::nullHandle()) +		{ +			S32 data_offset = TEXTURE_CACHE_ENTRY_SIZE - mOffset; +			data_offset = llmax(data_offset, 0); +			S32 file_size = mDataSize - data_offset; +			S32 file_offset = mOffset - TEXTURE_CACHE_ENTRY_SIZE; +			file_offset = llmax(file_offset, 0); +			if (file_size > 0 && mCache->appendToTextureEntryList(mID, file_size)) +			{ +				std::string filename = mCache->getTextureFileName(mID); +				mBytesRead = -1; +				mBytesToRead = file_size; +				setPriority(LLWorkerThread::PRIORITY_LOW | mPriority); +				mFileHandle = LLLFSThread::sLocal->write(filename, +														 mWriteData + data_offset, file_offset, mBytesToRead, +														 new WriteResponder(mCache, mRequestHandle)); +				return false; +			} +			else +			{ +				mDataSize = 0; // no data written +				return true; // done +			} +		} +		else +		{ +			if (mBytesRead >= 0) +			{ +				if (mBytesRead != mBytesToRead) +				{ +					llwarns << "LLTextureCacheWorker: "  << mID +							<< " incorrect number of bytes written to body: " << mBytesRead +							<< " != " << mBytesToRead << llendl; +					mDataSize = -1; // failed +				} +				return true; +			} +			else +			{ +				return false; +			} +		} +#else +		S32 data_offset = TEXTURE_CACHE_ENTRY_SIZE - mOffset; +		data_offset = llmax(data_offset, 0); +		S32 file_size = mDataSize - data_offset; +		S32 file_offset = mOffset - TEXTURE_CACHE_ENTRY_SIZE; +		file_offset = llmax(file_offset, 0); +		S32 bytes_written = 0; +		if (file_size > 0 && mCache->appendToTextureEntryList(mID, file_size)) +		{ +			std::string filename = mCache->getTextureFileName(mID); +			bytes_written = ll_apr_file_write_ex(filename, mCache->getFileAPRPool(), +												 mWriteData + data_offset, +												 file_offset, file_size); +			if (bytes_written <= 0) +			{ +				mDataSize = -1; // failed +			} +		} +		else +		{ +			mDataSize = 0; // no data written +		} + +		return true; +#endif +	} +	 +	return false; +} + +//virtual +bool LLTextureCacheWorker::doWork(S32 param) +{ +	bool res = false; +	if (param == 0) // read +	{ +		res = doRead(); +	} +	else if (param == 1) // write +	{ +		res = doWrite(); +	} +	else +	{ +		llassert_always(0); +	} +	return res; +} + +//virtual (WORKER THREAD) +void LLTextureCacheWorker::finishWork(S32 param, bool completed) +{ +	if (mResponder.notNull()) +	{ +		bool success = (completed && mDataSize > 0); +		if (param == 0) +		{ +			// read +			if (success) +			{ +				mResponder->setData(mReadData, mDataSize, mImageSize, mImageFormat, mImageLocal); +				mReadData = NULL; // responder owns data +				mDataSize = 0; +			} +			else +			{ +				delete[] mReadData; +				mReadData = NULL; +				 +			} +		} +		else +		{ +			// write +			mWriteData = NULL; // we never owned data +			mDataSize = 0; +		} +		mResponder->completed(success); +	} +} + +//virtual (MAIN THREAD) +void LLTextureCacheWorker::endWork(S32 param, bool aborted) +{ +	if (aborted) +	{ +		// Let the destructor handle any cleanup +		return; +	} +	switch(param) +	{ +	  default: +	  case 0: // read +	  case 1: // write +	  { +		  if (mDataSize < 0) +		  { +			  // failed +			  mCache->removeFromCache(mID); +		  } +		  break; +	  } +	} +} + +////////////////////////////////////////////////////////////////////////////// + +LLTextureCache::LLTextureCache(bool threaded) +	: LLWorkerThread("TextureCache", threaded), +	  mWorkersMutex(getAPRPool()), +	  mHeaderMutex(getAPRPool()), +	  mFileAPRPool(NULL), +	  mReadOnly(FALSE), +	  mTexturesSizeTotal(0), +	  mDoPurge(FALSE) +{ +	apr_pool_create(&mFileAPRPool, NULL); +} + +LLTextureCache::~LLTextureCache() +{ +	apr_pool_destroy(mFileAPRPool); +} + +////////////////////////////////////////////////////////////////////////////// + +//virtual +S32 LLTextureCache::update(U32 max_time_ms) +{ +	S32 res; +	res = LLWorkerThread::update(max_time_ms); + +	lockWorkers(); +	for (std::vector<handle_t>::iterator iter1 = mPrioritizeWriteList.begin(); +		 iter1 != mPrioritizeWriteList.end(); ++iter1) +	{ +		handle_t handle = *iter1; +		handle_map_t::iterator iter2 = mWriters.find(handle); +		if(iter2 != mWriters.end()) +		{ +			LLTextureCacheWorker* worker = iter2->second; +			worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mPriority); +		} +	} +	mPrioritizeWriteList.clear(); +	unlockWorkers(); +	return res; +} + +////////////////////////////////////////////////////////////////////////////// + +std::string LLTextureCache::getLocalFileName(const LLUUID& id) +{ +	// Does not include extension +	std::string idstr = id.asString(); +	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, "textures", idstr); +	return filename; +} + +std::string LLTextureCache::getTextureFileName(const LLUUID& id) +{ +	std::string idstr = id.asString(); +	std::string delem = gDirUtilp->getDirDelimiter(); +	std::string filename = mTexturesDirName + delem + idstr[0] + delem + idstr; +	return filename; +} + +bool LLTextureCache::appendToTextureEntryList(const LLUUID& id, S32 bodysize) +{ +	bool res = false; +	bool purge = false; +	// Append UUID to end of texture entries +	{ +		LLMutexLock lock(&mHeaderMutex); +		size_map_t::iterator iter = mTexturesSizeMap.find(id); +		if (iter == mTexturesSizeMap.end() || iter->second < bodysize) +		{ +			llassert_always(bodysize > 0); +			Entry* entry = new Entry(id, bodysize, time(NULL)); +			ll_apr_file_write_ex(mTexturesDirEntriesFileName, getFileAPRPool(), +								 (U8*)entry, -1, 1*sizeof(Entry)); +			delete entry; +			if (iter != mTexturesSizeMap.end()) +			{ +				mTexturesSizeTotal -= iter->second; +			} +			mTexturesSizeTotal += bodysize; +			mTexturesSizeMap[id] = bodysize; +			if (mTexturesSizeTotal > sCacheMaxTexturesSize) +			{ +				purge = true; +			} +			res = true; +		} +	} +	if (purge) +	{ +		mDoPurge = TRUE; +	} +	return res; +} + +////////////////////////////////////////////////////////////////////////////// + +//static +const S32 MAX_REASONABLE_FILE_SIZE = 512*1024*1024; // 512 MB +F32 LLTextureCache::sHeaderCacheVersion = 1.0f; +U32 LLTextureCache::sCacheMaxEntries = MAX_REASONABLE_FILE_SIZE / TEXTURE_CACHE_ENTRY_SIZE; +S64 LLTextureCache::sCacheMaxTexturesSize = 0; // no limit +const char* entries_filename = "texture.entries"; +const char* cache_filename = "texture.cache"; +const char* textures_dirname = "textures"; + +void LLTextureCache::setDirNames(ELLPath location) +{ +	std::string delem = gDirUtilp->getDirDelimiter(); +	mHeaderEntriesFileName = gDirUtilp->getExpandedFilename(location, entries_filename); +	mHeaderDataFileName = gDirUtilp->getExpandedFilename(location, cache_filename); +	mTexturesDirName = gDirUtilp->getExpandedFilename(location, textures_dirname); +	mTexturesDirEntriesFileName = mTexturesDirName + delem + entries_filename; +} + +void LLTextureCache::purgeCache(ELLPath location) +{ +	if (!mReadOnly) +	{ +		setDirNames(location); +	 +		ll_apr_file_remove(mHeaderEntriesFileName, NULL); +		ll_apr_file_remove(mHeaderDataFileName, NULL); +	} +	purgeAllTextures(true); +} + +S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL read_only) +{ +	mReadOnly = read_only; +	 +	S64 header_size = (max_size * 2) / 10; +	S64 max_entries = header_size / TEXTURE_CACHE_ENTRY_SIZE; +	sCacheMaxEntries = (S32)(llmin((S64)sCacheMaxEntries, max_entries)); +	header_size = sCacheMaxEntries * TEXTURE_CACHE_ENTRY_SIZE; +	max_size -= header_size; +	if (sCacheMaxTexturesSize > 0) +		sCacheMaxTexturesSize = llmin(sCacheMaxTexturesSize, max_size); +	else +		sCacheMaxTexturesSize = max_size; +	max_size -= sCacheMaxTexturesSize; +	 +	llinfos << "TEXTURE CACHE: Headers: " << sCacheMaxEntries +			<< " Textures size: " << sCacheMaxTexturesSize/(1024*1024) << " MB" << llendl; + +	setDirNames(location); +	 +	if (!mReadOnly) +	{ +		LLFile::mkdir(mTexturesDirName.c_str()); +		const char* subdirs = "0123456789abcdef"; +		for (S32 i=0; i<16; i++) +		{ +			std::string dirname = mTexturesDirName + gDirUtilp->getDirDelimiter() + subdirs[i]; +			LLFile::mkdir(dirname.c_str()); +		} +	} +	readHeaderCache(); +	purgeTextures(true); // calc mTexturesSize and make some room in the texture cache if we need it + +	return max_size; // unused cache space +} + +struct lru_data +{ +	lru_data(U32 t, S32 i, const LLUUID& id) { time=t; index=i; uuid=id; } +	U32 time; +	S32 index; +	LLUUID uuid; +	struct Compare +	{ +		// lhs < rhs +		typedef const lru_data* lru_data_ptr; +		bool operator()(const lru_data_ptr& a, const lru_data_ptr& b) const +		{ +			if (!(a->time < b->time)) +				return true; +			else if (!(b->time < a->time)) +				return false; +			else +				return a->index < b->index; +		} +	};				 +}; + +// Called from either the main thread or the worker thread +void LLTextureCache::readHeaderCache(apr_pool_t* poolp) +{ +	LLMutexLock lock(&mHeaderMutex); +	mHeaderEntriesInfo.mVersion = 0.f; +	mHeaderEntriesInfo.mEntries = 0; +	if (ll_apr_file_exists(mHeaderEntriesFileName, poolp)) +	{ +		ll_apr_file_read_ex(mHeaderEntriesFileName, poolp, +							(U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo)); +	} +	if (mHeaderEntriesInfo.mVersion != sHeaderCacheVersion) +	{ +		if (!mReadOnly) +		{ +			// Info with 0 entries +			mHeaderEntriesInfo.mVersion = sHeaderCacheVersion; +			ll_apr_file_write_ex(mHeaderEntriesFileName, poolp, +								 (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo)); +		} +	} +	else +	{ +		S32 num_entries = mHeaderEntriesInfo.mEntries; +		if (num_entries) +		{ +			Entry* entries = new Entry[num_entries]; +			ll_apr_file_read_ex(mHeaderEntriesFileName, poolp, +								(U8*)entries, sizeof(EntriesInfo), num_entries*sizeof(Entry)); +			typedef std::set<lru_data*, lru_data::Compare> lru_set_t; +			lru_set_t lru; +			for (S32 i=0; i<num_entries; i++) +			{ +				if (entries[i].mSize >= 0) // -1 indicates erased entry, skip +				{ +					const LLUUID& id = entries[i].mID; +					lru.insert(new lru_data(entries[i].mTime, i, id)); +					mHeaderIDMap[id] = i; +				} +			} +			mLRU.clear(); +			S32 lru_entries = sCacheMaxEntries / 10; +			for (lru_set_t::iterator iter = lru.begin(); iter != lru.end(); ++iter) +			{ +				lru_data* data = *iter; +				mLRU[data->index] = data->uuid; +				if (--lru_entries <= 0) +					break; +			} +			for_each(lru.begin(), lru.end(), DeletePointer()); +			delete[] entries; +		} +	} +} + +////////////////////////////////////////////////////////////////////////////// + +void LLTextureCache::purgeAllTextures(bool purge_directories) +{ +	if (!mReadOnly) +	{ +		const char* subdirs = "0123456789abcdef"; +		std::string delem = gDirUtilp->getDirDelimiter(); +		std::string mask = delem + "*"; +		for (S32 i=0; i<16; i++) +		{ +			std::string dirname = mTexturesDirName + delem + subdirs[i]; +			gDirUtilp->deleteFilesInDir(dirname.c_str(),mask); +			if (purge_directories) +			{ +				LLFile::rmdir(dirname.c_str()); +			} +		} +		ll_apr_file_remove(mTexturesDirEntriesFileName, NULL); +		if (purge_directories) +		{ +			LLFile::rmdir(mTexturesDirName.c_str()); +		} +	} +	mTexturesSizeMap.clear(); +} + +void LLTextureCache::purgeTextures(bool validate) +{ +	if (mReadOnly) +	{ +		return; +	} + +	LLMutexLock lock(&mHeaderMutex); +	 +	S32 filesize = ll_apr_file_size(mTexturesDirEntriesFileName, NULL); +	S32 num_entries = filesize / sizeof(Entry); +	if (num_entries * (S32)sizeof(Entry) != filesize) +	{ +		llwarns << "Bad cache file: " << mTexturesDirEntriesFileName << " Purging." << llendl; +		purgeAllTextures(false); +		return; +	} +	if (num_entries == 0) +	{ +		return; // nothing to do +	} +	 +	Entry* entries = new Entry[num_entries]; +	S32 bytes_read = ll_apr_file_read_ex(mTexturesDirEntriesFileName, NULL, +										 (U8*)entries, 0, num_entries*sizeof(Entry)); +	if (bytes_read != filesize) +	{ +		llwarns << "Bad cache file (2): " << mTexturesDirEntriesFileName << " Purging." << llendl; +		purgeAllTextures(false); +		return; +	} +	 +	llinfos << "TEXTURE CACHE: Reading Entries..." << llendl; +	 +	std::map<LLUUID, S32> entry_idx_map; +	S64 total_size = 0; +	for (S32 idx=0; idx<num_entries; idx++) +	{ +		const LLUUID& id = entries[idx].mID; +// 		llinfos << "Entry: " << id << " Size: " << entries[i].mSize << " Time: " << entries[i].mTime << llendl; +		std::map<LLUUID, S32>::iterator iter = entry_idx_map.find(id); +		if (iter != entry_idx_map.end()) +		{ +			// Newer entry replacing older entry +			S32 pidx = iter->second; +			total_size -= entries[pidx].mSize; +			entries[pidx].mSize = 0; // flag: skip older entry +		} +		entry_idx_map[id] = idx; +		total_size += entries[idx].mSize; +	} + +	U32 validate_idx = 0; +	if (validate) +	{ +		validate_idx = gSavedSettings.getU32("CacheValidateCounter"); +		U32 next_idx = (++validate_idx) % 256; +		gSavedSettings.setU32("CacheValidateCounter", next_idx); +		llinfos << "TEXTURE CACHE: Validating: " << validate_idx << llendl; +	} +	 +	S64 min_cache_size = (sCacheMaxTexturesSize * 9) / 10; +	S32 purge_count = 0; +	S32 next_idx = 0; +	for (S32 idx=0; idx<num_entries; idx++) +	{ +		if (entries[idx].mSize == 0) +		{ +			continue; +		} +		bool purge_entry = false; +		std::string filename = getTextureFileName(entries[idx].mID); +		if (total_size >= min_cache_size) +		{ +			purge_entry = true; +		} +		else if (validate) +		{ +			// make sure file exists and is the correct size +			S32 uuididx = entries[idx].mID.mData[0]; +			if (uuididx == validate_idx) +			{ +// 				llinfos << "Validating: " << filename << "Size: " << entries[idx].mSize << llendl; +				S32 bodysize = ll_apr_file_size(filename, NULL); +				if (bodysize != entries[idx].mSize) +				{ +					llwarns << "TEXTURE CACHE BODY HAS BAD SIZE: " << bodysize << " != " << entries[idx].mSize +							<< filename << llendl; +					purge_entry = true; +				} +			} +		} +		if (purge_entry) +		{ +			purge_count++; +//	 		llinfos << "PURGING: " << filename << llendl; +			ll_apr_file_remove(filename, NULL); +			total_size -= entries[idx].mSize; +			entries[idx].mSize = 0; +		} +		else +		{ +			if (next_idx != idx) +			{ +				entries[next_idx] = entries[idx]; +			} +			++next_idx; +		} +	} +	num_entries = next_idx; + +	llinfos << "TEXTURE CACHE: Writing Entries: " << num_entries << llendl; +	 +	ll_apr_file_remove(mTexturesDirEntriesFileName, NULL); +	ll_apr_file_write_ex(mTexturesDirEntriesFileName, NULL, +						 (U8*)&entries[0], 0, num_entries*sizeof(Entry)); +	 +	mTexturesSizeTotal = 0; +	mTexturesSizeMap.clear(); +	for (S32 idx=0; idx<num_entries; idx++) +	{ +		mTexturesSizeMap[entries[idx].mID] = entries[idx].mSize; +		mTexturesSizeTotal += entries[idx].mSize; +	} +	llassert(mTexturesSizeTotal == total_size); +	 +	delete[] entries; +	 +	llinfos << "TEXTURE CACHE:" +			<< " PURGED: " << purge_count +			<< " ENTRIES: " << num_entries +			<< " CACHE SIZE: " << total_size / 1024*1024 << " MB" +			<< llendl; +} + +////////////////////////////////////////////////////////////////////////////// + +// call lockWorkers() first! +LLTextureCacheWorker* LLTextureCache::getReader(handle_t handle) +{ +	LLTextureCacheWorker* res = NULL; +	handle_map_t::iterator iter = mReaders.find(handle); +	if (iter != mReaders.end()) +	{ +		res = iter->second; +	} +	return res; +} + +LLTextureCacheWorker* LLTextureCache::getWriter(handle_t handle) +{ +	LLTextureCacheWorker* res = NULL; +	handle_map_t::iterator iter = mWriters.find(handle); +	if (iter != mWriters.end()) +	{ +		res = iter->second; +	} +	return res; +} + +////////////////////////////////////////////////////////////////////////////// + +// Called from work thread +S32 LLTextureCache::getHeaderCacheEntry(const LLUUID& id, bool touch, S32* imagesize) +{ +	bool retry = false; +	S32 idx = -1; + +	{ +		LLMutexLock lock(&mHeaderMutex); +		id_map_t::iterator iter = mHeaderIDMap.find(id); +		if (iter != mHeaderIDMap.end()) +		{ +			idx = iter->second; +		} +		else if (touch && !mReadOnly) +		{ +			if (mHeaderEntriesInfo.mEntries < sCacheMaxEntries) +			{ +				// Add an entry +				idx = mHeaderEntriesInfo.mEntries++; +				mHeaderIDMap[id] = idx; +				// Update Info +				ll_apr_file_write_ex(mHeaderEntriesFileName, getFileAPRPool(), +									(U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo)); +			} +			else if (!mLRU.empty()) +			{ +				idx = mLRU.begin()->first; // will be erased below +				const LLUUID& oldid = mLRU.begin()->second; +				mHeaderIDMap.erase(oldid); +				mTexturesSizeMap.erase(oldid); +				mHeaderIDMap[id] = idx; +			} +			else +			{ +				idx = -1; +				retry = true; +			} +		} +		if (idx >= 0) +		{ +			if (touch && !mReadOnly) +			{ +				// Update the lru entry +				mLRU.erase(idx); +				llassert_always(imagesize && *imagesize > 0); +				Entry* entry = new Entry(id, *imagesize, time(NULL)); +				S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry); +				ll_apr_file_write_ex(mHeaderEntriesFileName, getFileAPRPool(), +									 (U8*)entry, offset, sizeof(Entry)); +				delete entry; +			} +			else if (imagesize) +			{ +				// Get the image size +				Entry entry; +				S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry); +				ll_apr_file_read_ex(mHeaderEntriesFileName, getFileAPRPool(), +									(U8*)&entry, offset, sizeof(Entry)); +				*imagesize = entry.mSize; +			} +		} +	} +	if (retry) +	{ +		readHeaderCache(getFileAPRPool()); // updates the lru +		llassert_always(!mLRU.empty() || mHeaderEntriesInfo.mEntries < sCacheMaxEntries); +		idx = getHeaderCacheEntry(id, touch, imagesize); // assert above ensures no inf. recursion +	} +	return idx; +} + +////////////////////////////////////////////////////////////////////////////// + +// Calls from texture pipeline thread (i.e. LLTextureFetch) + +LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id, U32 priority, +													   S32 offset, S32 size, ReadResponder* responder) +{ +	// Note: checking to see if an entry exists can cause a stall, +	//  so let the thread handle it +	LLMutexLock lock(&mWorkersMutex); +	LLTextureCacheWorker* worker = new LLTextureCacheWorker(this, priority, id, +															NULL, size, offset, 0, +															responder); +	handle_t handle = worker->read(); +	mReaders[handle] = worker; +	return handle; +} + +bool LLTextureCache::readComplete(handle_t handle, bool abort) +{ +	lockWorkers(); +	handle_map_t::iterator iter = mReaders.find(handle); +	llassert_always(iter != mReaders.end()); +	LLTextureCacheWorker* worker = iter->second; +	bool res = worker->complete(); +	if (res || abort) +	{ +		mReaders.erase(handle); +		unlockWorkers(); +		worker->scheduleDelete(); +		return true; +	} +	else +	{ +		unlockWorkers(); +		return false; +	} +} + +LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 priority, +													  U8* data, S32 datasize, S32 imagesize, +													  WriteResponder* responder) +{ +	if (mReadOnly) +	{ +		return LLWorkerThread::nullHandle(); +	} +	if (mDoPurge) +	{ +		// NOTE: This may cause an occasional hiccup, +		//  but it really needs to be done on the control thread +		//  (i.e. here) +		purgeTextures(false); +		mDoPurge = FALSE; +	} +	if (datasize >= TEXTURE_CACHE_ENTRY_SIZE) +	{ +		LLMutexLock lock(&mWorkersMutex); +		llassert_always(imagesize > 0); +		LLTextureCacheWorker* worker = new LLTextureCacheWorker(this, priority, id, +																data, datasize, 0, +																imagesize, responder); +		handle_t handle = worker->write(); +		mWriters[handle] = worker; +		return handle; +	} +	return LLWorkerThread::nullHandle(); +} + +bool LLTextureCache::writeComplete(handle_t handle, bool abort) +{ +	lockWorkers(); +	handle_map_t::iterator iter = mWriters.find(handle); +	llassert_always(iter != mWriters.end()); +	LLTextureCacheWorker* worker = iter->second; +	if (worker->complete() || abort) +	{ +		mWriters.erase(handle); +		unlockWorkers(); +		worker->scheduleDelete(); +		return true; +	} +	else +	{ +		unlockWorkers(); +		return false; +	} +} + +void LLTextureCache::prioritizeWrite(handle_t handle) +{ +	// Don't prioritize yet, we might be working on this now +	//   which could create a deadlock +	mPrioritizeWriteList.push_back(handle); +} + +////////////////////////////////////////////////////////////////////////////// + +// Called from MAIN thread (endWork()) + +bool LLTextureCache::removeHeaderCacheEntry(const LLUUID& id) +{ +	if (mReadOnly) +	{ +		return false; +	} +	LLMutexLock lock(&mHeaderMutex); +	id_map_t::iterator iter = mHeaderIDMap.find(id); +	if (iter != mHeaderIDMap.end()) +	{ +		S32 idx = iter->second; +		if (idx >= 0) +		{ +			Entry* entry = new Entry(id, -1, time(NULL)); +			S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry); +			ll_apr_file_write_ex(mHeaderEntriesFileName, NULL, +								 (U8*)entry, offset, sizeof(Entry)); +			delete entry; +			mLRU[idx] = id; +			mHeaderIDMap.erase(id); +			mTexturesSizeMap.erase(id); +			return true; +		} +	} +	return false; +} + +void LLTextureCache::removeFromCache(const LLUUID& id) +{ +	llwarns << "Removing texture from cache: " << id << llendl; +	if (!mReadOnly) +	{ +		removeHeaderCacheEntry(id); +		ll_apr_file_remove(getTextureFileName(id), NULL); +	} +} + +////////////////////////////////////////////////////////////////////////////// + +LLTextureCache::ReadResponder::ReadResponder() +	: mImageSize(0), +	  mImageLocal(FALSE) +{ +} + +void LLTextureCache::ReadResponder::setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal) +{ +	if (mFormattedImage.notNull()) +	{ +		llassert_always(mFormattedImage->getCodec() == imageformat); +		mFormattedImage->appendData(data, datasize); +	} +	else +	{ +		mFormattedImage = LLImageFormatted::createFromType(imageformat); +		mFormattedImage->setData(data,datasize); +	} +	mImageSize = imagesize; +	mImageLocal = imagelocal; +} + +////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h index 3b16b26b4a..f9eb8cb177 100644 --- a/indra/newview/lltexturecache.h +++ b/indra/newview/lltexturecache.h @@ -1,149 +1,149 @@ -/** 
 - * @file lltexturecache.h
 - * @brief Object for managing texture cachees.
 - *
 - * Copyright (c) 2000-$CurrentYear$, Linden Research, Inc.
 - * $License$
 - */
 -
 -#ifndef LL_LLTEXTURECACHE_
 -#define LL_LLTEXTURECACHE_H
 -
 -#include "lldir.h"
 -#include "llstl.h"
 -#include "llstring.h"
 -#include "lluuid.h"
 -
 -#include "llworkerthread.h"
 -
 -class LLTextureCacheWorker;
 -
 -class LLTextureCache : public LLWorkerThread
 -{
 -	friend class LLTextureCacheWorker;
 -
 -public:
 -
 -	class Responder : public LLResponder
 -	{
 -	public:
 -		virtual void setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal) = 0;
 -	};
 -	
 -	class ReadResponder : public Responder
 -	{
 -	public:
 -		ReadResponder();
 -		void setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal);
 -		void setImage(LLImageFormatted* image) { mFormattedImage = image; }
 -	protected:
 -		LLPointer<LLImageFormatted> mFormattedImage;
 -		S32 mImageSize;
 -		BOOL mImageLocal;
 -	};
 -
 -	class WriteResponder : public Responder
 -	{
 -		void setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal)
 -		{
 -			// not used
 -		}
 -	};
 -	
 -	LLTextureCache(bool threaded);
 -	~LLTextureCache();
 -
 -	/*virtual*/ S32 update(U32 max_time_ms);	
 -	
 -	void purgeCache(ELLPath location);
 -	S64 initCache(ELLPath location, S64 maxsize, BOOL read_only);
 -
 -	handle_t readFromCache(const LLUUID& id, U32 priority, S32 offset, S32 size,
 -						   ReadResponder* responder);
 -	bool readComplete(handle_t handle, bool abort);
 -	handle_t writeToCache(const LLUUID& id, U32 priority, U8* data, S32 datasize, S32 imagesize,
 -						  WriteResponder* responder);
 -	bool writeComplete(handle_t handle, bool abort = false);
 -	void prioritizeWrite(handle_t handle);
 -
 -	void removeFromCache(const LLUUID& id);
 -
 -	// For LLTextureCacheWorker::Responder
 -	LLTextureCacheWorker* getReader(handle_t handle);
 -	LLTextureCacheWorker* getWriter(handle_t handle);
 -	void lockWorkers() { mWorkersMutex.lock(); }
 -	void unlockWorkers() { mWorkersMutex.unlock(); }
 -
 -	// debug
 -	S32 getNumReads() { return mReaders.size(); }
 -	S32 getNumWrites() { return mWriters.size(); }
 -
 -protected:
 -	// Accessed by LLTextureCacheWorker
 -	apr_pool_t* getFileAPRPool() { return mFileAPRPool; }
 -	bool appendToTextureEntryList(const LLUUID& id, S32 size);
 -	std::string getLocalFileName(const LLUUID& id);
 -	std::string getTextureFileName(const LLUUID& id);
 -	
 -private:
 -	void setDirNames(ELLPath location);
 -	void readHeaderCache(apr_pool_t* poolp = NULL);
 -	void purgeAllTextures(bool purge_directories);
 -	void purgeTextures(bool validate);
 -	S32 getHeaderCacheEntry(const LLUUID& id, bool touch, S32* imagesize = NULL);
 -	bool removeHeaderCacheEntry(const LLUUID& id);
 -	void lockHeaders() { mHeaderMutex.lock(); }
 -	void unlockHeaders() { mHeaderMutex.unlock(); }
 -	
 -private:
 -	// Internal
 -	LLMutex mWorkersMutex;
 -	LLMutex mHeaderMutex;
 -	apr_pool_t* mFileAPRPool;
 -	
 -	typedef std::map<handle_t, LLTextureCacheWorker*> handle_map_t;
 -	handle_map_t mReaders;
 -	handle_map_t mWriters;
 -	std::vector<handle_t> mPrioritizeWriteList;
 -	
 -	BOOL mReadOnly;
 -	
 -	// Entries
 -	struct EntriesInfo
 -	{
 -		F32 mVersion;
 -		U32 mEntries;
 -	};
 -	struct Entry
 -	{
 -		Entry() {}
 -		Entry(const LLUUID& id, S32 size, U32 time) : mID(id), mSize(size), mTime(time) {}
 -		LLUUID mID; // 128 bits
 -		S32 mSize; // total size of image if known (NOT size cached)
 -		U32 mTime; // seconds since 1/1/1970
 -	};
 -
 -	// HEADERS (Include first mip)
 -	std::string mHeaderEntriesFileName;
 -	std::string mHeaderDataFileName;
 -	EntriesInfo mHeaderEntriesInfo;
 -	typedef std::map<S32,LLUUID> index_map_t;
 -	index_map_t mLRU; // index, id; stored as a map for fast removal
 -	typedef std::map<LLUUID,S32> id_map_t;
 -	id_map_t mHeaderIDMap;
 -
 -	// BODIES (TEXTURES minus headers)
 -	std::string mTexturesDirName;
 -	std::string mTexturesDirEntriesFileName;
 -	typedef std::map<LLUUID,S32> size_map_t;
 -	size_map_t mTexturesSizeMap;
 -	S64 mTexturesSizeTotal;
 -	LLAtomic32<BOOL> mDoPurge;
 -	
 -	// Statics
 -	static F32 sHeaderCacheVersion;
 -	static U32 sCacheMaxEntries;
 -	static S64 sCacheMaxTexturesSize;
 -};
 -
 -#endif // LL_LLTEXTURECACHE_H
 +/**  + * @file lltexturecache.h + * @brief Object for managing texture cachees. + * + * Copyright (c) 2000-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#ifndef LL_LLTEXTURECACHE_ +#define LL_LLTEXTURECACHE_H + +#include "lldir.h" +#include "llstl.h" +#include "llstring.h" +#include "lluuid.h" + +#include "llworkerthread.h" + +class LLTextureCacheWorker; + +class LLTextureCache : public LLWorkerThread +{ +	friend class LLTextureCacheWorker; + +public: + +	class Responder : public LLResponder +	{ +	public: +		virtual void setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal) = 0; +	}; +	 +	class ReadResponder : public Responder +	{ +	public: +		ReadResponder(); +		void setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal); +		void setImage(LLImageFormatted* image) { mFormattedImage = image; } +	protected: +		LLPointer<LLImageFormatted> mFormattedImage; +		S32 mImageSize; +		BOOL mImageLocal; +	}; + +	class WriteResponder : public Responder +	{ +		void setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal) +		{ +			// not used +		} +	}; +	 +	LLTextureCache(bool threaded); +	~LLTextureCache(); + +	/*virtual*/ S32 update(U32 max_time_ms);	 +	 +	void purgeCache(ELLPath location); +	S64 initCache(ELLPath location, S64 maxsize, BOOL read_only); + +	handle_t readFromCache(const LLUUID& id, U32 priority, S32 offset, S32 size, +						   ReadResponder* responder); +	bool readComplete(handle_t handle, bool abort); +	handle_t writeToCache(const LLUUID& id, U32 priority, U8* data, S32 datasize, S32 imagesize, +						  WriteResponder* responder); +	bool writeComplete(handle_t handle, bool abort = false); +	void prioritizeWrite(handle_t handle); + +	void removeFromCache(const LLUUID& id); + +	// For LLTextureCacheWorker::Responder +	LLTextureCacheWorker* getReader(handle_t handle); +	LLTextureCacheWorker* getWriter(handle_t handle); +	void lockWorkers() { mWorkersMutex.lock(); } +	void unlockWorkers() { mWorkersMutex.unlock(); } + +	// debug +	S32 getNumReads() { return mReaders.size(); } +	S32 getNumWrites() { return mWriters.size(); } + +protected: +	// Accessed by LLTextureCacheWorker +	apr_pool_t* getFileAPRPool() { return mFileAPRPool; } +	bool appendToTextureEntryList(const LLUUID& id, S32 size); +	std::string getLocalFileName(const LLUUID& id); +	std::string getTextureFileName(const LLUUID& id); +	 +private: +	void setDirNames(ELLPath location); +	void readHeaderCache(apr_pool_t* poolp = NULL); +	void purgeAllTextures(bool purge_directories); +	void purgeTextures(bool validate); +	S32 getHeaderCacheEntry(const LLUUID& id, bool touch, S32* imagesize = NULL); +	bool removeHeaderCacheEntry(const LLUUID& id); +	void lockHeaders() { mHeaderMutex.lock(); } +	void unlockHeaders() { mHeaderMutex.unlock(); } +	 +private: +	// Internal +	LLMutex mWorkersMutex; +	LLMutex mHeaderMutex; +	apr_pool_t* mFileAPRPool; +	 +	typedef std::map<handle_t, LLTextureCacheWorker*> handle_map_t; +	handle_map_t mReaders; +	handle_map_t mWriters; +	std::vector<handle_t> mPrioritizeWriteList; +	 +	BOOL mReadOnly; +	 +	// Entries +	struct EntriesInfo +	{ +		F32 mVersion; +		U32 mEntries; +	}; +	struct Entry +	{ +		Entry() {} +		Entry(const LLUUID& id, S32 size, U32 time) : mID(id), mSize(size), mTime(time) {} +		LLUUID mID; // 128 bits +		S32 mSize; // total size of image if known (NOT size cached) +		U32 mTime; // seconds since 1/1/1970 +	}; + +	// HEADERS (Include first mip) +	std::string mHeaderEntriesFileName; +	std::string mHeaderDataFileName; +	EntriesInfo mHeaderEntriesInfo; +	typedef std::map<S32,LLUUID> index_map_t; +	index_map_t mLRU; // index, id; stored as a map for fast removal +	typedef std::map<LLUUID,S32> id_map_t; +	id_map_t mHeaderIDMap; + +	// BODIES (TEXTURES minus headers) +	std::string mTexturesDirName; +	std::string mTexturesDirEntriesFileName; +	typedef std::map<LLUUID,S32> size_map_t; +	size_map_t mTexturesSizeMap; +	S64 mTexturesSizeTotal; +	LLAtomic32<BOOL> mDoPurge; +	 +	// Statics +	static F32 sHeaderCacheVersion; +	static U32 sCacheMaxEntries; +	static S64 sCacheMaxTexturesSize; +}; + +#endif // LL_LLTEXTURECACHE_H diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index db747c60fc..4c90c3624b 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1205,9 +1205,9 @@ bool LLTextureFetchWorker::writeToCacheComplete()  LLTextureFetch::LLTextureFetch(LLTextureCache* cache, bool threaded)  	: LLWorkerThread("TextureFetch", threaded),  	  mDebugCount(0), -	  mDebugPause(0), -	  mTextureCache(cache), -	  mQueueMutex(getAPRPool()) +	  mDebugPause(FALSE), +	  mQueueMutex(getAPRPool()), +	  mTextureCache(cache)  {  } diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index b3510d9e82..7cf7cb45f2 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -82,4 +82,4 @@ private:  	LLFrameTimer mNetworkTimer;  }; -#endif LL_LLTEXTUREFETCH_H +#endif // LL_LLTEXTUREFETCH_H diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 837eaa90e9..f6fa23c6f6 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -582,6 +582,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield)  			gPipeline.stateSort(hud_cam);  		} +		if (LLVertexBuffer::sEnableVBOs) +		{ +			LLImageGL::sBoundTextureMemory += LLVertexBuffer::sAllocatedBytes; +		} +		  		gPipeline.renderGeom(hud_cam);  		//restore type mask @@ -716,9 +721,10 @@ void render_ui_and_swap()  		}  		{ -// 			LLFastTimer ftm(LLFastTimer::FTM_TEMP6); -			LLVertexBuffer::clientCopy(); + 			LLFastTimer ftm(LLFastTimer::FTM_CLIENT_COPY); +			LLVertexBuffer::clientCopy(0.016);  		} +  	}  } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 275db0f906..64560efd67 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -1134,6 +1134,9 @@ void init_debug_rendering_menu(LLMenuGL* menu)  	sub_menu->append(new LLMenuItemCheckGL("Texture Area (sqrt(A))",&LLPipeline::toggleRenderDebug, NULL,  													&LLPipeline::toggleRenderDebugControl,  													(void*)LLPipeline::RENDER_DEBUG_TEXTURE_AREA)); +	sub_menu->append(new LLMenuItemCheckGL("Face Area (sqrt(A))",&LLPipeline::toggleRenderDebug, NULL, +													&LLPipeline::toggleRenderDebugControl, +													(void*)LLPipeline::RENDER_DEBUG_FACE_AREA));  	sub_menu->append(new LLMenuItemCheckGL("Pick Render",	&LLPipeline::toggleRenderDebug, NULL,  													&LLPipeline::toggleRenderDebugControl,  													(void*)LLPipeline::RENDER_DEBUG_PICKING)); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 8ed5406e85..6d4170e437 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1357,7 +1357,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  			// Make sure the binary bucket is big enough to hold the header   			// and a null terminated item name. -			if ( (binary_bucket_size < (sizeof(notice_bucket_header_t) + sizeof(U8))) +			if ( (binary_bucket_size < (S32)((sizeof(notice_bucket_header_t) + sizeof(U8))))  				|| (binary_bucket[binary_bucket_size - 1] != '\0') )  			{  				llwarns << "Malformed group notice binary bucket" << llendl; diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp index b02985ddfa..189b314e55 100644 --- a/indra/newview/llviewernetwork.cpp +++ b/indra/newview/llviewernetwork.cpp @@ -71,4 +71,4 @@ F32 gPacketDropPercentage = 0.f;  F32 gInBandwidth = 0.f;  F32 gOutBandwidth = 0.f; -unsigned char gMACAddress[MAC_ADDRESS_BYTES];		/* Flawfinder: ignore */
\ No newline at end of file +unsigned char gMACAddress[MAC_ADDRESS_BYTES];		/* Flawfinder: ignore */ diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index cd915317ba..ee29876274 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -2523,9 +2523,9 @@ LLParcelSelection::LLParcelSelection() :  	mParcel(NULL),  	mSelectedMultipleOwners(FALSE),  	mWholeParcelSelected(FALSE), -	mSelectedPublicCount(0),  	mSelectedSelfCount(0), -	mSelectedOtherCount(0) +	mSelectedOtherCount(0), +	mSelectedPublicCount(0)  {  } @@ -2533,9 +2533,9 @@ LLParcelSelection::LLParcelSelection(LLParcel* parcel)  :  	mParcel(parcel),  	mSelectedMultipleOwners(FALSE),  	mWholeParcelSelected(FALSE), -	mSelectedPublicCount(0),  	mSelectedSelfCount(0), -	mSelectedOtherCount(0) +	mSelectedOtherCount(0), +	mSelectedPublicCount(0)  {  } @@ -2570,4 +2570,4 @@ LLParcelSelection* get_null_parcel_selection()  {  	static LLParcelSelectionHandle null_ptr = new LLParcelSelection();  	return null_ptr; -}
\ No newline at end of file +} diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index aebcfdb9ce..36c08321ed 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1842,13 +1842,6 @@ void LLViewerWindow::reshape(S32 width, S32 height)  		gViewerStats->setStat(LLViewerStats::ST_WINDOW_WIDTH, (F64)width);  		gViewerStats->setStat(LLViewerStats::ST_WINDOW_HEIGHT, (F64)height); - -		//reposition HUD attachments -		LLVOAvatar* avatarp = gAgent.getAvatarObject(); -		if (avatarp) -		{ -			avatarp->resetHUDAttachments(); -		}  	}  } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 507a1468c7..afeffa0aec 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -748,9 +748,9 @@ LLVOAvatar::LLVOAvatar(  	mLastSkirtBakedID( IMG_DEFAULT_AVATAR ),  	mIsDummy(FALSE),  	mSpecialRenderMode(0), +	mTurning(FALSE),  	mPelvisToFoot(0.f),  	mLastSkeletonSerialNum( 0 ), -	mTurning(FALSE),  	mHeadOffset(),  	mIsSitting(FALSE),  	mTimeVisible(), @@ -3005,8 +3005,12 @@ void LLVOAvatar::updateCharacter(LLAgent &agent)  	{  		F32 aspect = gCamera->getAspect();  		LLVector3 scale(1.f, aspect, 1.f); -		mScreenp->setScale(scale); -		mScreenp->updateWorldMatrixChildren(); +		if (mScreenp->getScale() != scale) +		{ +			mScreenp->setScale(scale); +			mScreenp->updateWorldMatrixChildren(); +			resetHUDAttachments(); +		}  	}  	// clear debug text diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 2d898a1a5d..d08c5311d7 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -244,7 +244,7 @@ BOOL LLVOVolume::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)  		S32 result;  		if (result = mTextureAnimp->animateTextures(off_s, off_t, scale_s, scale_t, rot))  		{ -			mTexAnimMode = result | mTextureAnimp->mMode; +			mTexAnimMode = mTextureAnimp->mMode | result;  			S32 start, end;  			if (mTextureAnimp->mFace == -1) @@ -309,6 +309,13 @@ BOOL LLVOVolume::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)  				tex_mat.translate(trans);  			}  		} +		else +		{ +			if (mTextureAnimp->mRate == 0) +			{ +				mTexAnimMode = 0; +			} +		}  	}  	// Dispatch to implementation @@ -349,17 +356,18 @@ void LLVOVolume::updateTextures()  	mTextureUpdateTimer.reset(); +	F32 old_area = mPixelArea;  	mPixelArea = 0.f; -	const S32 num_faces = mDrawable->getNumFaces(); +	const S32 num_faces = mDrawable->getNumFaces();  	F32 min_vsize=999999999.f, max_vsize=0.f;  	for (S32 i = 0; i < num_faces; i++)  	{  		LLFace* face = mDrawable->getFace(i);  		const LLTextureEntry *te = face->getTextureEntry();  		LLViewerImage *imagep = face->getTexture(); - -		if (!imagep || !te) +		if (!imagep || !te || +			face->mExtents[0] == face->mExtents[1])  		{  			continue;  		} @@ -392,11 +400,12 @@ void LLVOVolume::updateTextures()  			if (pri < min_vsize) min_vsize = pri;  			if (pri > max_vsize) max_vsize = pri;  		} -	//	U8 bump = te->getBumpmap(); -	//	if( te && bump) -	//	{ -	//		gBumpImageList.addTextureStats( bump, imagep->getID(), vsize, 1, 1); -	//	} +		else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA)) +		{ +			F32 pri = mPixelArea; +			if (pri < min_vsize) min_vsize = pri; +			if (pri > max_vsize) max_vsize = pri; +		}	  	}  	if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) @@ -407,15 +416,22 @@ void LLVOVolume::updateTextures()  	{  		setDebugText(llformat("%.0f:%.0f", fsqrtf(min_vsize),fsqrtf(max_vsize)));  	} +	else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA)) +	{ +		setDebugText(llformat("%.0f:%.0f", fsqrtf(min_vsize),fsqrtf(max_vsize))); +	} + +	if (mPixelArea == 0) +	{ //flexi phasing issues make this happen +		mPixelArea = old_area; +	}  }  F32 LLVOVolume::getTextureVirtualSize(LLFace* face)  {  	//get area of circle around face  	LLVector3 center = face->getPositionAgent(); -	LLVector3 size = //isFlexible() ?  -					//	getScale()*3.f : -						(face->mExtents[1] - face->mExtents[0]) * 0.5f; +	LLVector3 size = (face->mExtents[1] - face->mExtents[0]) * 0.5f;  	F32 face_area = LLPipeline::calcPixelArea(center, size, *gCamera); @@ -585,9 +601,6 @@ BOOL LLVOVolume::calcLOD()  		return FALSE;  	} -	//update textures here as well -	updateTextures(); -  	S32 cur_detail = 0;  	F32 radius = mVolumep->mLODScaleBias.scaledVec(getScale()).magVec(); @@ -689,6 +702,17 @@ void LLVOVolume::updateFaceFlags()  	}  } +void LLVOVolume::setParent(LLViewerObject* parent) +{ +	LLViewerObject::setParent(parent); +	if (mDrawable) +	{ +		gPipeline.markMoved(mDrawable); +		mVolumeChanged = TRUE; +		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); +	} +} +  // NOTE: regenFaces() MUST be followed by genTriangles()!  void LLVOVolume::regenFaces()  { @@ -748,6 +772,8 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)  	{  		mDrawable->setSpatialExtents(min,max);  		mDrawable->setPositionGroup((min+max)*0.5f);	 +		//bounding boxes changed, update texture priorities +		updateTextures();  	}  	updateRadius(); @@ -1918,8 +1944,10 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  		draw_vec[idx]->mVertexBuffer == facep->mVertexBuffer &&  		draw_vec[idx]->mEnd == facep->getGeomIndex()-1 &&  		draw_vec[idx]->mTexture == tex && -		//draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange && -		//draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && +#if LL_DARWIN +		draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange && +		draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && +#endif  		draw_vec[idx]->mFullbright == fullbright &&  		draw_vec[idx]->mBump == bump &&  		draw_vec[idx]->mTextureMatrix == tex_mat) @@ -2220,7 +2248,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  					registerFace(group, facep, LLRenderPass::PASS_BUMP);  				} -				if (!force_simple && vobj->getIsLight()) +				if (vobj->getIsLight())  				{  					registerFace(group, facep, LLRenderPass::PASS_GLOW);  				} diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 3eb8ad6c14..76b469e6aa 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -79,7 +79,7 @@ public:  	/*virtual*/ BOOL	isHUDAttachment() const;  				void	generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point); - +	/*virtual*/	void	setParent(LLViewerObject* parent);  				F32		getIndividualRadius()					{ return mRadius; }  				S32		getLOD() const							{ return mLOD; }  	const LLVector3		getPivotPositionAgent() const; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 250b9bc7df..d7abae32c8 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -212,6 +212,8 @@ BOOL	LLPipeline::sSkipUpdate = FALSE;  BOOL	LLPipeline::sDynamicReflections = FALSE;  LLPipeline::LLPipeline() : +	mCubeBuffer(NULL), +	mCubeList(0),  	mVertexShadersEnabled(FALSE),  	mVertexShadersLoaded(0),  	mLastRebuildPool(NULL), @@ -225,9 +227,7 @@ LLPipeline::LLPipeline() :  	mSimplePool(NULL),  	mBumpPool(NULL),  	mLightMask(0), -	mLightMovingMask(0), -	mCubeBuffer(NULL), -	mCubeList(0) +	mLightMovingMask(0)  {  } @@ -1710,7 +1710,6 @@ void LLPipeline::updateMove()  F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera)  {  	LLVector3 lookAt = center - camera.getOrigin(); -	LLVector3 cross_vec = size * 2.f;	  	F32 dist = lookAt.magVec();  	//ramp down distance for nearby objects @@ -1722,7 +1721,7 @@ F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera  	}  	//get area of circle around node -	F32 app_angle = atanf((cross_vec*0.5f).magVec()/dist); +	F32 app_angle = atanf(size.magVec()/dist);  	F32 radius = app_angle*LLDrawable::sCurPixelAngle;  	return radius*radius * 3.14159f;  } @@ -2196,10 +2195,12 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)  		}  	} +#if !LL_DARWIN  	if (gFrameTimeSeconds - group->mLastUpdateTime > 4.f)  	{  		group->makeStatic();  	} +#endif  }  void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index c744a29bec..0fadae0a61 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -325,7 +325,8 @@ public:  		RENDER_DEBUG_POINTS				= 0x02000,  		RENDER_DEBUG_TEXTURE_PRIORITY	= 0x04000,  		RENDER_DEBUG_TEXTURE_AREA		= 0x08000, -		RENDER_DEBUG_PARTICLES			= 0x10000, +		RENDER_DEBUG_FACE_AREA			= 0x10000, +		RENDER_DEBUG_PARTICLES			= 0x20000,  	};  	LLPointer<LLViewerImage>	mAlphaSizzleImagep; | 
