diff options
66 files changed, 969 insertions, 715 deletions
@@ -229,3 +229,5 @@ c4911ec8cd81e676dfd2af438b3e065407a94a7a 3.2.1-start a8c7030d6845186fac7c188be4323a0e887b4184 DRTVWR-99_3.2.1-release a8c7030d6845186fac7c188be4323a0e887b4184 3.2.1-release 3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-start +3fe994349fae64fc40874bb59db387131eb35a41 DRTVWR-104_3.2.4-beta1 +3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-beta1 diff --git a/doc/contributions.txt b/doc/contributions.txt index 9f6de781b4..274632a804 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -171,6 +171,7 @@ Ansariel Hiller VWR-25480 VWR-26150 STORM-1685 + STORM-1713 Aralara Rajal Ardy Lay STORM-859 @@ -583,12 +584,17 @@ Jonathan Yap STORM-1639 STORM-910 STORM-1642 + STORM-591 STORM-1105 STORM-1679 STORM-1222 STORM-1659 STORM-1674 STORM-1685 + STORM-1721 + STORM-1719 + STORM-1712 + STORM-1728 Kadah Coba STORM-1060 Jondan Lundquist @@ -923,6 +929,7 @@ Robin Cornelius SNOW-599 SNOW-747 STORM-422 + STORM-591 STORM-960 STORM-1019 STORM-1095 diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index 5e540ad8c5..5fa28cb902 100644 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -1264,6 +1264,7 @@ LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32 mSyncSlave(false), mQueueSounds(false), mPlayedOnce(false), + mCorrupted(false), mType(type), mChannelp(NULL), mCurrentDatap(NULL), @@ -1296,16 +1297,25 @@ void LLAudioSource::setChannel(LLAudioChannel *channelp) void LLAudioSource::update() { + if(mCorrupted) + { + return ; //no need to update + } + if (!getCurrentBuffer()) { if (getCurrentData()) { // Hack - try and load the sound. Will do this as a callback // on decode later. - if (getCurrentData()->load()) + if (getCurrentData()->load() && getCurrentData()->getBuffer()) { play(getCurrentData()->getID()); - } + } + else + { + mCorrupted = true ; + } } } } @@ -1421,6 +1431,11 @@ bool LLAudioSource::play(const LLUUID &audio_uuid) bool LLAudioSource::isDone() const { + if(mCorrupted) + { + return true ; + } + const F32 MAX_AGE = 60.f; const F32 MAX_UNPLAYED_AGE = 15.f; const F32 MAX_MUTED_AGE = 11.f; @@ -1736,7 +1751,7 @@ LLAudioData::LLAudioData(const LLUUID &uuid) : } } - +//return false when the audio file is corrupted. bool LLAudioData::load() { // For now, just assume we're going to use one buffer per audiodata. @@ -1752,7 +1767,7 @@ bool LLAudioData::load() { // No free buffers, abort. llinfos << "Not able to allocate a new audio buffer, aborting." << llendl; - return false; + return true; } std::string uuid_str; diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h index 30d2490635..a47ee7ca7c 100644 --- a/indra/llaudio/llaudioengine.h +++ b/indra/llaudio/llaudioengine.h @@ -334,6 +334,7 @@ protected: bool mSyncSlave; bool mQueueSounds; bool mPlayedOnce; + bool mCorrupted; S32 mType; LLVector3d mPositionGlobal; LLVector3 mVelocity; diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index 5dee7a3541..1738c16dea 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -109,7 +109,7 @@ void LLQueuedThread::shutdown() // MAIN THREAD // virtual -S32 LLQueuedThread::update(U32 max_time_ms) +S32 LLQueuedThread::update(F32 max_time_ms) { if (!mStarted) { @@ -122,7 +122,7 @@ S32 LLQueuedThread::update(U32 max_time_ms) return updateQueue(max_time_ms); } -S32 LLQueuedThread::updateQueue(U32 max_time_ms) +S32 LLQueuedThread::updateQueue(F32 max_time_ms) { F64 max_time = (F64)max_time_ms * .001; LLTimer timer; diff --git a/indra/llcommon/llqueuedthread.h b/indra/llcommon/llqueuedthread.h index 499d13a792..d3704b0fe2 100644 --- a/indra/llcommon/llqueuedthread.h +++ b/indra/llcommon/llqueuedthread.h @@ -173,8 +173,8 @@ protected: public: bool waitForResult(handle_t handle, bool auto_complete = true); - virtual S32 update(U32 max_time_ms); - S32 updateQueue(U32 max_time_ms); + virtual S32 update(F32 max_time_ms); + S32 updateQueue(F32 max_time_ms); void waitOnPending(); void printQueueStats(); diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index 6ca0737445..e295e3c621 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -24,6 +24,9 @@ * $/LicenseInfo$ */ +// Must turn on conditional declarations in header file so definitions end up +// with proper linkage. +#define LLSD_DEBUG_INFO #include "linden_common.h" #include "llsd.h" @@ -31,6 +34,7 @@ #include "../llmath/llmath.h" #include "llformat.h" #include "llsdserialize.h" +#include "stringize.h" #ifndef LL_RELEASE_FOR_DOWNLOAD #define NAME_UNNAMED_NAMESPACE @@ -50,6 +54,18 @@ namespace using namespace LLSDUnnamedNamespace; #endif +namespace llsd +{ + +// statics +S32 sLLSDAllocationCount = 0; +S32 sLLSDNetObjects = 0; + +} // namespace llsd + +#define ALLOC_LLSD_OBJECT { llsd::sLLSDNetObjects++; llsd::sLLSDAllocationCount++; } +#define FREE_LLSD_OBJECT { llsd::sLLSDNetObjects--; } + class LLSD::Impl /**< This class is the abstract base class of the implementation of LLSD It provides the reference counting implementation, and the default @@ -58,13 +74,10 @@ class LLSD::Impl */ { -private: - U32 mUseCount; - protected: Impl(); - enum StaticAllocationMarker { STATIC }; + enum StaticAllocationMarker { STATIC_USAGE_COUNT = 0xFFFFFFFF }; Impl(StaticAllocationMarker); ///< This constructor is used for static objects and causes the // suppresses adjusting the debugging counters when they are @@ -72,8 +85,10 @@ protected: virtual ~Impl(); - bool shared() const { return mUseCount > 1; } + bool shared() const { return (mUseCount > 1) && (mUseCount != STATIC_USAGE_COUNT); } + U32 mUseCount; + public: static void reset(Impl*& var, Impl* impl); ///< safely set var to refer to the new impl (possibly shared) @@ -128,6 +143,18 @@ public: virtual LLSD::array_const_iterator beginArray() const { return endArray(); } virtual LLSD::array_const_iterator endArray() const { static const std::vector<LLSD> empty; return empty.end(); } + virtual void dumpStats() const; + virtual void calcStats(S32 type_counts[], S32 share_counts[]) const; + // Container subclasses contain LLSD objects, rather than directly + // containing Impl objects. This helper forwards through LLSD. + void calcStats(const LLSD& llsd, S32 type_counts[], S32 share_counts[]) const + { + safe(llsd.impl).calcStats(type_counts, share_counts); + } + + static const Impl& getImpl(const LLSD& llsd) { return safe(llsd.impl); } + static Impl& getImpl(LLSD& llsd) { return safe(llsd.impl); } + static const LLSD& undef(); static U32 sAllocationCount; @@ -360,6 +387,9 @@ namespace LLSD::map_iterator endMap() { return mData.end(); } virtual LLSD::map_const_iterator beginMap() const { return mData.begin(); } virtual LLSD::map_const_iterator endMap() const { return mData.end(); } + + virtual void dumpStats() const; + virtual void calcStats(S32 type_counts[], S32 share_counts[]) const; }; ImplMap& ImplMap::makeMap(LLSD::Impl*& var) @@ -414,6 +444,34 @@ namespace return i->second; } + void ImplMap::dumpStats() const + { + std::cout << "Map size: " << mData.size() << std::endl; + + std::cout << "LLSD Net Objects: " << llsd::sLLSDNetObjects << std::endl; + std::cout << "LLSD allocations: " << llsd::sLLSDAllocationCount << std::endl; + + std::cout << "LLSD::Impl Net Objects: " << sOutstandingCount << std::endl; + std::cout << "LLSD::Impl allocations: " << sAllocationCount << std::endl; + + Impl::dumpStats(); + } + + void ImplMap::calcStats(S32 type_counts[], S32 share_counts[]) const + { + LLSD::map_const_iterator iter = beginMap(); + while (iter != endMap()) + { + //std::cout << " " << (*iter).first << ": " << (*iter).second << std::endl; + Impl::calcStats((*iter).second, type_counts, share_counts); + iter++; + } + + // Add in the values for this map + Impl::calcStats(type_counts, share_counts); + } + + class ImplArray : public LLSD::Impl { private: @@ -449,6 +507,8 @@ namespace LLSD::array_iterator endArray() { return mData.end(); } virtual LLSD::array_const_iterator beginArray() const { return mData.begin(); } virtual LLSD::array_const_iterator endArray() const { return mData.end(); } + + virtual void calcStats(S32 type_counts[], S32 share_counts[]) const; }; ImplArray& ImplArray::makeArray(Impl*& var) @@ -490,12 +550,13 @@ namespace void ImplArray::insert(LLSD::Integer i, const LLSD& v) { - if (i < 0) { + if (i < 0) + { return; } DataVector::size_type index = i; - if (index >= mData.size()) + if (index >= mData.size()) // tbd - sanity check limit for index ? { mData.resize(index + 1); } @@ -543,6 +604,19 @@ namespace return mData[index]; } + + void ImplArray::calcStats(S32 type_counts[], S32 share_counts[]) const + { + LLSD::array_const_iterator iter = beginArray(); + while (iter != endArray()) + { // Add values for all items held in the array + Impl::calcStats((*iter), type_counts, share_counts); + iter++; + } + + // Add in the values for this array + Impl::calcStats(type_counts, share_counts); + } } LLSD::Impl::Impl() @@ -564,8 +638,11 @@ LLSD::Impl::~Impl() void LLSD::Impl::reset(Impl*& var, Impl* impl) { - if (impl) ++impl->mUseCount; - if (var && --var->mUseCount == 0) + if (impl && impl->mUseCount != STATIC_USAGE_COUNT) + { + ++impl->mUseCount; + } + if (var && var->mUseCount != STATIC_USAGE_COUNT && --var->mUseCount == 0) { delete var; } @@ -574,13 +651,13 @@ void LLSD::Impl::reset(Impl*& var, Impl* impl) LLSD::Impl& LLSD::Impl::safe(Impl* impl) { - static Impl theUndefined(STATIC); + static Impl theUndefined(STATIC_USAGE_COUNT); return impl ? *impl : theUndefined; } const LLSD::Impl& LLSD::Impl::safe(const Impl* impl) { - static Impl theUndefined(STATIC); + static Impl theUndefined(STATIC_USAGE_COUNT); return impl ? *impl : theUndefined; } @@ -656,6 +733,43 @@ const LLSD& LLSD::Impl::undef() return immutableUndefined; } +void LLSD::Impl::dumpStats() const +{ + S32 type_counts[LLSD::TypeLLSDNumTypes + 1]; + memset(&type_counts, 0, sizeof(type_counts)); + + S32 share_counts[LLSD::TypeLLSDNumTypes + 1]; + memset(&share_counts, 0, sizeof(share_counts)); + + // Add info from all the values this object has + calcStats(type_counts, share_counts); + + S32 type_index = LLSD::TypeLLSDTypeBegin; + while (type_index != LLSD::TypeLLSDTypeEnd) + { + std::cout << LLSD::typeString((LLSD::Type)type_index) << " type " + << type_counts[type_index] << " objects, " + << share_counts[type_index] << " shared" + << std::endl; + type_index++; + } +} + + +void LLSD::Impl::calcStats(S32 type_counts[], S32 share_counts[]) const +{ + S32 tp = S32(type()); + if (0 <= tp && tp < LLSD::TypeLLSDNumTypes) + { + type_counts[tp]++; + if (shared()) + { + share_counts[tp]++; + } + } +} + + U32 LLSD::Impl::sAllocationCount = 0; U32 LLSD::Impl::sOutstandingCount = 0; @@ -681,10 +795,10 @@ namespace } -LLSD::LLSD() : impl(0) { } -LLSD::~LLSD() { Impl::reset(impl, 0); } +LLSD::LLSD() : impl(0) { ALLOC_LLSD_OBJECT; } +LLSD::~LLSD() { FREE_LLSD_OBJECT; Impl::reset(impl, 0); } -LLSD::LLSD(const LLSD& other) : impl(0) { assign(other); } +LLSD::LLSD(const LLSD& other) : impl(0) { ALLOC_LLSD_OBJECT; assign(other); } void LLSD::assign(const LLSD& other) { Impl::assign(impl, other.impl); } @@ -692,18 +806,18 @@ void LLSD::clear() { Impl::assignUndefined(impl); } LLSD::Type LLSD::type() const { return safe(impl).type(); } -// Scaler Constructors -LLSD::LLSD(Boolean v) : impl(0) { assign(v); } -LLSD::LLSD(Integer v) : impl(0) { assign(v); } -LLSD::LLSD(Real v) : impl(0) { assign(v); } -LLSD::LLSD(const UUID& v) : impl(0) { assign(v); } -LLSD::LLSD(const String& v) : impl(0) { assign(v); } -LLSD::LLSD(const Date& v) : impl(0) { assign(v); } -LLSD::LLSD(const URI& v) : impl(0) { assign(v); } -LLSD::LLSD(const Binary& v) : impl(0) { assign(v); } +// Scalar Constructors +LLSD::LLSD(Boolean v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } +LLSD::LLSD(Integer v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } +LLSD::LLSD(Real v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } +LLSD::LLSD(const UUID& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } +LLSD::LLSD(const String& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } +LLSD::LLSD(const Date& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } +LLSD::LLSD(const URI& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } +LLSD::LLSD(const Binary& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } // Convenience Constructors -LLSD::LLSD(F32 v) : impl(0) { assign((Real)v); } +LLSD::LLSD(F32 v) : impl(0) { ALLOC_LLSD_OBJECT; assign((Real)v); } // Scalar Assignment void LLSD::assign(Boolean v) { safe(impl).assign(impl, v); } @@ -726,7 +840,7 @@ LLSD::URI LLSD::asURI() const { return safe(impl).asURI(); } LLSD::Binary LLSD::asBinary() const { return safe(impl).asBinary(); } // const char * helpers -LLSD::LLSD(const char* v) : impl(0) { assign(v); } +LLSD::LLSD(const char* v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } void LLSD::assign(const char* v) { if(v) assign(std::string(v)); @@ -784,9 +898,6 @@ LLSD& LLSD::operator[](Integer i) const LLSD& LLSD::operator[](Integer i) const { return safe(impl).ref(i); } -U32 LLSD::allocationCount() { return Impl::sAllocationCount; } -U32 LLSD::outstandingCount() { return Impl::sOutstandingCount; } - static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat) { // sStorage is used to hold the string representation of the llsd last @@ -801,15 +912,9 @@ static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat) { std::ostringstream out; if (useXMLFormat) - { - LLSDXMLStreamer xml_streamer(llsd); - out << xml_streamer; - } + out << LLSDXMLStreamer(llsd); else - { - LLSDNotationStreamer notation_streamer(llsd); - out << notation_streamer; - } + out << LLSDNotationStreamer(llsd); out_string = out.str(); } int len = out_string.length(); @@ -840,3 +945,38 @@ LLSD::array_iterator LLSD::beginArray() { return makeArray(impl).beginArray(); LLSD::array_iterator LLSD::endArray() { return makeArray(impl).endArray(); } LLSD::array_const_iterator LLSD::beginArray() const{ return safe(impl).beginArray(); } LLSD::array_const_iterator LLSD::endArray() const { return safe(impl).endArray(); } + +namespace llsd +{ + +U32 allocationCount() { return LLSD::Impl::sAllocationCount; } +U32 outstandingCount() { return LLSD::Impl::sOutstandingCount; } + +// Diagnostic dump of contents in an LLSD object +void dumpStats(const LLSD& llsd) { LLSD::Impl::getImpl(llsd).dumpStats(); } + +} // namespace llsd + +// static +std::string LLSD::typeString(Type type) +{ + static const char * sTypeNameArray[] = { + "Undefined", + "Boolean", + "Integer", + "Real", + "String", + "UUID", + "Date", + "URI", + "Binary", + "Map", + "Array" + }; + + if (0 <= type && type < LL_ARRAY_SIZE(sTypeNameArray)) + { + return sTypeNameArray[type]; + } + return STRINGIZE("** invalid type value " << type); +} diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h index 90d0f97873..5eb69059ac 100644 --- a/indra/llcommon/llsd.h +++ b/indra/llcommon/llsd.h @@ -40,10 +40,10 @@ /** LLSD provides a flexible data system similar to the data facilities of dynamic languages like Perl and Python. It is created to support exchange - of structured data between loosly coupled systems. (Here, "loosly coupled" + of structured data between loosely coupled systems. (Here, "loosely coupled" means not compiled together into the same module.) - Data in such exchanges must be highly tollerant of changes on either side + Data in such exchanges must be highly tolerant of changes on either side such as: - recompilation - implementation in a different langauge @@ -51,19 +51,19 @@ - execution of older versions (with fewer parameters) To this aim, the C++ API of LLSD strives to be very easy to use, and to - default to "the right thing" whereever possible. It is extremely tollerant + default to "the right thing" wherever possible. It is extremely tolerant of errors and unexpected situations. - The fundimental class is LLSD. LLSD is a value holding object. It holds + The fundamental class is LLSD. LLSD is a value holding object. It holds one value that is either undefined, one of the scalar types, or a map or an array. LLSD objects have value semantics (copying them copies the value, - though it can be considered efficient, due to shareing.), and mutable. + though it can be considered efficient, due to sharing), and mutable. Undefined is the singular value given to LLSD objects that are not initialized with any data. It is also used as the return value for - operations that return an LLSD, + operations that return an LLSD. - The sclar data types are: + The scalar data types are: - Boolean - true or false - Integer - a 32 bit signed integer - Real - a 64 IEEE 754 floating point value @@ -80,9 +80,73 @@ An array is a sequence of zero or more LLSD values. + Thread Safety + + In general, these LLSD classes offer *less* safety than STL container + classes. Implementations prior to this one were unsafe even when + completely unrelated LLSD trees were in two threads due to reference + sharing of special 'undefined' values that participated in the reference + counting mechanism. + + The dereference-before-refcount and aggressive tree sharing also make + it impractical to share an LLSD across threads. A strategy of passing + ownership or a copy to another thread is still difficult due to a lack + of a cloning interface but it can be done with some care. + + One way of transferring ownership is as follows: + + void method(const LLSD input) { + ... + LLSD * xfer_tree = new LLSD(); + { + // Top-level values + (* xfer_tree)['label'] = "Some text"; + (* xfer_tree)['mode'] = APP_MODE_CONSTANT; + + // There will be a second-level + LLSD subtree(LLSD::emptyMap()); + (* xfer_tree)['subtree'] = subtree; + + // Do *not* copy from LLSD objects via LLSD + // intermediaries. Only use plain-old-data + // types as intermediaries to prevent reference + // sharing. + subtree['value1'] = input['value1'].asInteger(); + subtree['value2'] = input['value2'].asString(); + + // Close scope and drop 'subtree's reference. + // Only xfer_tree has a reference to the second + // level data. + } + ... + // Transfer the LLSD pointer to another thread. Ownership + // transfers, this thread no longer has a reference to any + // part of the xfer_tree and there's nothing to free or + // release here. Receiving thread does need to delete the + // pointer when it is done with the LLSD. Transfer + // mechanism must perform correct data ordering operations + // as dictated by architecture. + other_thread.sendMessageAndPointer("Take This", xfer_tree); + xfer_tree = NULL; + + + Avoid this pattern which provides half of a race condition: + + void method(const LLSD input) { + ... + LLSD xfer_tree(LLSD::emptyMap()); + xfer_tree['label'] = "Some text"; + xfer_tree['mode'] = APP_MODE_CONSTANT; + ... + other_thread.sendMessageAndPointer("Take This", xfer_tree); + + @nosubgrouping */ +// Normally undefined, used for diagnostics +//#define LLSD_DEBUG_INFO 1 + class LL_COMMON_API LLSD { public: @@ -202,7 +266,7 @@ public: //@} /** @name Character Pointer Helpers - These are helper routines to make working with char* the same as easy as + These are helper routines to make working with char* as easy as working with strings. */ //@{ @@ -266,7 +330,7 @@ public: /** @name Type Testing */ //@{ enum Type { - TypeUndefined, + TypeUndefined = 0, TypeBoolean, TypeInteger, TypeReal, @@ -276,7 +340,10 @@ public: TypeURI, TypeBinary, TypeMap, - TypeArray + TypeArray, + TypeLLSDTypeEnd, + TypeLLSDTypeBegin = TypeUndefined, + TypeLLSDNumTypes = (TypeLLSDTypeEnd - TypeLLSDTypeBegin) }; Type type() const; @@ -302,7 +369,7 @@ public: If you get a linker error about these being missing, you have made mistake in your code. DO NOT IMPLEMENT THESE FUNCTIONS as a fix. - All of thse problems stem from trying to support char* in LLSD or in + All of these problems stem from trying to support char* in LLSD or in std::string. There are too many automatic casts that will lead to using an arbitrary pointer or scalar type to std::string. */ @@ -311,7 +378,7 @@ public: void assign(const void*); ///< assign from arbitrary pointers LLSD& operator=(const void*); ///< assign from arbitrary pointers - bool has(Integer) const; ///< has only works for Maps + bool has(Integer) const; ///< has() only works for Maps //@} /** @name Implementation */ @@ -320,13 +387,7 @@ public: class Impl; private: Impl* impl; - //@} - - /** @name Unit Testing Interface */ - //@{ -public: - static U32 allocationCount(); ///< how many Impls have been made - static U32 outstandingCount(); ///< how many Impls are still alive + friend class LLSD::Impl; //@} private: @@ -338,6 +399,10 @@ private: /// Returns Notation version of llsd -- only to be called from debugger static const char *dump(const LLSD &llsd); //@} + +public: + + static std::string typeString(Type type); // Return human-readable type as a string }; struct llsd_select_bool : public std::unary_function<LLSD, LLSD::Boolean> @@ -385,9 +450,32 @@ struct llsd_select_string : public std::unary_function<LLSD, LLSD::String> LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLSD& llsd); +namespace llsd +{ + +#ifdef LLSD_DEBUG_INFO +/** @name Unit Testing Interface */ +//@{ + LL_COMMON_API void dumpStats(const LLSD&); ///< Output information on object and usage + + /// @warn THE FOLLOWING COUNTS WILL NOT BE ACCURATE IN A MULTI-THREADED + /// ENVIRONMENT. + /// + /// These counts track LLSD::Impl (hidden) objects. + LL_COMMON_API U32 allocationCount(); ///< how many Impls have been made + LL_COMMON_API U32 outstandingCount(); ///< how many Impls are still alive + + /// These counts track LLSD (public) objects. + LL_COMMON_API extern S32 sLLSDAllocationCount; ///< Number of LLSD objects ever created + LL_COMMON_API extern S32 sLLSDNetObjects; ///< Number of LLSD objects that exist +#endif +//@} + +} // namespace llsd + /** QUESTIONS & TO DOS - - Would Binary be more convenient as usigned char* buffer semantics? - - Should Binary be convertable to/from String, and if so how? + - Would Binary be more convenient as unsigned char* buffer semantics? + - Should Binary be convertible to/from String, and if so how? - as UTF8 encoded strings (making not like UUID<->String) - as Base64 or Base96 encoded (making like UUID<->String) - Conversions to std::string and LLUUID do not result in easy assignment diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp index 4988bdf570..3d05a30ac2 100644 --- a/indra/llcommon/llworkerthread.cpp +++ b/indra/llcommon/llworkerthread.cpp @@ -81,7 +81,7 @@ void LLWorkerThread::clearDeleteList() } // virtual -S32 LLWorkerThread::update(U32 max_time_ms) +S32 LLWorkerThread::update(F32 max_time_ms) { S32 res = LLQueuedThread::update(max_time_ms); // Delete scheduled workers diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h index 78a4781d15..be46394d6e 100644 --- a/indra/llcommon/llworkerthread.h +++ b/indra/llcommon/llworkerthread.h @@ -86,7 +86,7 @@ public: LLWorkerThread(const std::string& name, bool threaded = true, bool should_pause = false); ~LLWorkerThread(); - /*virtual*/ S32 update(U32 max_time_ms); + /*virtual*/ S32 update(F32 max_time_ms); handle_t addWorkRequest(LLWorkerClass* workerclass, S32 param, U32 priority = PRIORITY_NORMAL); diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp index 28dc3bd313..ad2eb0f69c 100644 --- a/indra/llimage/llimageworker.cpp +++ b/indra/llimage/llimageworker.cpp @@ -46,7 +46,7 @@ LLImageDecodeThread::~LLImageDecodeThread() // MAIN THREAD // virtual -S32 LLImageDecodeThread::update(U32 max_time_ms) +S32 LLImageDecodeThread::update(F32 max_time_ms) { LLMutexLock lock(mCreationMutex); for (creation_list_t::iterator iter = mCreationList.begin(); diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h index c684222fa5..1bfb0ddfd3 100644 --- a/indra/llimage/llimageworker.h +++ b/indra/llimage/llimageworker.h @@ -78,7 +78,7 @@ public: handle_t decodeImage(LLImageFormatted* image, U32 priority, S32 discard, BOOL needs_aux, Responder* responder); - S32 update(U32 max_time_ms); + S32 update(F32 max_time_ms); // Used by unit tests to check the consistency of the thread instance S32 tut_size(); diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 7ca25d07fc..ce0632668c 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -841,7 +841,7 @@ LLCurlThread::~LLCurlThread() { } -S32 LLCurlThread::update(U32 max_time_ms) +S32 LLCurlThread::update(F32 max_time_ms) { return LLQueuedThread::update(max_time_ms); } diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index a275db3e53..2c95279438 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -344,7 +344,7 @@ public: LLCurlThread(bool threaded = true) ; virtual ~LLCurlThread() ; - S32 update(U32 max_time_ms); + S32 update(F32 max_time_ms); void addMulti(LLCurl::Multi* multi) ; void killMulti(LLCurl::Multi* multi) ; diff --git a/indra/llmessage/llsdmessagereader.cpp b/indra/llmessage/llsdmessagereader.cpp index 304a692cdf..3ab62a8c57 100644 --- a/indra/llmessage/llsdmessagereader.cpp +++ b/indra/llmessage/llsdmessagereader.cpp @@ -291,6 +291,7 @@ S32 getElementSize(const LLSD& llsd) case LLSD::TypeMap: case LLSD::TypeArray: case LLSD::TypeUndefined: + default: // TypeLLSDTypeEnd, TypeLLSDNumTypes, etc. return 0; } return 0; diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 812fa7024b..cd827f5091 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -1444,6 +1444,11 @@ const glh::matrix4f& LLRender::getModelviewMatrix() return mMatrix[MM_MODELVIEW][mMatIdx[MM_MODELVIEW]]; } +const glh::matrix4f& LLRender::getProjectionMatrix() +{ + return mMatrix[MM_PROJECTION][mMatIdx[MM_PROJECTION]]; +} + void LLRender::translateUI(F32 x, F32 y, F32 z) { if (mUIOffset.empty()) diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 7581b9f908..fa5f7f311d 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -348,6 +348,7 @@ public: void matrixMode(U32 mode); const glh::matrix4f& getModelviewMatrix(); + const glh::matrix4f& getProjectionMatrix(); void syncMatrices(); void syncLightState(); diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 1aa12614ea..ef2a7395da 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -457,7 +457,8 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, gGL.flush(); if (!source.mFBO || !mFBO) { - llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl; + llwarns << "Cannot copy framebuffer contents for non FBO render targets." << llendl; + return; } diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index dc3a1099b1..9d0d73b81e 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -108,6 +108,7 @@ LLWindow::LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags) mSupportedResolutions(NULL), mNumSupportedResolutions(0), mCurrentCursor(UI_CURSOR_ARROW), + mNextCursor(UI_CURSOR_ARROW), mCursorHidden(FALSE), mBusyCount(0), mIsMouseClipping(FALSE), diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index e8a86a1880..e5fcd19f2c 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -91,8 +91,9 @@ public: virtual S32 getBusyCount() const; // Sets cursor, may set to arrow+hourglass - virtual void setCursor(ECursorType cursor) = 0; + virtual void setCursor(ECursorType cursor) { mNextCursor = cursor; }; virtual ECursorType getCursor() const; + virtual void updateCursor() = 0; virtual void captureMouse() = 0; virtual void releaseMouse() = 0; @@ -181,6 +182,7 @@ protected: LLWindowResolution* mSupportedResolutions; S32 mNumSupportedResolutions; ECursorType mCurrentCursor; + ECursorType mNextCursor; BOOL mCursorHidden; S32 mBusyCount; // how deep is the "cursor busy" stack? BOOL mIsMouseClipping; // Is this window currently clipping the mouse diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h index ac53e6a86e..1e911d7547 100644 --- a/indra/llwindow/llwindowheadless.h +++ b/indra/llwindow/llwindowheadless.h @@ -55,7 +55,7 @@ public: /*virtual*/ void showCursorFromMouseMove() {}; /*virtual*/ void hideCursorUntilMouseMove() {}; /*virtual*/ BOOL isCursorHidden() {return FALSE;}; - /*virtual*/ void setCursor(ECursorType cursor) {}; + /*virtual*/ void updateCursor() {}; //virtual ECursorType getCursor() { return mCurrentCursor; }; /*virtual*/ void captureMouse() {}; /*virtual*/ void releaseMouse() {}; diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index d116f0dfff..d4832602a0 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1164,6 +1164,8 @@ void LLWindowMacOSX::gatherInput() } } + + updateCursor(); } BOOL LLWindowMacOSX::getPosition(LLCoordScreen *position) @@ -2841,7 +2843,7 @@ static void initPixmapCursor(int cursorid, int hotspotX, int hotspotY) gCursors[cursorid] = createImageCursor(fullpath.c_str(), hotspotX, hotspotY); } -void LLWindowMacOSX::setCursor(ECursorType cursor) +void LLWindowMacOSX::updateCursor() { OSStatus result = noErr; @@ -2849,30 +2851,30 @@ void LLWindowMacOSX::setCursor(ECursorType cursor) { // A drag is in progress...remember the requested cursor and we'll // restore it when it is done - mCurrentCursor = cursor; + mCurrentCursor = mNextCursor; return; } - if (cursor == UI_CURSOR_ARROW + if (mNextCursor == UI_CURSOR_ARROW && mBusyCount > 0) { - cursor = UI_CURSOR_WORKING; + mNextCursor = UI_CURSOR_WORKING; } - if(mCurrentCursor == cursor) + if(mCurrentCursor == mNextCursor) return; // RN: replace multi-drag cursors with single versions - if (cursor == UI_CURSOR_ARROWDRAGMULTI) + if (mNextCursor == UI_CURSOR_ARROWDRAGMULTI) { - cursor = UI_CURSOR_ARROWDRAG; + mNextCursor = UI_CURSOR_ARROWDRAG; } - else if (cursor == UI_CURSOR_ARROWCOPYMULTI) + else if (mNextCursor == UI_CURSOR_ARROWCOPYMULTI) { - cursor = UI_CURSOR_ARROWCOPY; + mNextCursor = UI_CURSOR_ARROWCOPY; } - switch(cursor) + switch(mNextCursor) { default: case UI_CURSOR_ARROW: @@ -2923,7 +2925,7 @@ void LLWindowMacOSX::setCursor(ECursorType cursor) case UI_CURSOR_TOOLSIT: case UI_CURSOR_TOOLBUY: case UI_CURSOR_TOOLOPEN: - result = setImageCursor(gCursors[cursor]); + result = setImageCursor(gCursors[mNextCursor]); break; } @@ -2933,7 +2935,7 @@ void LLWindowMacOSX::setCursor(ECursorType cursor) InitCursor(); } - mCurrentCursor = cursor; + mCurrentCursor = mNextCursor; } ECursorType LLWindowMacOSX::getCursor() const diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index 6c9e075a21..1414a7e2a7 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -67,7 +67,7 @@ public: /*virtual*/ void showCursorFromMouseMove(); /*virtual*/ void hideCursorUntilMouseMove(); /*virtual*/ BOOL isCursorHidden(); - /*virtual*/ void setCursor(ECursorType cursor); + /*virtual*/ void updateCursor(); /*virtual*/ ECursorType getCursor() const; /*virtual*/ void captureMouse(); /*virtual*/ void releaseMouse(); diff --git a/indra/llwindow/llwindowmesaheadless.h b/indra/llwindow/llwindowmesaheadless.h index fd4bd635e2..db7cb43754 100644 --- a/indra/llwindow/llwindowmesaheadless.h +++ b/indra/llwindow/llwindowmesaheadless.h @@ -59,7 +59,7 @@ public: /*virtual*/ void showCursorFromMouseMove() {}; /*virtual*/ void hideCursorUntilMouseMove() {}; /*virtual*/ BOOL isCursorHidden() {return FALSE;}; - /*virtual*/ void setCursor(ECursorType cursor) {}; + /*virtual*/ void updateCursor() {}; //virtual ECursorType getCursor() { return mCurrentCursor; }; /*virtual*/ void captureMouse() {}; /*virtual*/ void releaseMouse() {}; diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 8acb52516a..f8c6697432 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -1920,6 +1920,8 @@ void LLWindowSDL::gatherInput() break; } } + + updateCursor(); #if LL_X11 // This is a good time to stop flashing the icon if our mFlashTimer has @@ -2006,7 +2008,7 @@ static SDL_Cursor *makeSDLCursorFromBMP(const char *filename, int hotx, int hoty return sdlcursor; } -void LLWindowSDL::setCursor(ECursorType cursor) +void LLWindowSDL::updateCursor() { if (ATIbug) { // cursor-updating is very flaky when this bug is @@ -2014,11 +2016,11 @@ void LLWindowSDL::setCursor(ECursorType cursor) return; } - if (mCurrentCursor != cursor) + if (mCurrentCursor != mNextCursor) { - if (cursor < UI_CURSOR_COUNT) + if (mNextCursor < UI_CURSOR_COUNT) { - SDL_Cursor *sdlcursor = mSDLCursors[cursor]; + SDL_Cursor *sdlcursor = mSDLCursors[mNextCursor]; // Try to default to the arrow for any cursors that // did not load correctly. if (!sdlcursor && mSDLCursors[UI_CURSOR_ARROW]) @@ -2026,9 +2028,9 @@ void LLWindowSDL::setCursor(ECursorType cursor) if (sdlcursor) SDL_SetCursor(sdlcursor); } else { - llwarns << "Tried to set invalid cursor number " << cursor << llendl; + llwarns << "Tried to set invalid cursor number " << mNextCursor << llendl; } - mCurrentCursor = cursor; + mCurrentCursor = mNextCursor; } } diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h index fa544b16ce..fb3b117693 100644 --- a/indra/llwindow/llwindowsdl.h +++ b/indra/llwindow/llwindowsdl.h @@ -72,7 +72,7 @@ public: /*virtual*/ void showCursorFromMouseMove(); /*virtual*/ void hideCursorUntilMouseMove(); /*virtual*/ BOOL isCursorHidden(); - /*virtual*/ void setCursor(ECursorType cursor); + /*virtual*/ void updateCursor(); /*virtual*/ void captureMouse(); /*virtual*/ void releaseMouse(); /*virtual*/ void setMouseClipping( BOOL b ); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 799f0a3fab..03fff3d526 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -1667,18 +1667,18 @@ void LLWindowWin32::initCursors() -void LLWindowWin32::setCursor(ECursorType cursor) +void LLWindowWin32::updateCursor() { - if (cursor == UI_CURSOR_ARROW + if (mNextCursor == UI_CURSOR_ARROW && mBusyCount > 0) { - cursor = UI_CURSOR_WORKING; + mNextCursor = UI_CURSOR_WORKING; } - if( mCurrentCursor != cursor ) + if( mCurrentCursor != mNextCursor ) { - mCurrentCursor = cursor; - SetCursor( mCursor[cursor] ); + mCurrentCursor = mNextCursor; + SetCursor( mCursor[mNextCursor] ); } } @@ -1760,6 +1760,8 @@ void LLWindowWin32::gatherInput() mInputProcessingPaused = FALSE; + updateCursor(); + // clear this once we've processed all mouse messages that might have occurred after // we slammed the mouse position mMousePositionModified = FALSE; diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 387e4cbdb6..84f731a79f 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -66,7 +66,7 @@ public: /*virtual*/ void showCursorFromMouseMove(); /*virtual*/ void hideCursorUntilMouseMove(); /*virtual*/ BOOL isCursorHidden(); - /*virtual*/ void setCursor(ECursorType cursor); + /*virtual*/ void updateCursor(); /*virtual*/ ECursorType getCursor() const; /*virtual*/ void captureMouse(); /*virtual*/ void releaseMouse(); diff --git a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl index 88fe3c3dee..e612efba61 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl @@ -57,7 +57,7 @@ float getDepth(vec2 pos_screen) float calc_cof(float depth) { - float sc = abs(depth-focal_distance)/-depth*blur_constant; + float sc = (depth-focal_distance)/-depth*blur_constant; sc /= magnification; @@ -79,9 +79,10 @@ void main() vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); float sc = calc_cof(depth); - sc = min(abs(sc), max_cof); + sc = min(sc, max_cof); + sc = max(sc, -max_cof); vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res); gl_FragColor.rgb = diff.rgb + bloom.rgb; - gl_FragColor.a = sc/max_cof; + gl_FragColor.a = sc/max_cof*0.5+0.5; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl b/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl index 21453aefaa..01e3505359 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl @@ -48,7 +48,7 @@ void main() vec4 diff = texture2DRect(lightMap, vary_fragcoord.xy); - float a = min(diff.a * max_cof*res_scale*res_scale, 1.0); + float a = min(abs(diff.a*2.0-1.0) * max_cof*res_scale*res_scale, 1.0); if (a > 0.25 && a < 0.75) { //help out the transition a bit diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl index 4603d99c5e..18d451bf87 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl @@ -42,7 +42,7 @@ void dofSample(inout vec4 diff, inout float w, float min_sc, vec2 tc) { vec4 s = texture2DRect(diffuseRect, tc); - float sc = s.a*max_cof; + float sc = abs(s.a*2.0-1.0)*max_cof; if (sc > min_sc) //sampled pixel is more "out of focus" than current sample radius { @@ -57,6 +57,20 @@ void dofSample(inout vec4 diff, inout float w, float min_sc, vec2 tc) } } +void dofSampleNear(inout vec4 diff, inout float w, float min_sc, vec2 tc) +{ + vec4 s = texture2DRect(diffuseRect, tc); + + float wg = 0.25; + + // de-weight dull areas to make highlights 'pop' + wg += s.r+s.g+s.b; + + diff += wg*s; + + w += wg; +} + void main() { vec2 tc = vary_fragcoord.xy; @@ -66,12 +80,30 @@ void main() { float w = 1.0; - float sc = diff.a*max_cof; - + float sc = (diff.a*2.0-1.0)*max_cof; + float PI = 3.14159265358979323846264; // sample quite uniformly spaced points within a circle, for a circular 'bokeh' + if (sc > 0.5) + { + while (sc > 0.5) + { + int its = int(max(1.0,(sc*3.7))); + for (int i=0; i<its; ++i) + { + float ang = sc+i*2*PI/its; // sc is added for rotary perturbance + float samp_x = sc*sin(ang); + float samp_y = sc*cos(ang); + // you could test sample coords against an interesting non-circular aperture shape here, if desired. + dofSampleNear(diff, w, sc, vary_fragcoord.xy + vec2(samp_x,samp_y)); + } + sc -= 1.0; + } + } + else if (sc < -0.5) { + sc = abs(sc); while (sc > 0.5) { int its = int(max(1.0,(sc*3.7))); @@ -86,7 +118,7 @@ void main() sc -= 1.0; } } - + diff /= w; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index 60952ea38e..51110ae4df 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -35,7 +35,6 @@ uniform sampler2DRect positionMap; uniform sampler2DRect normalMap; uniform sampler2DRect lightMap; uniform sampler2DRect depthMap; -uniform sampler2D noiseMap; uniform samplerCube environmentMap; uniform sampler2D lightFunc; @@ -60,9 +59,7 @@ uniform vec4 distance_multiplier; uniform vec4 max_y; uniform vec4 glow; uniform float scene_light_strength; -uniform vec3 env_mat[3]; -//uniform mat4 shadow_matrix[3]; -//uniform vec4 shadow_clip; +uniform mat3 env_mat; uniform mat3 ssao_effect_mat; uniform vec3 sun_dir; @@ -279,8 +276,7 @@ void main() vec3 pos = getPosition_d(tc, depth).xyz; vec3 norm = texture2DRect(normalMap, tc).xyz; norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm - //vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz; - + float da = max(dot(norm.xyz, sun_dir.xyz), 0.0); vec4 diffuse = texture2DRect(diffuseRect, tc); @@ -309,6 +305,11 @@ void main() vec3 spec_contrib = dumbshiny * spec.rgb; bloom = dot(spec_contrib, spec_contrib); col += spec_contrib; + + //add environmentmap + vec3 env_vec = env_mat * refnormpersp; + col = mix(col.rgb, textureCube(environmentMap, env_vec).rgb, + max(spec.a-diffuse.a*2.0, 0.0)); } col = atmosLighting(col); diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl index e014e53d25..5522e6c41d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl @@ -52,7 +52,7 @@ void main() vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal ); gl_FragData[0] = vec4(outColor.rgb, 0.0); - gl_FragData[1] = vec4(outColor.rgb*0.2, 0.2); + gl_FragData[1] = vec4(0,0,0,0); vec3 nvn = normalize(vary_normal); gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0); } diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index eb367d4ad6..97f3063a9e 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -34,7 +34,6 @@ uniform sampler2DRect specularRect; uniform sampler2DRect normalMap; uniform sampler2DRect lightMap; uniform sampler2DRect depthMap; -uniform sampler2D noiseMap; uniform samplerCube environmentMap; uniform sampler2D lightFunc; uniform vec3 gi_quad; @@ -60,7 +59,7 @@ uniform vec4 distance_multiplier; uniform vec4 max_y; uniform vec4 glow; uniform float scene_light_strength; -uniform vec3 env_mat[3]; +uniform mat3 env_mat; uniform vec4 shadow_clip; uniform mat3 ssao_effect_mat; @@ -279,8 +278,7 @@ void main() vec3 pos = getPosition_d(tc, depth).xyz; vec3 norm = texture2DRect(normalMap, tc).xyz; norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm - //vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz; - + float da = max(dot(norm.xyz, sun_dir.xyz), 0.0); vec4 diffuse = texture2DRect(diffuseRect, tc); @@ -315,6 +313,11 @@ void main() vec3 spec_contrib = dumbshiny * spec.rgb; bloom = dot(spec_contrib, spec_contrib); col += spec_contrib; + + //add environmentmap + vec3 env_vec = env_mat * refnormpersp; + col = mix(col.rgb, textureCube(environmentMap, env_vec).rgb, + max(spec.a-diffuse.a*2.0, 0.0)); } col = atmosLighting(col); diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml index 6641c80b94..99dbfcae51 100644 --- a/indra/newview/character/avatar_lad.xml +++ b/indra/newview/character/avatar_lad.xml @@ -395,7 +395,7 @@ <attachment_point id="39" - group="9" + group="6" pie_slice="1" name="Neck" joint="mNeck" @@ -405,7 +405,7 @@ <attachment_point id="40" - group="9" + group="6" pie_slice="2" name="Avatar Center" joint="mRoot" diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index e80475f096..9455bf9875 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1345,17 +1345,19 @@ bool LLAppViewer::mainLoop() { S32 work_pending = 0; S32 io_pending = 0; + F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f); + { LLFastTimer ftm(FTM_TEXTURE_CACHE); - work_pending += LLAppViewer::getTextureCache()->update(1); // unpauses the texture cache thread + work_pending += LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread } { LLFastTimer ftm(FTM_DECODE); - work_pending += LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread + work_pending += LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread } { LLFastTimer ftm(FTM_DECODE); - work_pending += LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread + work_pending += LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread } { diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp index 42e7decec1..b539ac38ed 100644..100755 --- a/indra/newview/llavatariconctrl.cpp +++ b/indra/newview/llavatariconctrl.cpp @@ -75,6 +75,9 @@ void LLAvatarIconIDCache::load () LLUUID icon_id; LLDate date; + if (line.length()<=uuid_len*2) + continue; // short line, bail out to prevent substr calls throwing exception. + std::string avatar_id_str = line.substr(0,uuid_len); std::string icon_id_str = line.substr(uuid_len,uuid_len); diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 065dc5f4be..233038daba 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -105,6 +105,7 @@ void LLFastTimerView::onPause() if (!LLFastTimer::sPauseHistory) { mScrollIndex = 0; + LLFastTimer::sResetHistory = true; getChild<LLButton>("pause_btn")->setLabel(getString("pause")); } else @@ -591,6 +592,7 @@ void LLFastTimerView::draw() { mAvgCountTotal = ticks; mMaxCountTotal = ticks; + LLFastTimer::sResetHistory = false; } } diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp index a09b9ea235..cece8d299c 100644 --- a/indra/newview/llfloaterinspect.cpp +++ b/indra/newview/llfloaterinspect.cpp @@ -37,6 +37,7 @@ #include "llselectmgr.h" #include "lltoolcomp.h" #include "lltoolmgr.h" +#include "lltrans.h" #include "llviewercontrol.h" #include "llviewerobject.h" #include "lluictrlfactory.h" @@ -166,6 +167,15 @@ LLUUID LLFloaterInspect::getSelectedUUID() return LLUUID::null; } +void LLFloaterInspect::onGetAvNameCallback(const LLUUID& idCreator, const LLAvatarName& av_name, void* FloaterPtr) +{ + if (FloaterPtr) + { + LLFloaterInspect* floater = (LLFloaterInspect*)FloaterPtr; + floater->dirty(); + } +} + void LLFloaterInspect::refresh() { LLUUID creator_id; @@ -205,11 +215,32 @@ void LLFloaterInspect::refresh() substitution["datetime"] = (S32) timestamp; LLStringUtil::format (timeStr, substitution); + const LLUUID& idOwner = obj->mPermissions->getOwner(); + const LLUUID& idCreator = obj->mPermissions->getCreator(); LLAvatarName av_name; - LLAvatarNameCache::get(obj->mPermissions->getOwner(), &av_name); - owner_name = av_name.getCompleteName(); - LLAvatarNameCache::get(obj->mPermissions->getCreator(), &av_name); - creator_name = av_name.getCompleteName(); + + // Only work with the names if we actually get a result + // from the name cache. If not, defer setting the + // actual name and set a placeholder. + if (LLAvatarNameCache::get(idOwner, &av_name)) + { + owner_name = av_name.getCompleteName(); + } + else + { + owner_name = LLTrans::getString("RetrievingData"); + LLAvatarNameCache::get(idOwner, boost::bind(&LLFloaterInspect::onGetAvNameCallback, _1, _2, this)); + } + + if (LLAvatarNameCache::get(idCreator, &av_name)) + { + creator_name = av_name.getCompleteName(); + } + else + { + creator_name = LLTrans::getString("RetrievingData"); + LLAvatarNameCache::get(idCreator, boost::bind(&LLFloaterInspect::onGetAvNameCallback, _1, _2, this)); + } row["id"] = obj->getObject()->getID(); row["columns"][0]["column"] = "object_name"; diff --git a/indra/newview/llfloaterinspect.h b/indra/newview/llfloaterinspect.h index d9ffdf114b..7ee83ccdb4 100644 --- a/indra/newview/llfloaterinspect.h +++ b/indra/newview/llfloaterinspect.h @@ -29,6 +29,7 @@ #ifndef LL_LLFLOATERINSPECT_H #define LL_LLFLOATERINSPECT_H +#include "llavatarname.h" #include "llfloater.h" //class LLTool; @@ -53,6 +54,9 @@ public: void onClickCreatorProfile(); void onClickOwnerProfile(); void onSelectObject(); + + static void onGetAvNameCallback(const LLUUID& idCreator, const LLAvatarName& av_name, void* FloaterPtr); + LLScrollListCtrl* mObjectList; protected: // protected members diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp deleted file mode 100644 index c2bbec0470..0000000000 --- a/indra/newview/lloverlaybar.cpp +++ /dev/null @@ -1,378 +0,0 @@ -/** - * @file lloverlaybar.cpp - * @brief LLOverlayBar class implementation - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -// Temporary buttons that appear at the bottom of the screen when you -// are in a mode. - -#include "llviewerprecompiledheaders.h" - -#include "lloverlaybar.h" - -#include "llaudioengine.h" -#include "llrender.h" -#include "llagent.h" -#include "llbutton.h" -#include "llfocusmgr.h" -#include "llimview.h" -#include "llmediaremotectrl.h" -#include "llparcel.h" -#include "lltextbox.h" -#include "llui.h" -#include "llviewercontrol.h" -#include "llviewertexturelist.h" -#include "llviewerjoystick.h" -#include "llviewermedia.h" -#include "llviewermenu.h" // handle_reset_view() -#include "llviewermedia.h" -#include "llviewerparcelmedia.h" -#include "llviewerparcelmgr.h" -#include "lluictrlfactory.h" -#include "llviewerwindow.h" -#include "llvoiceclient.h" -#include "llvoavatarself.h" -#include "llvoiceremotectrl.h" -#include "llmediactrl.h" -#include "llselectmgr.h" - -// -// Globals -// - -LLOverlayBar *gOverlayBar = NULL; - -extern S32 MENU_BAR_HEIGHT; - -// -// Functions -// - - - -void* LLOverlayBar::createMediaRemote(void* userdata) -{ - LLOverlayBar *self = (LLOverlayBar*)userdata; - self->mMediaRemote = new LLMediaRemoteCtrl (); - return self->mMediaRemote; -} - -void* LLOverlayBar::createVoiceRemote(void* userdata) -{ - LLOverlayBar *self = (LLOverlayBar*)userdata; - self->mVoiceRemote = new LLVoiceRemoteCtrl(); - return self->mVoiceRemote; -} - -LLOverlayBar::LLOverlayBar() - : LLPanel(), - mMediaRemote(NULL), - mVoiceRemote(NULL), - mMusicState(STOPPED) -{ - setMouseOpaque(FALSE); - setIsChrome(TRUE); - - mBuilt = false; - - mFactoryMap["media_remote"] = LLCallbackMap(LLOverlayBar::createMediaRemote, this); - mFactoryMap["voice_remote"] = LLCallbackMap(LLOverlayBar::createVoiceRemote, this); - - LLUICtrlFactory::getInstance()->buildPanel(this, "panel_overlaybar.xml"); -} - -BOOL LLOverlayBar::postBuild() -{ - childSetAction("Set Not Busy",onClickSetNotBusy,this); - childSetAction("Mouselook",onClickMouselook,this); - childSetAction("Stand Up",onClickStandUp,this); - childSetAction("Flycam",onClickFlycam,this); - childSetVisible("chat_bar", gSavedSettings.getBOOL("ChatVisible")); - - mVoiceRemote->expandOrCollapse(); - mMediaRemote->expandOrCollapse(); - - setFocusRoot(TRUE); - mBuilt = true; - - layoutButtons(); - return TRUE; -} - -LLOverlayBar::~LLOverlayBar() -{ - // LLView destructor cleans up children -} - -// virtual -void LLOverlayBar::reshape(S32 width, S32 height, BOOL called_from_parent) -{ - LLView::reshape(width, height, called_from_parent); - - if (mBuilt) - { - layoutButtons(); - } -} - -void LLOverlayBar::layoutButtons() -{ - LLView* state_buttons_panel = getChildView("state_buttons"); - - if (state_buttons_panel->getVisible()) - { - LLViewQuery query; - LLWidgetTypeFilter<LLButton> widget_filter; - query.addPreFilter(LLEnabledFilter::getInstance()); - query.addPreFilter(&widget_filter); - - child_list_t button_list = query(state_buttons_panel); - - const S32 MAX_BAR_WIDTH = 600; - S32 bar_width = llclamp(state_buttons_panel->getRect().getWidth(), 0, MAX_BAR_WIDTH); - - // calculate button widths - const S32 MAX_BUTTON_WIDTH = 150; - const S32 STATUS_BAR_PAD = 10; - S32 segment_width = llclamp(lltrunc((F32)(bar_width) / (F32)button_list.size()), 0, MAX_BUTTON_WIDTH); - S32 btn_width = segment_width - STATUS_BAR_PAD; - - // Evenly space all buttons, starting from left - S32 left = 0; - S32 bottom = 1; - - for (child_list_reverse_iter_t child_iter = button_list.rbegin(); - child_iter != button_list.rend(); ++child_iter) - { - LLView *view = *child_iter; - LLRect r = view->getRect(); - r.setOriginAndSize(left, bottom, btn_width, r.getHeight()); - view->setRect(r); - left += segment_width; - } - } -} - -// Per-frame updates of visibility -void LLOverlayBar::refresh() -{ - BOOL buttons_changed = FALSE; - - BOOL im_received = gIMMgr->getIMReceived(); - LLButton* button = getChild<LLButton>("IM Received"); - if (button && button->getVisible() != im_received) - { - button->setVisible(im_received); - sendChildToFront(button); - moveChildToBackOfTabGroup(button); - buttons_changed = TRUE; - } - - BOOL busy = gAgent.getBusy(); - button = getChild<LLButton>("Set Not Busy"); - if (button && button->getVisible() != busy) - { - button->setVisible(busy); - sendChildToFront(button); - moveChildToBackOfTabGroup(button); - buttons_changed = TRUE; - } - - BOOL flycam = LLViewerJoystick::getInstance()->getOverrideCamera(); - button = getChild<LLButton>("Flycam"); - if (button && button->getVisible() != flycam) - { - button->setVisible(flycam); - sendChildToFront(button); - moveChildToBackOfTabGroup(button); - buttons_changed = TRUE; - } - - BOOL mouselook_grabbed; - mouselook_grabbed = gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_DOWN_INDEX) - || gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_UP_INDEX); - button = getChild<LLButton>("Mouselook"); - - if (button && button->getVisible() != mouselook_grabbed) - { - button->setVisible(mouselook_grabbed); - sendChildToFront(button); - moveChildToBackOfTabGroup(button); - buttons_changed = TRUE; - } - - BOOL sitting = FALSE; - if (gAgent.getAvatarObject()) - { - sitting = gAgent.getAvatarObject()->isSitting(); - } - button = getChild<LLButton>("Stand Up"); - - if (button && button->getVisible() != sitting) - { - button->setVisible(sitting); - sendChildToFront(button); - moveChildToBackOfTabGroup(button); - buttons_changed = TRUE; - } - - - moveChildToBackOfTabGroup(mMediaRemote); - moveChildToBackOfTabGroup(mVoiceRemote); - - // turn off the whole bar in mouselook - if (gAgent.cameraMouselook()) - { - childSetVisible("media_remote_container", FALSE); - childSetVisible("voice_remote_container", FALSE); - childSetVisible("state_buttons", FALSE); - } - else - { - // update "remotes" - childSetVisible("media_remote_container", TRUE); - childSetVisible("voice_remote_container", LLVoiceClient::getInstance()->voiceEnabled()); - childSetVisible("state_buttons", TRUE); - } - - // always let user toggle into and out of chatbar - childSetVisible("chat_bar", gSavedSettings.getBOOL("ChatVisible")); - - if (buttons_changed) - { - layoutButtons(); - } -} - -//----------------------------------------------------------------------- -// Static functions -//----------------------------------------------------------------------- - -// static -void LLOverlayBar::onClickSetNotBusy(void*) -{ - gAgent.clearBusy(); -} - - -// static -void LLOverlayBar::onClickFlycam(void*) -{ - LLViewerJoystick::getInstance()->toggleFlycam(); -} - -// static -void LLOverlayBar::onClickResetView(void* data) -{ - handle_reset_view(); -} - -//static -void LLOverlayBar::onClickMouselook(void*) -{ - gAgent.changeCameraToMouselook(); -} - -//static -void LLOverlayBar::onClickStandUp(void*) -{ - LLSelectMgr::getInstance()->deselectAllForStandingUp(); - gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); -} - -//////////////////////////////////////////////////////////////////////////////// -// static media helpers -// *TODO: Move this into an audio manager abstraction -//static -void LLOverlayBar::mediaStop(void*) -{ - if (!gOverlayBar) - { - // return; - } - LLViewerParcelMedia::stop(); -} -//static -void LLOverlayBar::toggleMediaPlay(void*) -{ - if (!gOverlayBar) - { - // return; - } - - - if (LLViewerParcelMedia::getStatus() == LLViewerMediaImpl::MEDIA_PAUSED) - { - LLViewerParcelMedia::start(); - } - else if(LLViewerParcelMedia::getStatus() == LLViewerMediaImpl::MEDIA_PLAYING) - { - LLViewerParcelMedia::pause(); - } - else - { - LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); - if (parcel) - { - LLViewerParcelMedia::play(parcel); - } - } -} - -//static -void LLOverlayBar::toggleMusicPlay(void*) -{ - if (gAudiop->isInternetStreamPlaying() != 1) - { - if (gAudiop) - { - LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); - if ( parcel ) - { - // this doesn't work properly when crossing parcel boundaries - even when the - // stream is stopped, it doesn't return the right thing - commenting out for now. - // if ( gAudiop->isInternetStreamPlaying() == 0 ) - { - gAudiop->startInternetStream(parcel->getMusicURL()); - } - } - } - } - //else - //{ - // gOverlayBar->mMusicState = PAUSED; // desired state - // if (gAudiop) - // { - // gAudiop->pauseInternetStream(1); - // } - //} - else - { - if (gAudiop) - { - gAudiop->stopInternetStream(); - } - } -} - diff --git a/indra/newview/lloverlaybar.h b/indra/newview/lloverlaybar.h deleted file mode 100644 index b36f5ebb73..0000000000 --- a/indra/newview/lloverlaybar.h +++ /dev/null @@ -1,95 +0,0 @@ -/** - * @file lloverlaybar.h - * @brief LLOverlayBar class definition - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLOVERLAYBAR_H -#define LL_LLOVERLAYBAR_H - -#include "llpanel.h" - -// "Constants" loaded from settings.xml at start time -extern S32 STATUS_BAR_HEIGHT; - -class LLButton; -class LLLineEditor; -class LLMediaRemoteCtrl; -class LLMessageSystem; -class LLTextBox; -class LLTextEditor; -class LLUICtrl; -class LLUUID; -class LLFrameTimer; -class LLStatGraph; -class LLSlider; -class LLVoiceRemoteCtrl; - -class LLOverlayBar -: public LLPanel -{ -public: - LLOverlayBar(); - ~LLOverlayBar(); - - /*virtual*/ void refresh(); - /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); - /*virtual*/ BOOL postBuild(); - - void layoutButtons(); - - // helpers for returning desired state - BOOL musicPlaying() { return mMusicState == PLAYING; } - - static void onClickSetNotBusy(void* data); - static void onClickMouselook(void* data); - static void onClickStandUp(void* data); - static void onClickResetView(void* data); - static void onClickFlycam(void* data); - - //static media helper functions - static void toggleMediaPlay(void*); - static void toggleMusicPlay(void*); - static void musicPause(void*); - static void musicStop(void*); - static void mediaStop(void*); - - static void toggleAudioVolumeFloater(void*); - -protected: - static void* createMediaRemote(void* userdata); - static void* createVoiceRemote(void* userdata); - - void enableMediaButtons(); - -protected: - LLMediaRemoteCtrl* mMediaRemote; - LLVoiceRemoteCtrl* mVoiceRemote; - bool mBuilt; // dialog constructed yet? - enum { STOPPED=0, PLAYING=1, PAUSED=2 }; - S32 mMusicState; -}; - -extern LLOverlayBar* gOverlayBar; - -#endif diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp index 2bbd15ae11..c01adc3c35 100644 --- a/indra/newview/llpanelnearbymedia.cpp +++ b/indra/newview/llpanelnearbymedia.cpp @@ -52,6 +52,7 @@ #include "llvovolume.h" #include "llstatusbar.h" #include "llsdutil.h" +#include "llvieweraudio.h" #include "llfloaterreg.h" #include "llfloaterpreference.h" // for the gear icon @@ -807,14 +808,26 @@ bool LLPanelNearByMedia::setDisabled(const LLUUID &row_id, bool disabled) { if (row_id == PARCEL_AUDIO_LIST_ITEM_UUID) { - if (disabled) onClickParcelAudioStop(); - else onClickParcelAudioStart(); + if (disabled) + { + onClickParcelAudioStop(); + } + else + { + onClickParcelAudioPlay(); + } return true; } else if (row_id == PARCEL_MEDIA_LIST_ITEM_UUID) { - if (disabled) onClickDisableParcelMedia(); - else onClickEnableParcelMedia(); + if (disabled) + { + onClickDisableParcelMedia(); + } + else + { + onClickEnableParcelMedia(); + } return true; } else { @@ -857,24 +870,11 @@ void LLPanelNearByMedia::onClickParcelMediaPause() LLViewerParcelMedia::pause(); } -void LLPanelNearByMedia::onClickParcelAudioStart() -{ - // User *explicitly* started the internet stream, so keep the stream - // playing and updated as they cross to other parcels etc. - mParcelAudioAutoStart = true; - - if (!gAudiop) - return; - - gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL()); -} - void LLPanelNearByMedia::onClickParcelAudioPlay() { // User *explicitly* started the internet stream, so keep the stream // playing and updated as they cross to other parcels etc. mParcelAudioAutoStart = true; - if (!gAudiop) return; @@ -883,8 +883,9 @@ void LLPanelNearByMedia::onClickParcelAudioPlay() // 'false' means unpause gAudiop->pauseInternetStream(false); } - else { - gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL()); + else + { + LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLViewerMedia::getParcelAudioURL()); } } @@ -894,11 +895,10 @@ void LLPanelNearByMedia::onClickParcelAudioStop() // re-start audio when i.e. they move to another parcel, until // they explicitly start it again. mParcelAudioAutoStart = false; - if (!gAudiop) return; - gAudiop->stopInternetStream(); + LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade(); } void LLPanelNearByMedia::onClickParcelAudioPause() diff --git a/indra/newview/llpanelnearbymedia.h b/indra/newview/llpanelnearbymedia.h index be4d313743..c3634de9b4 100644 --- a/indra/newview/llpanelnearbymedia.h +++ b/indra/newview/llpanelnearbymedia.h @@ -115,7 +115,6 @@ private: void onClickParcelMediaPause(); void onClickParcelAudioPlay(); void onClickParcelAudioStop(); - void onClickParcelAudioStart(); void onClickParcelAudioPause(); void onCheckAutoPlay(); void onAdvancedButtonClick(); diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index fb1153980a..5c95e805ce 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -468,7 +468,7 @@ void LLParticipantList::setValidateSpeakerCallback(validate_speaker_callback_t c void LLParticipantList::updateRecentSpeakersOrder() { - if (E_SORT_BY_RECENT_SPEAKERS == getSortOrder()) + if (E_SORT_BY_RECENT_SPEAKERS == getSortOrder() && !isHovered()) { // Need to update speakers to sort list correctly mSpeakerMgr->update(true); @@ -477,6 +477,13 @@ void LLParticipantList::updateRecentSpeakersOrder() } } +bool LLParticipantList::isHovered() +{ + S32 x, y; + LLUI::getMousePositionScreen(&x, &y); + return mAvatarList->calcScreenRect().pointInRect(x, y); +} + bool LLParticipantList::onAddItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata) { LLUUID uu_id = event->getValue().asUUID(); diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h index e0b3d42c25..a001d29b67 100644 --- a/indra/newview/llparticipantlist.h +++ b/indra/newview/llparticipantlist.h @@ -251,6 +251,8 @@ private: */ void adjustParticipant(const LLUUID& speaker_id); + bool isHovered(); + LLSpeakerMgr* mSpeakerMgr; LLAvatarList* mAvatarList; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 3e16ccf3da..fb107a302a 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -28,6 +28,10 @@ #include "llspatialpartition.h" +#include "llappviewer.h" +#include "lltexturecache.h" +#include "lltexturefetch.h" +#include "llimageworker.h" #include "llviewerwindow.h" #include "llviewerobjectlist.h" #include "llvovolume.h" @@ -1221,6 +1225,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) { mOcclusionQuery[i] = 0; + mOcclusionIssued[i] = 0; mOcclusionState[i] = parent ? SG_STATE_INHERIT_MASK & parent->mOcclusionState[i] : 0; mVisible[i] = 0; } @@ -1543,6 +1548,8 @@ BOOL LLSpatialGroup::rebound() } static LLFastTimer::DeclareTimer FTM_OCCLUSION_READBACK("Readback Occlusion"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Wait"); + void LLSpatialGroup::checkOcclusion() { if (LLPipeline::sUseOcclusion > 1) @@ -1560,6 +1567,22 @@ void LLSpatialGroup::checkOcclusion() if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) { glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); + + if (mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount) + { //query was issued last frame, wait until it's available + S32 max_loop = 1024; + LLFastTimer t(FTM_OCCLUSION_WAIT); + while (!available && max_loop-- > 0) + { + F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f); + //do some usefu work while we wait + LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread + LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread + LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread + + glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); + } + } } else { @@ -1679,6 +1702,9 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) { LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS); + //store which frame this query was issued on + mOcclusionIssued[LLViewerCamera::sCurCameraID] = gFrameCount; + { LLFastTimer t(FTM_OCCLUSION_BEGIN_QUERY); glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]); diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index f0c8a372ee..899547ae4d 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -396,6 +396,8 @@ protected: U32 mState; U32 mOcclusionState[LLViewerCamera::NUM_CAMERAS]; + U32 mOcclusionIssued[LLViewerCamera::NUM_CAMERAS]; + S32 mLODHash; static S32 sLODSeed; diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index e7a176f4f9..8632890bbb 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -760,7 +760,7 @@ LLTextureCache::~LLTextureCache() ////////////////////////////////////////////////////////////////////////////// //virtual -S32 LLTextureCache::update(U32 max_time_ms) +S32 LLTextureCache::update(F32 max_time_ms) { static LLFrameTimer timer ; static const F32 MAX_TIME_INTERVAL = 300.f ; //seconds. diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h index 64e3a2658c..dd0cc9b4bd 100644 --- a/indra/newview/lltexturecache.h +++ b/indra/newview/lltexturecache.h @@ -101,7 +101,7 @@ public: LLTextureCache(bool threaded); ~LLTextureCache(); - /*virtual*/ S32 update(U32 max_time_ms); + /*virtual*/ S32 update(F32 max_time_ms); void purgeCache(ELLPath location); void setReadOnly(BOOL read_only) ; diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 56dfb61c4f..f18aa8b4e6 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -2204,7 +2204,7 @@ void LLTextureFetch::commonUpdate() // MAIN THREAD //virtual -S32 LLTextureFetch::update(U32 max_time_ms) +S32 LLTextureFetch::update(F32 max_time_ms) { static LLCachedControl<F32> band_width(gSavedSettings,"ThrottleBandwidthKBPS"); diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index d101da1f4b..35df7d816f 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -55,7 +55,7 @@ public: class TFRequest; - /*virtual*/ S32 update(U32 max_time_ms); + /*virtual*/ S32 update(F32 max_time_ms); void shutDownTextureCacheThread() ; //called in the main thread after the TextureCacheThread shuts down. void shutDownImageDecodeThread() ; //called in the main thread after the ImageDecodeThread shuts down. diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp index f7fa5690d6..2447f5dea8 100644 --- a/indra/newview/llvieweraudio.cpp +++ b/indra/newview/llvieweraudio.cpp @@ -37,9 +37,226 @@ #include "llvoiceclient.h" #include "llviewermedia.h" #include "llprogressview.h" +#include "llcallbacklist.h" +#include "llstartup.h" +#include "llviewerparcelmgr.h" +#include "llparcel.h" ///////////////////////////////////////////////////////// +LLViewerAudio::LLViewerAudio() : + mDone(true), + mFadeState(FADE_IDLE), + mFadeTime(), + mIdleListnerActive(false), + mForcedTeleportFade(false) +{ + mTeleportFailedConnection = LLViewerParcelMgr::getInstance()-> + setTeleportFailedCallback(boost::bind(&LLViewerAudio::onTeleportFailed, this)); +} + +LLViewerAudio::~LLViewerAudio() +{ + mTeleportFailedConnection.disconnect(); +} + +void LLViewerAudio::registerIdleListener() +{ + if(mIdleListnerActive==false) + { + mIdleListnerActive = true; + doOnIdleRepeating(boost::bind(boost::bind(&LLViewerAudio::onIdleUpdate, this))); + } + +} + +void LLViewerAudio::startInternetStreamWithAutoFade(std::string streamURI) +{ + // Old and new stream are identical + if (mNextStreamURI == streamURI) + { + return; + } + + // Record the URI we are going to be switching to + mNextStreamURI = streamURI; + + switch (mFadeState) + { + case FADE_IDLE: + // If a stream is playing fade it out first + if (!gAudiop->getInternetStreamURL().empty()) + { + // The order of these tests is important, state FADE_OUT will be processed below + mFadeState = FADE_OUT; + } + // Otherwise the new stream can be faded in + else + { + mFadeState = FADE_IN; + gAudiop->startInternetStream(mNextStreamURI); + startFading(); + registerIdleListener(); + break; + } + + case FADE_OUT: + startFading(); + registerIdleListener(); + break; + + case FADE_IN: + registerIdleListener(); + break; + + default: + llwarns << "Unknown fading state: " << mFadeState << llendl; + break; + } +} + +// A return of false from onIdleUpdate means it will be called again next idle update. +// A return of true means we have finished with it and the callback will be deleted. +bool LLViewerAudio::onIdleUpdate() +{ + bool fadeIsFinished = false; + + // There is a delay in the login sequence between when the parcel information has + // arrived and the music stream is started and when the audio system is called to set + // initial volume levels. This code extends the fade time so you hear a full fade in. + if ((LLStartUp::getStartupState() < STATE_STARTED)) + { + stream_fade_timer.reset(); + stream_fade_timer.setTimerExpirySec(mFadeTime); + } + + if (mDone) + { + // This should be a rare or never occurring state. + if (mFadeState == FADE_IDLE) + { + deregisterIdleListener(); + fadeIsFinished = true; // Stop calling onIdleUpdate + } + + // we have finished the current fade operation + if (mFadeState == FADE_OUT) + { + // Clear URI + gAudiop->startInternetStream(LLStringUtil::null); + gAudiop->stopInternetStream(); + + if (!mNextStreamURI.empty()) + { + mFadeState = FADE_IN; + gAudiop->startInternetStream(mNextStreamURI); + startFading(); + } + else + { + mFadeState = FADE_IDLE; + deregisterIdleListener(); + fadeIsFinished = true; // Stop calling onIdleUpdate + } + } + else if (mFadeState == FADE_IN) + { + if (mNextStreamURI != gAudiop->getInternetStreamURL()) + { + mFadeState = FADE_OUT; + startFading(); + } + else + { + mFadeState = FADE_IDLE; + deregisterIdleListener(); + fadeIsFinished = true; // Stop calling onIdleUpdate + } + } + } + + return fadeIsFinished; +} + +void LLViewerAudio::stopInternetStreamWithAutoFade() +{ + mFadeState = FADE_IDLE; + mNextStreamURI = LLStringUtil::null; + mDone = true; + + gAudiop->startInternetStream(LLStringUtil::null); + gAudiop->stopInternetStream(); +} + +void LLViewerAudio::startFading() +{ + const F32 AUDIO_MUSIC_FADE_IN_TIME = 3.0f; + const F32 AUDIO_MUSIC_FADE_OUT_TIME = 2.0f; + // This minimum fade time prevents divide by zero and negative times + const F32 AUDIO_MUSIC_MINIMUM_FADE_TIME = 0.01f; + + if(mDone) + { + // The fade state here should only be one of FADE_IN or FADE_OUT, but, in case it is not, + // rather than check for both states assume a fade in and check for the fade out case. + mFadeTime = AUDIO_MUSIC_FADE_IN_TIME; + if (LLViewerAudio::getInstance()->getFadeState() == LLViewerAudio::FADE_OUT) + { + mFadeTime = AUDIO_MUSIC_FADE_OUT_TIME; + } + + // Prevent invalid fade time + mFadeTime = llmax(mFadeTime, AUDIO_MUSIC_MINIMUM_FADE_TIME); + + stream_fade_timer.reset(); + stream_fade_timer.setTimerExpirySec(mFadeTime); + mDone = false; + } +} + +F32 LLViewerAudio::getFadeVolume() +{ + F32 fade_volume = 1.0f; + + if (stream_fade_timer.hasExpired()) + { + mDone = true; + // If we have been fading out set volume to 0 until the next fade state occurs to prevent + // an audio transient. + if (LLViewerAudio::getInstance()->getFadeState() == LLViewerAudio::FADE_OUT) + { + fade_volume = 0.0f; + } + } + + if (!mDone) + { + // Calculate how far we are into the fade time + fade_volume = stream_fade_timer.getElapsedTimeF32() / mFadeTime; + + if (LLViewerAudio::getInstance()->getFadeState() == LLViewerAudio::FADE_OUT) + { + // If we are not fading in then we are fading out, so invert the fade + // direction; start loud and move towards zero volume. + fade_volume = 1.0f - fade_volume; + } + } + + return fade_volume; +} + +void LLViewerAudio::onTeleportFailed() +{ + if (gAudiop) + { + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if (parcel) + { + mNextStreamURI = parcel->getMusicURL(); + } + } +} + void init_audio() { if (!gAudiop) @@ -142,12 +359,25 @@ void audio_update_volume(bool force_update) // Streaming Music if (gAudiop) - { + { + if (progress_view_visible && !LLViewerAudio::getInstance()->getForcedTeleportFade()) + { + LLViewerAudio::getInstance()->setForcedTeleportFade(true); + LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null); + LLViewerAudio::getInstance()->setNextStreamURI(LLStringUtil::null); + } + + if (!progress_view_visible && LLViewerAudio::getInstance()->getForcedTeleportFade() == true) + { + LLViewerAudio::getInstance()->setForcedTeleportFade(false); + } + F32 music_volume = gSavedSettings.getF32("AudioLevelMusic"); BOOL music_muted = gSavedSettings.getBOOL("MuteMusic"); - music_volume = mute_volume * master_volume * music_volume; - gAudiop->setInternetStreamGain ( music_muted || progress_view_visible ? 0.f : music_volume ); - + F32 fade_volume = LLViewerAudio::getInstance()->getFadeVolume(); + + music_volume = mute_volume * master_volume * music_volume * fade_volume; + gAudiop->setInternetStreamGain (music_muted ? 0.f : music_volume); } // Streaming Media diff --git a/indra/newview/llvieweraudio.h b/indra/newview/llvieweraudio.h index e5916285fb..a3da9fc6b8 100644 --- a/indra/newview/llvieweraudio.h +++ b/indra/newview/llvieweraudio.h @@ -27,6 +27,9 @@ #ifndef LL_VIEWERAUDIO_H #define LL_VIEWERAUDIO_H +#include "llframetimer.h" +#include "llsingleton.h" + // comment out to turn off wind #define kAUDIO_ENABLE_WIND //#define kAUDIO_ENABLE_WATER 1 // comment out to turn off water @@ -38,4 +41,48 @@ void audio_update_volume(bool force_update = true); void audio_update_listener(); void audio_update_wind(bool force_update = true); +class LLViewerAudio : public LLSingleton<LLViewerAudio> +{ +public: + + enum EFadeState + { + FADE_IDLE, + FADE_IN, + FADE_OUT, + }; + + LLViewerAudio(); + virtual ~LLViewerAudio(); + + void startInternetStreamWithAutoFade(std::string streamURI); + void stopInternetStreamWithAutoFade(); + + bool onIdleUpdate(); + + EFadeState getFadeState() { return mFadeState; } + bool isDone() { return mDone; }; + F32 getFadeVolume(); + bool getForcedTeleportFade() { return mForcedTeleportFade; }; + void setForcedTeleportFade(bool fade) { mForcedTeleportFade = fade;} ; + void setNextStreamURI(std::string stream) { mNextStreamURI = stream; } ; + +private: + + bool mDone; + F32 mFadeTime; + std::string mNextStreamURI; + EFadeState mFadeState; + LLFrameTimer stream_fade_timer; + bool mIdleListnerActive; + bool mForcedTeleportFade; + boost::signals2::connection mTeleportFailedConnection; + + void registerIdleListener(); + void deregisterIdleListener() { mIdleListnerActive = false; }; + void startFading(); + void onTeleportFailed(); + +}; + #endif //LL_VIEWER_H diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 98f4ce58fe..4ac1b7fa6e 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -67,7 +67,7 @@ //#include "llfirstuse.h" #include "llviewernetwork.h" #include "llwindow.h" - +#include "llvieweraudio.h" #include "llfloaterwebcontent.h" // for handling window close requests and geometry change requests in media browser windows. @@ -986,7 +986,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg) { if(LLViewerMedia::isParcelAudioPlaying() && gAudiop && LLViewerMedia::hasParcelAudio()) { - gAudiop->stopInternetStream(); + LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade(); } } pimpl->setPriority(new_priority); @@ -1090,13 +1090,24 @@ void LLViewerMedia::setAllMediaEnabled(bool val) gAudiop && LLViewerMedia::hasParcelAudio()) { - gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL()); + if (LLAudioEngine::AUDIO_PAUSED == gAudiop->isInternetStreamPlaying()) + { + // 'false' means unpause + gAudiop->pauseInternetStream(false); + } + else + { + LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLViewerMedia::getParcelAudioURL()); + } } } else { // This actually unloads the impl, as opposed to "stop"ping the media LLViewerParcelMedia::stop(); - if (gAudiop) gAudiop->stopInternetStream(); + if (gAudiop) + { + LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade(); + } } } diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index dca5cdd06d..ad333a71ff 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3638,6 +3638,9 @@ void process_teleport_finish(LLMessageSystem* msg, void**) gCacheName->setUpstream(sim); */ + // Make sure we're standing + gAgent.standUp(); + // now, use the circuit info to tell simulator about us! LL_INFOS("Messaging") << "process_teleport_finish() Enabling " << sim_host << " with code " << msg->mOurCircuitCode << LL_ENDL; diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index d6002e7320..c64e8dd6af 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -67,6 +67,7 @@ #include "llworld.h" #include "roles_constants.h" #include "llweb.h" +#include "llvieweraudio.h" const F32 PARCEL_COLLISION_DRAW_SECS = 1.f; @@ -1725,7 +1726,10 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use } else { - // look for music. + // Check for video + LLViewerParcelMedia::update(parcel); + + // Then check for music if (gAudiop) { if (parcel) @@ -1736,46 +1740,34 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use std::string music_url = music_url_raw; LLStringUtil::trim(music_url); - // On entering a new parcel, stop the last stream if the - // new parcel has a different music url. (Empty URL counts - // as different.) - const std::string& stream_url = gAudiop->getInternetStreamURL(); - - if (music_url.empty() || music_url != stream_url) + // If there is a new music URL and it's valid, play it. + if (music_url.size() > 12) { - // URL is different from one currently playing. - gAudiop->stopInternetStream(); - - // If there is a new music URL and it's valid, play it. - if (music_url.size() > 12) + if (music_url.substr(0,7) == "http://") { - if (music_url.substr(0,7) == "http://") - { - optionally_start_music(music_url); - } - else - { - llinfos << "Stopping parcel music (invalid audio stream URL)" << llendl; - // clears the URL - gAudiop->startInternetStream(LLStringUtil::null); - } + optionally_start_music(music_url); } - else if (!gAudiop->getInternetStreamURL().empty()) + else { - llinfos << "Stopping parcel music (parcel stream URL is empty)" << llendl; - gAudiop->startInternetStream(LLStringUtil::null); + llinfos << "Stopping parcel music (invalid audio stream URL)" << llendl; + // clears the URL + // null value causes fade out + LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null); } } + else if (!gAudiop->getInternetStreamURL().empty()) + { + llinfos << "Stopping parcel music (parcel stream URL is empty)" << llendl; + // null value causes fade out + LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null); + } } else { // Public land has no music - gAudiop->stopInternetStream(); + LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade(); } }//if gAudiop - - // now check for video - LLViewerParcelMedia::update( parcel ); }; } @@ -1794,7 +1786,11 @@ void optionally_start_music(const std::string& music_url) gSavedSettings.getBOOL("MediaTentativeAutoPlay"))) { llinfos << "Starting parcel music " << music_url << llendl; - gAudiop->startInternetStream(music_url); + LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(music_url); + } + else + { + LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null); } } } diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index f4bbc2b067..61236edc86 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -417,11 +417,24 @@ const S32 min_non_tex_system_mem = (128<<20); // 128 MB F32 texmem_lower_bound_scale = 0.85f; F32 texmem_middle_bound_scale = 0.925f; +static LLFastTimer::DeclareTimer FTM_TEXTURE_MEMORY_CHECK("Memory Check"); + //static bool LLViewerTexture::isMemoryForTextureLow() { - const static S32 MIN_FREE_TEXTURE_MEMORY = 5 ; //MB - const static S32 MIN_FREE_MAIN_MEMORy = 100 ; //MB + const F32 WAIT_TIME = 1.0f ; //second + static LLFrameTimer timer ; + + if(timer.getElapsedTimeF32() < WAIT_TIME) //call this once per second. + { + return false; + } + timer.reset() ; + + LLFastTimer t(FTM_TEXTURE_MEMORY_CHECK); + + const S32 MIN_FREE_TEXTURE_MEMORY = 5 ; //MB + const S32 MIN_FREE_MAIN_MEMORy = 100 ; //MB bool low_mem = false ; if (gGLManager.mHasATIMemInfo) @@ -433,6 +446,15 @@ bool LLViewerTexture::isMemoryForTextureLow() { low_mem = true ; } + + if(!low_mem) //check main memory, only works for windows. + { + LLMemory::updateMemoryInfo() ; + if(LLMemory::getAvailableMemKB() / 1024 < MIN_FREE_MAIN_MEMORy) + { + low_mem = true ; + } + } } #if 0 //ignore nVidia cards else if (gGLManager.mHasNVXMemInfo) @@ -445,20 +467,14 @@ bool LLViewerTexture::isMemoryForTextureLow() low_mem = true ; } } -#endif - - if(!low_mem) //check main memory, only works for windows. - { - LLMemory::updateMemoryInfo() ; - if(LLMemory::getAvailableMemKB() / 1024 < MIN_FREE_MAIN_MEMORy) - { - low_mem = true ; - } - } +#endif return low_mem ; } +static LLFastTimer::DeclareTimer FTM_TEXTURE_UPDATE_MEDIA("Media"); +static LLFastTimer::DeclareTimer FTM_TEXTURE_UPDATE_TEST("Test"); + //static void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity) { @@ -467,9 +483,14 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); if (tester) { + LLFastTimer t(FTM_TEXTURE_UPDATE_TEST); tester->update() ; } - LLViewerMediaTexture::updateClass() ; + + { + LLFastTimer t(FTM_TEXTURE_UPDATE_MEDIA); + LLViewerMediaTexture::updateClass() ; + } sBoundTextureMemoryInBytes = LLImageGL::sBoundTextureMemoryInBytes;//in bytes sTotalTextureMemoryInBytes = LLImageGL::sGlobalTextureMemoryInBytes;//in bytes @@ -3142,8 +3163,13 @@ void LLViewerLODTexture::processTextureStats() S32 current_discard = getDiscardLevel(); if (sDesiredDiscardBias > 0.0f && mBoostLevel < LLViewerTexture::BOOST_SCULPTED && current_discard >= 0) { + if(desired_discard_bias_max <= sDesiredDiscardBias && !mForceToSaveRawImage) + { + //needs to release texture memory urgently + scaleDown() ; + } // Limit the amount of GL memory bound each frame - if ( BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) > sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale && + else if ( BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) > sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale && (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel)) { scaleDown() ; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 12bec90881..00acc3e511 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -6333,17 +6333,10 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } - U32 res_mod = RenderResolutionDivisor; - LLVector2 tc1(0,0); LLVector2 tc2((F32) mScreen.getWidth()*2, (F32) mScreen.getHeight()*2); - if (res_mod > 1) - { - tc2 /= (F32) res_mod; - } - LLFastTimer ftm(FTM_RENDER_BLOOM); gGL.color4f(1,1,1,1); LLGLDepthTest depth(GL_FALSE); @@ -6807,7 +6800,13 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) mFXAABuffer.bindTexture(0, channel); gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); } - + + gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; + gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; + gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); + gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); + F32 scale_x = (F32) width/mFXAABuffer.getWidth(); F32 scale_y = (F32) height/mFXAABuffer.getHeight(); shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y); @@ -6827,11 +6826,6 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) } else { - if (res_mod > 1) - { - tc2 /= (F32) res_mod; - } - U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1; LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0); buff->allocateBuffer(3,0,TRUE); @@ -7108,13 +7102,12 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n cube_map->enable(channel); cube_map->bind(); F32* m = gGLModelView; - - + F32 mat[] = { m[0], m[1], m[2], m[4], m[5], m[6], m[8], m[9], m[10] }; - shader.uniform3fv(LLShaderMgr::DEFERRED_ENV_MAT, 3, mat); + shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat); } } diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index c8c1922bf6..3a581e7e6e 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1723,12 +1723,6 @@ function="Tools.EnableReleaseKeys" parameter="" /> </menu_item_call> - <menu_item_call - label="Set UI Size to Default" - name="Set UI Size to Default"> - <menu_item_call.on_click - function="View.DefaultUISize" /> - </menu_item_call> <!-- This second, alternative shortcut for Show Advanced Menu is for backward compatibility. The main shortcut has been changed so it's Linux-friendly, where the old shortcut is typically eaten by the window manager. --> <menu_item_check label="Show Advanced Menu - legacy shortcut" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index e4458f33b1..4e4eea0354 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6939,7 +6939,7 @@ With the following Residents: <usetemplate name="okcancelbuttons" notext="Cancel" - yestext="Ok"/> + yestext="OK"/> </notification> <notification @@ -7135,7 +7135,7 @@ Mute everyone? <usetemplate ignoretext="Confirm before I mute all participants in a group call" name="okcancelignore" - yestext="Ok" + yestext="OK" notext="Cancel"> <unique/> </usetemplate> diff --git a/indra/newview/skins/default/xui/en/panel_region_covenant.xml b/indra/newview/skins/default/xui/en/panel_region_covenant.xml index df16f6fd37..112f12500d 100644 --- a/indra/newview/skins/default/xui/en/panel_region_covenant.xml +++ b/indra/newview/skins/default/xui/en/panel_region_covenant.xml @@ -57,7 +57,7 @@ mouse_opaque="false" name="estate_name_text" top_delta="0" - width="150"> + width="350"> mainland </text> <text @@ -79,7 +79,7 @@ mouse_opaque="false" name="estate_owner_text" top_delta="0" - width="150"> + width="350"> (none) </text> <text diff --git a/indra/newview/skins/default/xui/es/panel_navigation_bar.xml b/indra/newview/skins/default/xui/es/panel_navigation_bar.xml index 1b7f5d5a9f..d36c6283bc 100644 --- a/indra/newview/skins/default/xui/es/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/es/panel_navigation_bar.xml @@ -3,7 +3,7 @@ <layout_stack name="nvp_stack"> <layout_panel name="navigation_layout_panel"> <panel name="navigation_panel"> - <pull_button name="back_btn" tool_tip="Volver a lo localización anterior"/> + <pull_button name="back_btn" tool_tip="Volver a la localización anterior"/> <pull_button name="forward_btn" tool_tip="Ir una localización adelante"/> <button name="home_btn" tool_tip="Teleportar a mi Base"/> <location_input label="Lugar" name="location_combo"/> diff --git a/indra/newview/skins/default/xui/fr/menu_viewer.xml b/indra/newview/skins/default/xui/fr/menu_viewer.xml index 64cd463070..78f973a61f 100644 --- a/indra/newview/skins/default/xui/fr/menu_viewer.xml +++ b/indra/newview/skins/default/xui/fr/menu_viewer.xml @@ -319,7 +319,7 @@ <menu_item_check label="Pauser l'avatar" name="AgentPause"/> <menu_item_call label="Activer le journal des messages" name="Enable Message Log"/> <menu_item_call label="Désactiver le journal des messages" name="Disable Message Log"/> - <menu_item_check label="Velocity Interpolate Objects" name="Velocity Interpolate Objects"/> + <menu_item_check label="Objets d'interpolation de vitesse" name="Velocity Interpolate Objects"/> <menu_item_check label="Interpolation ping des positions des objets" name="Ping Interpolate Object Positions"/> <menu_item_call label="Abandonner un paquet" name="Drop a Packet"/> </menu> @@ -336,7 +336,7 @@ <menu_item_check label="Ignorer les paramètres du soleil de la sim" name="Sim Sun Override"/> <menu_item_check label="Balise animée" name="Cheesy Beacon"/> <menu_item_check label="Météo fixe" name="Fixed Weather"/> - <menu_item_call label="Dump Region Object Cache" name="Dump Region Object Cache"/> + <menu_item_call label="Vidage de cache d'objet de la région" name="Dump Region Object Cache"/> </menu> <menu label="Interface" name="UI"> <menu_item_call label="Test du navigateur de médias" name="Web Browser Test"/> diff --git a/indra/test/llsd_new_tut.cpp b/indra/test/llsd_new_tut.cpp index b2fa54a688..f928a1bad0 100644 --- a/indra/test/llsd_new_tut.cpp +++ b/indra/test/llsd_new_tut.cpp @@ -25,6 +25,7 @@ * $/LicenseInfo$ */ +#define LLSD_DEBUG_INFO #include <tut/tut.hpp> #include "linden_common.h" #include "lltut.h" @@ -52,11 +53,11 @@ namespace tut private: U32 mOutstandingAtStart; public: - SDCleanupCheck() : mOutstandingAtStart(LLSD::outstandingCount()) { } + SDCleanupCheck() : mOutstandingAtStart(llsd::outstandingCount()) { } ~SDCleanupCheck() { ensure_equals("SDCleanupCheck", - LLSD::outstandingCount(), mOutstandingAtStart); + llsd::outstandingCount(), mOutstandingAtStart); } }; @@ -70,12 +71,12 @@ namespace tut SDAllocationCheck(const std::string& message, int expectedAllocations) : mMessage(message), mExpectedAllocations(expectedAllocations), - mAllocationAtStart(LLSD::allocationCount()) + mAllocationAtStart(llsd::allocationCount()) { } ~SDAllocationCheck() { ensure_equals(mMessage + " SDAllocationCheck", - LLSD::allocationCount() - mAllocationAtStart, + llsd::allocationCount() - mAllocationAtStart, mExpectedAllocations); } }; @@ -756,6 +757,42 @@ namespace tut { SDAllocationCheck check("shared values test for threaded work", 9); + //U32 start_llsd_count = llsd::outstandingCount(); + + LLSD m = LLSD::emptyMap(); + + m["one"] = 1; + m["two"] = 2; + m["one_copy"] = m["one"]; // 3 (m, "one" and "two") + + m["undef_one"] = LLSD(); + m["undef_two"] = LLSD(); + m["undef_one_copy"] = m["undef_one"]; + + { // Ensure first_array gets freed to avoid counting it + LLSD first_array = LLSD::emptyArray(); + first_array.append(1.0f); + first_array.append(2.0f); + first_array.append(3.0f); // 7 + + m["array"] = first_array; + m["array_clone"] = first_array; + m["array_copy"] = m["array"]; // 7 + } + + m["string_one"] = "string one value"; + m["string_two"] = "string two value"; + m["string_one_copy"] = m["string_one"]; // 9 + + //U32 llsd_object_count = llsd::outstandingCount(); + //std::cout << "Using " << (llsd_object_count - start_llsd_count) << " LLSD objects" << std::endl; + + //m.dumpStats(); + } + + { + SDAllocationCheck check("shared values test for threaded work", 9); + //U32 start_llsd_count = LLSD::outstandingCount(); LLSD m = LLSD::emptyMap(); diff --git a/indra/test/lltut.cpp b/indra/test/lltut.cpp index da7031b52a..c43a8f0c7d 100644 --- a/indra/test/lltut.cpp +++ b/indra/test/lltut.cpp @@ -34,6 +34,7 @@ #include "llformat.h" #include "llsd.h" #include "lluri.h" +#include "stringize.h" namespace tut { @@ -144,6 +145,10 @@ namespace tut } return; } + default: + // should never get here, but compiler produces warning if we + // don't cover this case, and at Linden warnings are fatal. + throw failure(STRINGIZE("invalid type field " << actual.type())); } } |