Merge branch 'sunshine' of https://github.com/Shyotl/SingularityViewer
This commit is contained in:
@@ -76,6 +76,7 @@ protected:
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LL_ALIGN_PREFIX(16)
|
||||||
class LLDriverParam : public LLViewerVisualParam
|
class LLDriverParam : public LLViewerVisualParam
|
||||||
{
|
{
|
||||||
friend class LLPhysicsMotion;
|
friend class LLPhysicsMotion;
|
||||||
@@ -133,13 +134,13 @@ protected:
|
|||||||
void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake);
|
void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake);
|
||||||
|
|
||||||
|
|
||||||
LLVector4a mDefaultVec; // temp holder
|
LL_ALIGN_16(LLVector4a mDefaultVec); // temp holder
|
||||||
typedef std::vector<LLDrivenEntry> entry_list_t;
|
typedef std::vector<LLDrivenEntry> entry_list_t;
|
||||||
entry_list_t mDriven;
|
entry_list_t mDriven;
|
||||||
LLViewerVisualParam* mCurrentDistortionParam;
|
LLViewerVisualParam* mCurrentDistortionParam;
|
||||||
// Backlink only; don't make this an LLPointer.
|
// Backlink only; don't make this an LLPointer.
|
||||||
LLAvatarAppearance* mAvatarAppearance;
|
LLAvatarAppearance* mAvatarAppearance;
|
||||||
LLWearable* mWearablep;
|
LLWearable* mWearablep;
|
||||||
};
|
} LL_ALIGN_POSTFIX(16);
|
||||||
|
|
||||||
#endif // LL_LLDRIVERPARAM_H
|
#endif // LL_LLDRIVERPARAM_H
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ class LLWearable;
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// LLPolyMorphData()
|
// LLPolyMorphData()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
LL_ALIGN_PREFIX(16)
|
||||||
class LLPolyMorphData
|
class LLPolyMorphData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -79,12 +80,13 @@ public:
|
|||||||
|
|
||||||
F32 mTotalDistortion; // vertex distortion summed over entire morph
|
F32 mTotalDistortion; // vertex distortion summed over entire morph
|
||||||
F32 mMaxDistortion; // maximum single vertex distortion in a given morph
|
F32 mMaxDistortion; // maximum single vertex distortion in a given morph
|
||||||
LLVector4a mAvgDistortion; // average vertex distortion, to infer directionality of the morph
|
LL_ALIGN_16(LLVector4a mAvgDistortion); // average vertex distortion, to infer directionality of the morph
|
||||||
LLPolyMeshSharedData* mMesh;
|
LLPolyMeshSharedData* mMesh;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void freeData();
|
void freeData();
|
||||||
};
|
} LL_ALIGN_POSTFIX(16);
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// LLPolyVertexMask()
|
// LLPolyVertexMask()
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ struct LLPolySkeletalBoneInfo
|
|||||||
BOOL mHasPositionDeformation;
|
BOOL mHasPositionDeformation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
LL_ALIGN_PREFIX(16)
|
||||||
class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo
|
class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo
|
||||||
{
|
{
|
||||||
friend class LLPolySkeletalDistortion;
|
friend class LLPolySkeletalDistortion;
|
||||||
@@ -118,13 +119,13 @@ public:
|
|||||||
/*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;};
|
/*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
LL_ALIGN_16(LLVector4a mDefaultVec);
|
||||||
typedef std::map<LLJoint*, LLVector3> joint_vec_map_t;
|
typedef std::map<LLJoint*, LLVector3> joint_vec_map_t;
|
||||||
joint_vec_map_t mJointScales;
|
joint_vec_map_t mJointScales;
|
||||||
joint_vec_map_t mJointOffsets;
|
joint_vec_map_t mJointOffsets;
|
||||||
LLVector4a mDefaultVec;
|
|
||||||
// Backlink only; don't make this an LLPointer.
|
// Backlink only; don't make this an LLPointer.
|
||||||
LLAvatarAppearance *mAvatar;
|
LLAvatarAppearance *mAvatar;
|
||||||
};
|
} LL_ALIGN_POSTFIX(16);
|
||||||
|
|
||||||
#endif // LL_LLPOLYSKELETALDISTORTION_H
|
#endif // LL_LLPOLYSKELETALDISTORTION_H
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ protected:
|
|||||||
// LLTexLayerParamAlpha
|
// LLTexLayerParamAlpha
|
||||||
//
|
//
|
||||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
LL_ALIGN_PREFIX(16)
|
||||||
class LLTexLayerParamAlpha : public LLTexLayerParam
|
class LLTexLayerParamAlpha : public LLTexLayerParam
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -67,8 +68,6 @@ public:
|
|||||||
LLTexLayerParamAlpha( LLAvatarAppearance* appearance );
|
LLTexLayerParamAlpha( LLAvatarAppearance* appearance );
|
||||||
/*virtual*/ ~LLTexLayerParamAlpha();
|
/*virtual*/ ~LLTexLayerParamAlpha();
|
||||||
|
|
||||||
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const;
|
|
||||||
|
|
||||||
void* operator new(size_t size)
|
void* operator new(size_t size)
|
||||||
{
|
{
|
||||||
return ll_aligned_malloc_16(size);
|
return ll_aligned_malloc_16(size);
|
||||||
@@ -79,6 +78,8 @@ public:
|
|||||||
ll_aligned_free_16(ptr);
|
ll_aligned_free_16(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const;
|
||||||
|
|
||||||
// LLVisualParam Virtual functions
|
// LLVisualParam Virtual functions
|
||||||
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
|
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
|
||||||
/*virtual*/ void apply( ESex avatar_sex ) {}
|
/*virtual*/ void apply( ESex avatar_sex ) {}
|
||||||
@@ -106,7 +107,7 @@ private:
|
|||||||
LLPointer<LLImageRaw> mStaticImageRaw;
|
LLPointer<LLImageRaw> mStaticImageRaw;
|
||||||
BOOL mNeedsCreateTexture;
|
BOOL mNeedsCreateTexture;
|
||||||
BOOL mStaticImageInvalid;
|
BOOL mStaticImageInvalid;
|
||||||
LLVector4a mAvgDistortionVec;
|
LL_ALIGN_16(LLVector4a mAvgDistortionVec);
|
||||||
F32 mCachedEffectiveWeight;
|
F32 mCachedEffectiveWeight;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -116,7 +117,7 @@ public:
|
|||||||
|
|
||||||
typedef std::list< LLTexLayerParamAlpha* > param_alpha_ptr_list_t;
|
typedef std::list< LLTexLayerParamAlpha* > param_alpha_ptr_list_t;
|
||||||
static param_alpha_ptr_list_t sInstances;
|
static param_alpha_ptr_list_t sInstances;
|
||||||
};
|
} LL_ALIGN_POSTFIX(16);
|
||||||
class LLTexLayerParamAlphaInfo : public LLViewerVisualParamInfo
|
class LLTexLayerParamAlphaInfo : public LLViewerVisualParamInfo
|
||||||
{
|
{
|
||||||
friend class LLTexLayerParamAlpha;
|
friend class LLTexLayerParamAlpha;
|
||||||
@@ -140,6 +141,8 @@ private:
|
|||||||
// LLTexLayerParamColor
|
// LLTexLayerParamColor
|
||||||
//
|
//
|
||||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
LL_ALIGN_PREFIX(16)
|
||||||
class LLTexLayerParamColor : public LLTexLayerParam
|
class LLTexLayerParamColor : public LLTexLayerParam
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -153,7 +156,6 @@ public:
|
|||||||
|
|
||||||
LLTexLayerParamColor( LLTexLayerInterface* layer );
|
LLTexLayerParamColor( LLTexLayerInterface* layer );
|
||||||
LLTexLayerParamColor( LLAvatarAppearance* appearance );
|
LLTexLayerParamColor( LLAvatarAppearance* appearance );
|
||||||
/* virtual */ ~LLTexLayerParamColor();
|
|
||||||
|
|
||||||
void* operator new(size_t size)
|
void* operator new(size_t size)
|
||||||
{
|
{
|
||||||
@@ -165,6 +167,8 @@ public:
|
|||||||
ll_aligned_free_16(ptr);
|
ll_aligned_free_16(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* virtual */ ~LLTexLayerParamColor();
|
||||||
|
|
||||||
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const;
|
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const;
|
||||||
|
|
||||||
// LLVisualParam Virtual functions
|
// LLVisualParam Virtual functions
|
||||||
@@ -188,8 +192,8 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
virtual void onGlobalColorChanged(bool upload_bake) {}
|
virtual void onGlobalColorChanged(bool upload_bake) {}
|
||||||
private:
|
private:
|
||||||
LLVector4a mAvgDistortionVec;
|
LL_ALIGN_16(LLVector4a mAvgDistortionVec);
|
||||||
};
|
} LL_ALIGN_POSTFIX(16);
|
||||||
|
|
||||||
class LLTexLayerParamColorInfo : public LLViewerVisualParamInfo
|
class LLTexLayerParamColorInfo : public LLViewerVisualParamInfo
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ protected:
|
|||||||
// VIRTUAL CLASS
|
// VIRTUAL CLASS
|
||||||
// a viewer side interface class for a generalized parametric modification of the avatar mesh
|
// a viewer side interface class for a generalized parametric modification of the avatar mesh
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
LL_ALIGN_PREFIX(16)
|
||||||
class LLViewerVisualParam : public LLVisualParam
|
class LLViewerVisualParam : public LLVisualParam
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -106,6 +107,6 @@ public:
|
|||||||
|
|
||||||
BOOL getCrossWearable() const { return getInfo()->mCrossWearable; }
|
BOOL getCrossWearable() const { return getInfo()->mCrossWearable; }
|
||||||
|
|
||||||
};
|
} LL_ALIGN_POSTFIX(16);
|
||||||
|
|
||||||
#endif // LL_LLViewerVisualParam_H
|
#endif // LL_LLViewerVisualParam_H
|
||||||
|
|||||||
@@ -35,28 +35,6 @@
|
|||||||
DECLARE_bool(heap_profile_use_stack_trace);
|
DECLARE_bool(heap_profile_use_stack_trace);
|
||||||
//DECLARE_double(tcmalloc_release_rate);
|
//DECLARE_double(tcmalloc_release_rate);
|
||||||
|
|
||||||
// static
|
|
||||||
void LLAllocator::pushMemType(S32 type)
|
|
||||||
{
|
|
||||||
if(isProfiling())
|
|
||||||
{
|
|
||||||
PushMemType(type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
S32 LLAllocator::popMemType()
|
|
||||||
{
|
|
||||||
if (isProfiling())
|
|
||||||
{
|
|
||||||
return PopMemType();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LLAllocator::setProfilingEnabled(bool should_enable)
|
void LLAllocator::setProfilingEnabled(bool should_enable)
|
||||||
{
|
{
|
||||||
// NULL disables dumping to disk
|
// NULL disables dumping to disk
|
||||||
@@ -94,17 +72,6 @@ std::string LLAllocator::getRawProfile()
|
|||||||
// stub implementations for when tcmalloc is disabled
|
// stub implementations for when tcmalloc is disabled
|
||||||
//
|
//
|
||||||
|
|
||||||
// static
|
|
||||||
void LLAllocator::pushMemType(S32 type)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
S32 LLAllocator::popMemType()
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LLAllocator::setProfilingEnabled(bool should_enable)
|
void LLAllocator::setProfilingEnabled(bool should_enable)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,16 +29,10 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "llmemtype.h"
|
|
||||||
#include "llallocator_heap_profile.h"
|
#include "llallocator_heap_profile.h"
|
||||||
|
|
||||||
class LL_COMMON_API LLAllocator {
|
class LL_COMMON_API LLAllocator {
|
||||||
friend class LLMemoryView;
|
friend class LLMemoryView;
|
||||||
friend class LLMemType;
|
|
||||||
|
|
||||||
private:
|
|
||||||
static void pushMemType(S32 type);
|
|
||||||
static S32 popMemType();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void setProfilingEnabled(bool should_enable);
|
void setProfilingEnabled(bool should_enable);
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <boost/function.hpp>
|
#include <boost/function.hpp>
|
||||||
#include <boost/type_traits/is_convertible.hpp>
|
#include <boost/type_traits/is_convertible.hpp>
|
||||||
|
#include <boost/type_traits/is_enum.hpp>
|
||||||
#include <boost/unordered_map.hpp>
|
#include <boost/unordered_map.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
@@ -224,32 +225,81 @@ namespace LLInitParam
|
|||||||
typedef std::map<const std::type_info*, parser_write_func_t> parser_write_func_map_t;
|
typedef std::map<const std::type_info*, parser_write_func_t> parser_write_func_map_t;
|
||||||
typedef std::map<const std::type_info*, parser_inspect_func_t> parser_inspect_func_map_t;
|
typedef std::map<const std::type_info*, parser_inspect_func_t> parser_inspect_func_map_t;
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename T, bool is_enum = boost::is_enum<T>::value>
|
||||||
|
struct ReaderWriter
|
||||||
|
{
|
||||||
|
static bool read(T& param, Parser* parser)
|
||||||
|
{
|
||||||
|
parser_read_func_map_t::iterator found_it = parser->mParserReadFuncs->find(&typeid(T));
|
||||||
|
if (found_it != parser->mParserReadFuncs->end())
|
||||||
|
{
|
||||||
|
return found_it->second(*parser, (void*)¶m);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool write(const T& param, Parser* parser, name_stack_t& name_stack)
|
||||||
|
{
|
||||||
|
parser_write_func_map_t::iterator found_it = parser->mParserWriteFuncs->find(&typeid(T));
|
||||||
|
if (found_it != parser->mParserWriteFuncs->end())
|
||||||
|
{
|
||||||
|
return found_it->second(*parser, (const void*)¶m, name_stack);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// read enums as ints
|
||||||
|
template<typename T>
|
||||||
|
struct ReaderWriter<T, true>
|
||||||
|
{
|
||||||
|
static bool read(T& param, Parser* parser)
|
||||||
|
{
|
||||||
|
// read all enums as ints
|
||||||
|
parser_read_func_map_t::iterator found_it = parser->mParserReadFuncs->find(&typeid(S32));
|
||||||
|
if (found_it != parser->mParserReadFuncs->end())
|
||||||
|
{
|
||||||
|
S32 value;
|
||||||
|
if (found_it->second(*parser, (void*)&value))
|
||||||
|
{
|
||||||
|
param = (T)value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool write(const T& param, Parser* parser, name_stack_t& name_stack)
|
||||||
|
{
|
||||||
|
parser_write_func_map_t::iterator found_it = parser->mParserWriteFuncs->find(&typeid(S32));
|
||||||
|
if (found_it != parser->mParserWriteFuncs->end())
|
||||||
|
{
|
||||||
|
return found_it->second(*parser, (const void*)¶m, name_stack);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)
|
Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)
|
||||||
: mParseSilently(false),
|
: mParseSilently(false),
|
||||||
mParserReadFuncs(&read_map),
|
mParserReadFuncs(&read_map),
|
||||||
mParserWriteFuncs(&write_map),
|
mParserWriteFuncs(&write_map),
|
||||||
mParserInspectFuncs(&inspect_map)
|
mParserInspectFuncs(&inspect_map)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual ~Parser();
|
virtual ~Parser();
|
||||||
|
|
||||||
template <typename T> bool readValue(T& param)
|
template <typename T> bool readValue(T& param)
|
||||||
{
|
{
|
||||||
parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T));
|
return ReaderWriter<T>::read(param, this);
|
||||||
if (found_it != mParserReadFuncs->end())
|
|
||||||
{
|
|
||||||
return found_it->second(*this, (void*)¶m);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> bool writeValue(const T& param, name_stack_t& name_stack)
|
template <typename T> bool writeValue(const T& param, name_stack_t& name_stack)
|
||||||
{
|
{
|
||||||
parser_write_func_map_t::iterator found_it = mParserWriteFuncs->find(&typeid(T));
|
return ReaderWriter<T>::write(param, this, name_stack);
|
||||||
if (found_it != mParserWriteFuncs->end())
|
|
||||||
{
|
|
||||||
return found_it->second(*this, (const void*)¶m, name_stack);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// dispatch inspection to registered inspection functions, for each parameter in a param block
|
// dispatch inspection to registered inspection functions, for each parameter in a param block
|
||||||
@@ -841,31 +891,25 @@ namespace LLInitParam
|
|||||||
self_t& typed_param = static_cast<self_t&>(param);
|
self_t& typed_param = static_cast<self_t&>(param);
|
||||||
// no further names in stack, attempt to parse value now
|
// no further names in stack, attempt to parse value now
|
||||||
if (name_stack_range.first == name_stack_range.second)
|
if (name_stack_range.first == name_stack_range.second)
|
||||||
{
|
{
|
||||||
if (parser.readValue(typed_param.getValue()))
|
std::string name;
|
||||||
|
|
||||||
|
// try to parse a known named value
|
||||||
|
if(name_value_lookup_t::valueNamesExist()
|
||||||
|
&& parser.readValue(name)
|
||||||
|
&& name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
|
||||||
|
{
|
||||||
|
typed_param.setValueName(name);
|
||||||
|
typed_param.setProvided();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// try to read value directly
|
||||||
|
else if (parser.readValue(typed_param.getValue()))
|
||||||
{
|
{
|
||||||
typed_param.clearValueName();
|
typed_param.clearValueName();
|
||||||
typed_param.setProvided();
|
typed_param.setProvided();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to parse a known named value
|
|
||||||
if(name_value_lookup_t::valueNamesExist())
|
|
||||||
{
|
|
||||||
// try to parse a known named value
|
|
||||||
std::string name;
|
|
||||||
if (parser.readValue(name))
|
|
||||||
{
|
|
||||||
// try to parse a per type named value
|
|
||||||
if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
|
|
||||||
{
|
|
||||||
typed_param.setValueName(name);
|
|
||||||
typed_param.setProvided();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -987,30 +1031,29 @@ namespace LLInitParam
|
|||||||
static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
|
static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
|
||||||
{
|
{
|
||||||
self_t& typed_param = static_cast<self_t&>(param);
|
self_t& typed_param = static_cast<self_t&>(param);
|
||||||
// attempt to parse block...
|
|
||||||
|
if (name_stack_range.first == name_stack_range.second)
|
||||||
|
{ // try to parse a known named value
|
||||||
|
std::string name;
|
||||||
|
|
||||||
|
if(name_value_lookup_t::valueNamesExist()
|
||||||
|
&& parser.readValue(name)
|
||||||
|
&& name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
|
||||||
|
{
|
||||||
|
typed_param.setValueName(name);
|
||||||
|
typed_param.setProvided();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(typed_param.deserializeBlock(parser, name_stack_range, new_name))
|
if(typed_param.deserializeBlock(parser, name_stack_range, new_name))
|
||||||
{
|
{ // attempt to parse block...
|
||||||
typed_param.clearValueName();
|
typed_param.clearValueName();
|
||||||
typed_param.setProvided();
|
typed_param.setProvided();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(name_value_lookup_t::valueNamesExist())
|
|
||||||
{
|
|
||||||
// try to parse a known named value
|
|
||||||
std::string name;
|
|
||||||
if (parser.readValue(name))
|
|
||||||
{
|
|
||||||
// try to parse a per type named value
|
|
||||||
if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
|
|
||||||
{
|
|
||||||
typed_param.setValueName(name);
|
|
||||||
typed_param.setProvided();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1160,31 +1203,23 @@ namespace LLInitParam
|
|||||||
value_t value;
|
value_t value;
|
||||||
// no further names in stack, attempt to parse value now
|
// no further names in stack, attempt to parse value now
|
||||||
if (name_stack_range.first == name_stack_range.second)
|
if (name_stack_range.first == name_stack_range.second)
|
||||||
{
|
{
|
||||||
// attempt to read value directly
|
std::string name;
|
||||||
if (parser.readValue(value))
|
|
||||||
|
// try to parse a known named value
|
||||||
|
if(name_value_lookup_t::valueNamesExist()
|
||||||
|
&& parser.readValue(name)
|
||||||
|
&& name_value_lookup_t::getValueFromName(name, value))
|
||||||
|
{
|
||||||
|
typed_param.add(value);
|
||||||
|
typed_param.mValues.back().setValueName(name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (parser.readValue(value)) // attempt to read value directly
|
||||||
{
|
{
|
||||||
typed_param.add(value);
|
typed_param.add(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to parse a known named value
|
|
||||||
if(name_value_lookup_t::valueNamesExist())
|
|
||||||
{
|
|
||||||
// try to parse a known named value
|
|
||||||
std::string name;
|
|
||||||
if (parser.readValue(name))
|
|
||||||
{
|
|
||||||
// try to parse a per type named value
|
|
||||||
if (name_value_lookup_t::getValueFromName(name, value))
|
|
||||||
{
|
|
||||||
typed_param.add(value);
|
|
||||||
typed_param.mValues.back().setValueName(name);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1362,28 +1397,27 @@ namespace LLInitParam
|
|||||||
|
|
||||||
param_value_t& value = typed_param.mValues.back();
|
param_value_t& value = typed_param.mValues.back();
|
||||||
|
|
||||||
|
if (name_stack_range.first == name_stack_range.second)
|
||||||
|
{ // try to parse a known named value
|
||||||
|
std::string name;
|
||||||
|
|
||||||
|
if(name_value_lookup_t::valueNamesExist()
|
||||||
|
&& parser.readValue(name)
|
||||||
|
&& name_value_lookup_t::getValueFromName(name, value.getValue()))
|
||||||
|
{
|
||||||
|
typed_param.mValues.back().setValueName(name);
|
||||||
|
typed_param.setProvided();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// attempt to parse block...
|
// attempt to parse block...
|
||||||
if(value.deserializeBlock(parser, name_stack_range, new_name))
|
if(value.deserializeBlock(parser, name_stack_range, new_name))
|
||||||
{
|
{
|
||||||
typed_param.setProvided();
|
typed_param.setProvided();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if(name_value_lookup_t::valueNamesExist())
|
|
||||||
{
|
|
||||||
// try to parse a known named value
|
|
||||||
std::string name;
|
|
||||||
if (parser.readValue(name))
|
|
||||||
{
|
|
||||||
// try to parse a per type named value
|
|
||||||
if (name_value_lookup_t::getValueFromName(name, value.getValue()))
|
|
||||||
{
|
|
||||||
typed_param.mValues.back().setValueName(name);
|
|
||||||
typed_param.setProvided();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (new_value)
|
if (new_value)
|
||||||
{ // failed to parse new value, pop it off
|
{ // failed to parse new value, pop it off
|
||||||
|
|||||||
@@ -27,7 +27,9 @@
|
|||||||
#include "llmemtype.h"
|
#include "llmemtype.h"
|
||||||
#include "llallocator.h"
|
#include "llallocator.h"
|
||||||
|
|
||||||
|
#if MEM_TRACK_TYPE
|
||||||
std::vector<char const *> LLMemType::DeclareMemType::mNameList;
|
std::vector<char const *> LLMemType::DeclareMemType::mNameList;
|
||||||
|
#endif
|
||||||
|
|
||||||
LLMemType::DeclareMemType LLMemType::MTYPE_INIT("Init");
|
LLMemType::DeclareMemType LLMemType::MTYPE_INIT("Init");
|
||||||
LLMemType::DeclareMemType LLMemType::MTYPE_STARTUP("Startup");
|
LLMemType::DeclareMemType LLMemType::MTYPE_STARTUP("Startup");
|
||||||
@@ -194,7 +196,7 @@ LLMemType::DeclareMemType LLMemType::MTYPE_TEMP9("Temp9");
|
|||||||
|
|
||||||
LLMemType::DeclareMemType LLMemType::MTYPE_OTHER("Other");
|
LLMemType::DeclareMemType LLMemType::MTYPE_OTHER("Other");
|
||||||
|
|
||||||
|
#if MEM_TRACK_TYPE
|
||||||
LLMemType::DeclareMemType::DeclareMemType(char const * st)
|
LLMemType::DeclareMemType::DeclareMemType(char const * st)
|
||||||
{
|
{
|
||||||
mID = (S32)mNameList.size();
|
mID = (S32)mNameList.size();
|
||||||
@@ -229,3 +231,4 @@ char const * LLMemType::getNameFromID(S32 id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
#endif //MEM_TRACK_TYPE
|
||||||
@@ -52,6 +52,10 @@ public:
|
|||||||
class LL_COMMON_API DeclareMemType
|
class LL_COMMON_API DeclareMemType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
#if !MEM_TRACK_TYPE
|
||||||
|
DeclareMemType(char const * st) {}; //Do nothing
|
||||||
|
#else
|
||||||
DeclareMemType(char const * st);
|
DeclareMemType(char const * st);
|
||||||
~DeclareMemType();
|
~DeclareMemType();
|
||||||
|
|
||||||
@@ -60,12 +64,17 @@ public:
|
|||||||
|
|
||||||
// array so we can map an index ID to Name
|
// array so we can map an index ID to Name
|
||||||
static std::vector<char const *> mNameList;
|
static std::vector<char const *> mNameList;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !MEM_TRACK_TYPE
|
||||||
|
LLMemType(DeclareMemType& dt){} //Do nothing
|
||||||
|
#else
|
||||||
LLMemType(DeclareMemType& dt);
|
LLMemType(DeclareMemType& dt);
|
||||||
~LLMemType();
|
~LLMemType();
|
||||||
|
|
||||||
static char const * getNameFromID(S32 id);
|
static char const * getNameFromID(S32 id);
|
||||||
|
#endif
|
||||||
|
|
||||||
static DeclareMemType MTYPE_INIT;
|
static DeclareMemType MTYPE_INIT;
|
||||||
static DeclareMemType MTYPE_STARTUP;
|
static DeclareMemType MTYPE_STARTUP;
|
||||||
@@ -232,7 +241,9 @@ public:
|
|||||||
|
|
||||||
static DeclareMemType MTYPE_OTHER; // Special; used by display code
|
static DeclareMemType MTYPE_OTHER; // Special; used by display code
|
||||||
|
|
||||||
|
#if MEM_TRACK_TYPE
|
||||||
S32 mTypeIndex;
|
S32 mTypeIndex;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -598,7 +598,7 @@ bool llsd_equals(const LLSD& lhs, const LLSD& rhs, unsigned bits)
|
|||||||
case LLSD::TypeReal:
|
case LLSD::TypeReal:
|
||||||
// This is where the 'bits' argument comes in handy. If passed
|
// This is where the 'bits' argument comes in handy. If passed
|
||||||
// explicitly, it means to use is_approx_equal_fraction() to compare.
|
// explicitly, it means to use is_approx_equal_fraction() to compare.
|
||||||
if (bits >= 0)
|
if (bits != -1)
|
||||||
{
|
{
|
||||||
return is_approx_equal_fraction(lhs.asReal(), rhs.asReal(), bits);
|
return is_approx_equal_fraction(lhs.asReal(), rhs.asReal(), bits);
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -27,294 +27,52 @@
|
|||||||
#ifndef LL_LLSTAT_H
|
#ifndef LL_LLSTAT_H
|
||||||
#define LL_LLSTAT_H
|
#define LL_LLSTAT_H
|
||||||
|
|
||||||
#include <deque>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "lltimer.h"
|
#include "lltimer.h"
|
||||||
#include "llframetimer.h"
|
#include "llframetimer.h"
|
||||||
#include "llfile.h"
|
|
||||||
|
|
||||||
class LLSD;
|
class LLSD;
|
||||||
|
|
||||||
// Set this if longer stats are needed
|
|
||||||
#define ENABLE_LONG_TIME_STATS 0
|
|
||||||
|
|
||||||
//
|
|
||||||
// Accumulates statistics for an arbitrary length of time.
|
|
||||||
// Does this by maintaining a chain of accumulators, each one
|
|
||||||
// accumulation the results of the parent. Can scale to arbitrary
|
|
||||||
// amounts of time with very low memory cost.
|
|
||||||
//
|
|
||||||
|
|
||||||
class LL_COMMON_API LLStatAccum
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
LLStatAccum(bool use_frame_timer);
|
|
||||||
virtual ~LLStatAccum();
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum TimeScale {
|
|
||||||
SCALE_100MS,
|
|
||||||
SCALE_SECOND,
|
|
||||||
SCALE_MINUTE,
|
|
||||||
#if ENABLE_LONG_TIME_STATS
|
|
||||||
SCALE_HOUR,
|
|
||||||
SCALE_DAY,
|
|
||||||
SCALE_WEEK,
|
|
||||||
#endif
|
|
||||||
NUM_SCALES, // Use to size storage arrays
|
|
||||||
SCALE_PER_FRAME // For latest frame information - should be after NUM_SCALES since this doesn't go into the time buckets
|
|
||||||
};
|
|
||||||
|
|
||||||
static U64 sScaleTimes[NUM_SCALES];
|
|
||||||
|
|
||||||
virtual F32 meanValue(TimeScale scale) const;
|
|
||||||
// see the subclasses for the specific meaning of value
|
|
||||||
|
|
||||||
F32 meanValueOverLast100ms() const { return meanValue(SCALE_100MS); }
|
|
||||||
F32 meanValueOverLastSecond() const { return meanValue(SCALE_SECOND); }
|
|
||||||
F32 meanValueOverLastMinute() const { return meanValue(SCALE_MINUTE); }
|
|
||||||
|
|
||||||
void reset(U64 when);
|
|
||||||
|
|
||||||
void sum(F64 value);
|
|
||||||
void sum(F64 value, U64 when);
|
|
||||||
|
|
||||||
U64 getCurrentUsecs() const;
|
|
||||||
// Get current microseconds based on timer type
|
|
||||||
|
|
||||||
BOOL mUseFrameTimer;
|
|
||||||
BOOL mRunning;
|
|
||||||
|
|
||||||
U64 mLastTime;
|
|
||||||
|
|
||||||
struct Bucket
|
|
||||||
{
|
|
||||||
Bucket() :
|
|
||||||
accum(0.0),
|
|
||||||
endTime(0),
|
|
||||||
lastValid(false),
|
|
||||||
lastAccum(0.0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
F64 accum;
|
|
||||||
U64 endTime;
|
|
||||||
|
|
||||||
bool lastValid;
|
|
||||||
F64 lastAccum;
|
|
||||||
};
|
|
||||||
|
|
||||||
Bucket mBuckets[NUM_SCALES];
|
|
||||||
|
|
||||||
BOOL mLastSampleValid;
|
|
||||||
F64 mLastSampleValue;
|
|
||||||
};
|
|
||||||
|
|
||||||
class LL_COMMON_API LLStatMeasure : public LLStatAccum
|
|
||||||
// gathers statistics about things that are measured
|
|
||||||
// ex.: tempature, time dilation
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
LLStatMeasure(bool use_frame_timer = true);
|
|
||||||
|
|
||||||
void sample(F64);
|
|
||||||
void sample(S32 v) { sample((F64)v); }
|
|
||||||
void sample(U32 v) { sample((F64)v); }
|
|
||||||
void sample(S64 v) { sample((F64)v); }
|
|
||||||
void sample(U64 v) { sample((F64)v); }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class LL_COMMON_API LLStatRate : public LLStatAccum
|
|
||||||
// gathers statistics about things that can be counted over time
|
|
||||||
// ex.: LSL instructions executed, messages sent, simulator frames completed
|
|
||||||
// renders it in terms of rate of thing per second
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
LLStatRate(bool use_frame_timer = true);
|
|
||||||
|
|
||||||
void count(U32);
|
|
||||||
// used to note that n items have occured
|
|
||||||
|
|
||||||
void mark();
|
|
||||||
// used for counting the rate thorugh a point in the code
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class LL_COMMON_API LLStatTime : public LLStatAccum
|
|
||||||
// gathers statistics about time spent in a block of code
|
|
||||||
// measure average duration per second in the block
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
LLStatTime( const std::string & key = "undefined" );
|
|
||||||
|
|
||||||
U32 mFrameNumber; // Current frame number
|
|
||||||
U64 mTotalTimeInFrame; // Total time (microseconds) accumulated during the last frame
|
|
||||||
|
|
||||||
void setKey( const std::string & key ) { mKey = key; };
|
|
||||||
|
|
||||||
virtual F32 meanValue(TimeScale scale) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void start(); // Start and stop measuring time block
|
|
||||||
void stop();
|
|
||||||
|
|
||||||
std::string mKey; // Tag representing this time block
|
|
||||||
|
|
||||||
#if LL_DEBUG
|
|
||||||
BOOL mRunning; // TRUE if start() has been called
|
|
||||||
#endif
|
|
||||||
|
|
||||||
friend class LLPerfBlock;
|
|
||||||
};
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
// Use this class on the stack to record statistics about an area of code
|
|
||||||
class LL_COMMON_API LLPerfBlock
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
struct StatEntry
|
|
||||||
{
|
|
||||||
StatEntry(const std::string& key) : mStat(LLStatTime(key)), mCount(0) {}
|
|
||||||
LLStatTime mStat;
|
|
||||||
U32 mCount;
|
|
||||||
};
|
|
||||||
typedef std::map<std::string, StatEntry*> stat_map_t;
|
|
||||||
|
|
||||||
// Use this constructor for pre-defined LLStatTime objects
|
|
||||||
LLPerfBlock(LLStatTime* stat);
|
|
||||||
|
|
||||||
// Use this constructor for normal, optional LLPerfBlock time slices
|
|
||||||
LLPerfBlock( const char* key );
|
|
||||||
|
|
||||||
// Use this constructor for dynamically created LLPerfBlock time slices
|
|
||||||
// that are only enabled by specific control flags
|
|
||||||
LLPerfBlock( const char* key1, const char* key2, S32 flags = LLSTATS_BASIC_STATS );
|
|
||||||
|
|
||||||
~LLPerfBlock();
|
|
||||||
|
|
||||||
enum
|
|
||||||
{ // Stats bitfield flags
|
|
||||||
LLSTATS_NO_OPTIONAL_STATS = 0x00, // No optional stats gathering, just pre-defined LLStatTime objects
|
|
||||||
LLSTATS_BASIC_STATS = 0x01, // Gather basic optional runtime stats
|
|
||||||
LLSTATS_SCRIPT_FUNCTIONS = 0x02, // Include LSL function calls
|
|
||||||
};
|
|
||||||
static void setStatsFlags( S32 flags ) { sStatsFlags = flags; };
|
|
||||||
static S32 getStatsFlags() { return sStatsFlags; };
|
|
||||||
|
|
||||||
static void clearDynamicStats(); // Reset maps to clear out dynamic objects
|
|
||||||
static void addStatsToLLSDandReset( LLSD & stats, // Get current information and clear time bin
|
|
||||||
LLStatAccum::TimeScale scale );
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Initialize dynamically created LLStatTime objects
|
|
||||||
void initDynamicStat(const std::string& key);
|
|
||||||
|
|
||||||
std::string mLastPath; // Save sCurrentStatPath when this is called
|
|
||||||
LLStatTime * mPredefinedStat; // LLStatTime object to get data
|
|
||||||
StatEntry * mDynamicStat; // StatEntryobject to get data
|
|
||||||
|
|
||||||
static S32 sStatsFlags; // Control what is being recorded
|
|
||||||
static stat_map_t sStatMap; // Map full path string to LLStatTime objects
|
|
||||||
static std::string sCurrentStatPath; // Something like "frame/physics/physics step"
|
|
||||||
};
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class LL_COMMON_API LLPerfStats
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
LLPerfStats(const std::string& process_name = "unknown", S32 process_pid = 0);
|
|
||||||
virtual ~LLPerfStats();
|
|
||||||
|
|
||||||
virtual void init(); // Reset and start all stat timers
|
|
||||||
virtual void updatePerFrameStats();
|
|
||||||
// Override these function to add process-specific information to the performance log header and per-frame logging.
|
|
||||||
virtual void addProcessHeaderInfo(LLSD& info) { /* not implemented */ }
|
|
||||||
virtual void addProcessFrameInfo(LLSD& info, LLStatAccum::TimeScale scale) { /* not implemented */ }
|
|
||||||
|
|
||||||
// High-resolution frame stats
|
|
||||||
BOOL frameStatsIsRunning() { return (mReportPerformanceStatEnd > 0.); };
|
|
||||||
F32 getReportPerformanceInterval() const { return mReportPerformanceStatInterval; };
|
|
||||||
void setReportPerformanceInterval( F32 interval ) { mReportPerformanceStatInterval = interval; };
|
|
||||||
void setReportPerformanceDuration( F32 seconds, S32 flags = LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS );
|
|
||||||
void setProcessName(const std::string& process_name) { mProcessName = process_name; }
|
|
||||||
void setProcessPID(S32 process_pid) { mProcessPID = process_pid; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void openPerfStatsFile(); // Open file for high resolution metrics logging
|
|
||||||
void dumpIntervalPerformanceStats();
|
|
||||||
|
|
||||||
llofstream mFrameStatsFile; // File for per-frame stats
|
|
||||||
BOOL mFrameStatsFileFailure; // Flag to prevent repeat opening attempts
|
|
||||||
BOOL mSkipFirstFrameStats; // Flag to skip one (partial) frame report
|
|
||||||
std::string mProcessName;
|
|
||||||
S32 mProcessPID;
|
|
||||||
|
|
||||||
private:
|
|
||||||
F32 mReportPerformanceStatInterval; // Seconds between performance stats
|
|
||||||
F64 mReportPerformanceStatEnd; // End time (seconds) for performance stats
|
|
||||||
};
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
class LL_COMMON_API LLStat
|
class LL_COMMON_API LLStat
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
typedef std::multimap<std::string, LLStat*> stat_map_t;
|
typedef std::multimap<std::string, LLStat*> stat_map_t;
|
||||||
|
|
||||||
void init();
|
|
||||||
static stat_map_t& getStatList();
|
static stat_map_t& getStatList();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LLStat(U32 num_bins = 32, BOOL use_frame_timer = FALSE);
|
LLStat(std::string name = std::string(), S32 num_bins = 32, BOOL use_frame_timer = FALSE);
|
||||||
LLStat(std::string name, U32 num_bins = 32, BOOL use_frame_timer = FALSE);
|
|
||||||
~LLStat();
|
~LLStat();
|
||||||
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
void start(); // Start the timer for the current "frame", otherwise uses the time tracked from
|
void start(); // Start the timer for the current "frame", otherwise uses the time tracked from
|
||||||
// the last addValue
|
// the last addValue
|
||||||
|
void reset();
|
||||||
void addValue(const F32 value = 1.f); // Adds the current value being tracked, and tracks the DT.
|
void addValue(const F32 value = 1.f); // Adds the current value being tracked, and tracks the DT.
|
||||||
void addValue(const S32 value) { addValue((F32)value); }
|
void addValue(const S32 value) { addValue((F32)value); }
|
||||||
void addValue(const U32 value) { addValue((F32)value); }
|
void addValue(const U32 value) { addValue((F32)value); }
|
||||||
|
|
||||||
void setBeginTime(const F64 time);
|
|
||||||
void addValueTime(const F64 time, const F32 value = 1.f);
|
|
||||||
|
|
||||||
S32 getCurBin() const;
|
S32 getCurBin() const;
|
||||||
S32 getNextBin() const;
|
S32 getNextBin() const;
|
||||||
|
|
||||||
F32 getCurrent() const;
|
|
||||||
F32 getCurrentPerSec() const;
|
|
||||||
F64 getCurrentBeginTime() const;
|
|
||||||
F64 getCurrentTime() const;
|
|
||||||
F32 getCurrentDuration() const;
|
|
||||||
|
|
||||||
F32 getPrev(S32 age) const; // Age is how many "addValues" previously - zero is current
|
F32 getPrev(S32 age) const; // Age is how many "addValues" previously - zero is current
|
||||||
F32 getPrevPerSec(S32 age) const; // Age is how many "addValues" previously - zero is current
|
F32 getPrevPerSec(S32 age) const; // Age is how many "addValues" previously - zero is current
|
||||||
|
F32 getCurrent() const;
|
||||||
|
F32 getCurrentPerSec() const;
|
||||||
|
F32 getCurrentDuration() const;
|
||||||
|
|
||||||
F64 getPrevBeginTime(S32 age) const;
|
F64 getPrevBeginTime(S32 age) const;
|
||||||
F64 getPrevTime(S32 age) const;
|
F64 getPrevTime(S32 age) const;
|
||||||
|
|
||||||
F32 getBin(S32 bin) const;
|
|
||||||
F32 getBinPerSec(S32 bin) const;
|
|
||||||
F64 getBinBeginTime(S32 bin) const;
|
|
||||||
F64 getBinTime(S32 bin) const;
|
F64 getBinTime(S32 bin) const;
|
||||||
|
|
||||||
F32 getMax() const;
|
|
||||||
F32 getMaxPerSec() const;
|
|
||||||
|
|
||||||
F32 getMean() const;
|
|
||||||
F32 getMeanPerSec() const;
|
|
||||||
F32 getMeanDuration() const;
|
|
||||||
|
|
||||||
F32 getMin() const;
|
F32 getMin() const;
|
||||||
F32 getMinPerSec() const;
|
F32 getMinPerSec() const;
|
||||||
F32 getMinDuration() const;
|
F32 getMean() const;
|
||||||
|
F32 getMeanPerSec() const;
|
||||||
F32 getSum() const;
|
F32 getMeanDuration() const;
|
||||||
F32 getSumDuration() const;
|
F32 getMax() const;
|
||||||
|
F32 getMaxPerSec() const;
|
||||||
|
|
||||||
U32 getNumValues() const;
|
U32 getNumValues() const;
|
||||||
S32 getNumBins() const;
|
S32 getNumBins() const;
|
||||||
@@ -326,10 +84,21 @@ private:
|
|||||||
U32 mNumBins;
|
U32 mNumBins;
|
||||||
F32 mLastValue;
|
F32 mLastValue;
|
||||||
F64 mLastTime;
|
F64 mLastTime;
|
||||||
F32 *mBins;
|
|
||||||
F64 *mBeginTime;
|
struct ValueEntry
|
||||||
F64 *mTime;
|
{
|
||||||
F32 *mDT;
|
ValueEntry()
|
||||||
|
: mValue(0.f),
|
||||||
|
mBeginTime(0.0),
|
||||||
|
mTime(0.0),
|
||||||
|
mDT(0.f)
|
||||||
|
{}
|
||||||
|
F32 mValue;
|
||||||
|
F64 mBeginTime;
|
||||||
|
F64 mTime;
|
||||||
|
F32 mDT;
|
||||||
|
};
|
||||||
|
ValueEntry* mBins;
|
||||||
S32 mCurBin;
|
S32 mCurBin;
|
||||||
S32 mNextBin;
|
S32 mNextBin;
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,13 @@ enum
|
|||||||
LL_SIM_STAT_SIMSPARETIME = 32,
|
LL_SIM_STAT_SIMSPARETIME = 32,
|
||||||
LL_SIM_STAT_SIMSLEEPTIME = 33,
|
LL_SIM_STAT_SIMSLEEPTIME = 33,
|
||||||
LL_SIM_STAT_IOPUMPTIME = 34,
|
LL_SIM_STAT_IOPUMPTIME = 34,
|
||||||
|
LL_SIM_STAT_PCTSCRIPTSRUN = 35,
|
||||||
|
LL_SIM_STAT_REGION_IDLE = 36, // dataserver only
|
||||||
|
LL_SIM_STAT_REGION_IDLE_POSSIBLE = 37, // dataserver only
|
||||||
|
LL_SIM_STAT_SIMAISTEPTIMEMS = 38,
|
||||||
|
LL_SIM_STAT_SKIPPEDAISILSTEPS_PS = 39,
|
||||||
|
LL_SIM_STAT_PCTSTEPPEDCHARACTERS = 40
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -24,6 +24,10 @@
|
|||||||
* $/LicenseInfo$
|
* $/LicenseInfo$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if LL_WINDOWS
|
||||||
|
#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "linden_common.h"
|
#include "linden_common.h"
|
||||||
|
|
||||||
#include "llsys.h"
|
#include "llsys.h"
|
||||||
@@ -36,22 +40,45 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "llprocessor.h"
|
#include "llprocessor.h"
|
||||||
|
#include "llerrorcontrol.h"
|
||||||
|
#include "llevents.h"
|
||||||
|
#include "lltimer.h"
|
||||||
|
#include "llsdserialize.h"
|
||||||
|
#include "llsdutil.h"
|
||||||
|
#include <boost/bind.hpp>
|
||||||
|
#include <boost/circular_buffer.hpp>
|
||||||
|
#include <boost/regex.hpp>
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
#include <boost/range.hpp>
|
||||||
|
#include <boost/utility/enable_if.hpp>
|
||||||
|
#include <boost/type_traits/is_integral.hpp>
|
||||||
|
#include <boost/type_traits/is_float.hpp>
|
||||||
|
|
||||||
|
using namespace llsd;
|
||||||
|
|
||||||
#if LL_WINDOWS
|
#if LL_WINDOWS
|
||||||
# define WIN32_LEAN_AND_MEAN
|
# define WIN32_LEAN_AND_MEAN
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
|
# include <psapi.h> // GetPerformanceInfo() et al.
|
||||||
#elif LL_DARWIN
|
#elif LL_DARWIN
|
||||||
# include <errno.h>
|
# include <errno.h>
|
||||||
# include <sys/sysctl.h>
|
# include <sys/sysctl.h>
|
||||||
# include <sys/utsname.h>
|
# include <sys/utsname.h>
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
# include <Carbon/Carbon.h>
|
# include <Carbon/Carbon.h>
|
||||||
|
# include <stdexcept>
|
||||||
|
# include <mach/host_info.h>
|
||||||
|
# include <mach/mach_host.h>
|
||||||
|
# include <mach/task.h>
|
||||||
|
# include <mach/task_info.h>
|
||||||
#elif LL_LINUX
|
#elif LL_LINUX
|
||||||
# include <errno.h>
|
# include <errno.h>
|
||||||
# include <sys/utsname.h>
|
# include <sys/utsname.h>
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
# include <sys/sysinfo.h>
|
# include <sys/sysinfo.h>
|
||||||
|
# include <stdexcept>
|
||||||
const char MEMINFO_FILE[] = "/proc/meminfo";
|
const char MEMINFO_FILE[] = "/proc/meminfo";
|
||||||
#elif LL_SOLARIS
|
#elif LL_SOLARIS
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
@@ -70,6 +97,15 @@ extern int errno;
|
|||||||
static const S32 CPUINFO_BUFFER_SIZE = 16383;
|
static const S32 CPUINFO_BUFFER_SIZE = 16383;
|
||||||
LLCPUInfo gSysCPU;
|
LLCPUInfo gSysCPU;
|
||||||
|
|
||||||
|
// Don't log memory info any more often than this. It also serves as our
|
||||||
|
// framerate sample size.
|
||||||
|
static const F32 MEM_INFO_THROTTLE = 20;
|
||||||
|
// Sliding window of samples. We intentionally limit the length of time we
|
||||||
|
// remember "the slowest" framerate because framerate is very slow at login.
|
||||||
|
// If we only triggered FrameWatcher logging when the session framerate
|
||||||
|
// dropped below the login framerate, we'd have very little additional data.
|
||||||
|
static const F32 MEM_INFO_WINDOW = 10*60;
|
||||||
|
|
||||||
#if LL_WINDOWS
|
#if LL_WINDOWS
|
||||||
#ifndef DLLVERSIONINFO
|
#ifndef DLLVERSIONINFO
|
||||||
typedef struct _DllVersionInfo
|
typedef struct _DllVersionInfo
|
||||||
@@ -572,6 +608,7 @@ LLCPUInfo::LLCPUInfo()
|
|||||||
out << " (" << mCPUMHz << " MHz)";
|
out << " (" << mCPUMHz << " MHz)";
|
||||||
}
|
}
|
||||||
mCPUString = out.str();
|
mCPUString = out.str();
|
||||||
|
LLStringUtil::trim(mCPUString);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LLCPUInfo::hasAltivec() const
|
bool LLCPUInfo::hasAltivec() const
|
||||||
@@ -613,8 +650,78 @@ void LLCPUInfo::stream(std::ostream& s) const
|
|||||||
s << "->mCPUString: " << mCPUString << std::endl;
|
s << "->mCPUString: " << mCPUString << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper class for LLMemoryInfo: accumulate stats in the form we store for
|
||||||
|
// LLMemoryInfo::getStatsMap().
|
||||||
|
class Stats
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Stats():
|
||||||
|
mStats(LLSD::emptyMap())
|
||||||
|
{}
|
||||||
|
|
||||||
|
// Store every integer type as LLSD::Integer.
|
||||||
|
template <class T>
|
||||||
|
void add(const LLSD::String& name, const T& value,
|
||||||
|
typename boost::enable_if<boost::is_integral<T> >::type* = 0)
|
||||||
|
{
|
||||||
|
mStats[name] = LLSD::Integer(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store every floating-point type as LLSD::Real.
|
||||||
|
template <class T>
|
||||||
|
void add(const LLSD::String& name, const T& value,
|
||||||
|
typename boost::enable_if<boost::is_float<T> >::type* = 0)
|
||||||
|
{
|
||||||
|
mStats[name] = LLSD::Real(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hope that LLSD::Date values are sufficiently unambiguous.
|
||||||
|
void add(const LLSD::String& name, const LLSD::Date& value)
|
||||||
|
{
|
||||||
|
mStats[name] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLSD get() const { return mStats; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
LLSD mStats;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Wrap boost::regex_match() with a function that doesn't throw.
|
||||||
|
template <typename S, typename M, typename R>
|
||||||
|
static bool regex_match_no_exc(const S& string, M& match, const R& regex)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return boost::regex_match(string, match, regex);
|
||||||
|
}
|
||||||
|
catch (const std::runtime_error& e)
|
||||||
|
{
|
||||||
|
LL_WARNS("LLMemoryInfo") << "error matching with '" << regex.str() << "': "
|
||||||
|
<< e.what() << ":\n'" << string << "'" << LL_ENDL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap boost::regex_search() with a function that doesn't throw.
|
||||||
|
template <typename S, typename M, typename R>
|
||||||
|
static bool regex_search_no_exc(const S& string, M& match, const R& regex)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return boost::regex_search(string, match, regex);
|
||||||
|
}
|
||||||
|
catch (const std::runtime_error& e)
|
||||||
|
{
|
||||||
|
LL_WARNS("LLMemoryInfo") << "error searching with '" << regex.str() << "': "
|
||||||
|
<< e.what() << ":\n'" << string << "'" << LL_ENDL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LLMemoryInfo::LLMemoryInfo()
|
LLMemoryInfo::LLMemoryInfo()
|
||||||
{
|
{
|
||||||
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LL_WINDOWS
|
#if LL_WINDOWS
|
||||||
@@ -638,11 +745,7 @@ static U32 LLMemoryAdjustKBResult(U32 inKB)
|
|||||||
U32 LLMemoryInfo::getPhysicalMemoryKB() const
|
U32 LLMemoryInfo::getPhysicalMemoryKB() const
|
||||||
{
|
{
|
||||||
#if LL_WINDOWS
|
#if LL_WINDOWS
|
||||||
MEMORYSTATUSEX state;
|
return LLMemoryAdjustKBResult(mStatsMap["Total Physical KB"].asInteger());
|
||||||
state.dwLength = sizeof(state);
|
|
||||||
GlobalMemoryStatusEx(&state);
|
|
||||||
|
|
||||||
return LLMemoryAdjustKBResult((U32)(state.ullTotalPhys >> 10));
|
|
||||||
|
|
||||||
#elif LL_DARWIN
|
#elif LL_DARWIN
|
||||||
// This might work on Linux as well. Someone check...
|
// This might work on Linux as well. Someone check...
|
||||||
@@ -690,12 +793,82 @@ U32 LLMemoryInfo::getPhysicalMemoryClamped() const
|
|||||||
void LLMemoryInfo::getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_virtual_mem_kb)
|
void LLMemoryInfo::getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_virtual_mem_kb)
|
||||||
{
|
{
|
||||||
#if LL_WINDOWS
|
#if LL_WINDOWS
|
||||||
MEMORYSTATUSEX state;
|
// Sigh, this shouldn't be a static method, then we wouldn't have to
|
||||||
state.dwLength = sizeof(state);
|
// reload this data separately from refresh()
|
||||||
GlobalMemoryStatusEx(&state);
|
LLSD statsMap(loadStatsMap());
|
||||||
|
|
||||||
avail_physical_mem_kb = (U32)(state.ullAvailPhys/1024) ;
|
avail_physical_mem_kb = statsMap["Avail Physical KB"].asInteger();
|
||||||
avail_virtual_mem_kb = (U32)(state.ullAvailVirtual/1024) ;
|
avail_virtual_mem_kb = statsMap["Avail Virtual KB"].asInteger();
|
||||||
|
|
||||||
|
#elif LL_DARWIN
|
||||||
|
// mStatsMap is derived from vm_stat, look for (e.g.) "kb free":
|
||||||
|
// $ vm_stat
|
||||||
|
// Mach Virtual Memory Statistics: (page size of 4096 bytes)
|
||||||
|
// Pages free: 462078.
|
||||||
|
// Pages active: 142010.
|
||||||
|
// Pages inactive: 220007.
|
||||||
|
// Pages wired down: 159552.
|
||||||
|
// "Translation faults": 220825184.
|
||||||
|
// Pages copy-on-write: 2104153.
|
||||||
|
// Pages zero filled: 167034876.
|
||||||
|
// Pages reactivated: 65153.
|
||||||
|
// Pageins: 2097212.
|
||||||
|
// Pageouts: 41759.
|
||||||
|
// Object cache: 841598 hits of 7629869 lookups (11% hit rate)
|
||||||
|
avail_physical_mem_kb = -1 ;
|
||||||
|
avail_virtual_mem_kb = -1 ;
|
||||||
|
|
||||||
|
#elif LL_LINUX
|
||||||
|
// mStatsMap is derived from MEMINFO_FILE:
|
||||||
|
// $ cat /proc/meminfo
|
||||||
|
// MemTotal: 4108424 kB
|
||||||
|
// MemFree: 1244064 kB
|
||||||
|
// Buffers: 85164 kB
|
||||||
|
// Cached: 1990264 kB
|
||||||
|
// SwapCached: 0 kB
|
||||||
|
// Active: 1176648 kB
|
||||||
|
// Inactive: 1427532 kB
|
||||||
|
// Active(anon): 529152 kB
|
||||||
|
// Inactive(anon): 15924 kB
|
||||||
|
// Active(file): 647496 kB
|
||||||
|
// Inactive(file): 1411608 kB
|
||||||
|
// Unevictable: 16 kB
|
||||||
|
// Mlocked: 16 kB
|
||||||
|
// HighTotal: 3266316 kB
|
||||||
|
// HighFree: 721308 kB
|
||||||
|
// LowTotal: 842108 kB
|
||||||
|
// LowFree: 522756 kB
|
||||||
|
// SwapTotal: 6384632 kB
|
||||||
|
// SwapFree: 6384632 kB
|
||||||
|
// Dirty: 28 kB
|
||||||
|
// Writeback: 0 kB
|
||||||
|
// AnonPages: 528820 kB
|
||||||
|
// Mapped: 89472 kB
|
||||||
|
// Shmem: 16324 kB
|
||||||
|
// Slab: 159624 kB
|
||||||
|
// SReclaimable: 145168 kB
|
||||||
|
// SUnreclaim: 14456 kB
|
||||||
|
// KernelStack: 2560 kB
|
||||||
|
// PageTables: 5560 kB
|
||||||
|
// NFS_Unstable: 0 kB
|
||||||
|
// Bounce: 0 kB
|
||||||
|
// WritebackTmp: 0 kB
|
||||||
|
// CommitLimit: 8438844 kB
|
||||||
|
// Committed_AS: 1271596 kB
|
||||||
|
// VmallocTotal: 122880 kB
|
||||||
|
// VmallocUsed: 65252 kB
|
||||||
|
// VmallocChunk: 52356 kB
|
||||||
|
// HardwareCorrupted: 0 kB
|
||||||
|
// HugePages_Total: 0
|
||||||
|
// HugePages_Free: 0
|
||||||
|
// HugePages_Rsvd: 0
|
||||||
|
// HugePages_Surp: 0
|
||||||
|
// Hugepagesize: 2048 kB
|
||||||
|
// DirectMap4k: 434168 kB
|
||||||
|
// DirectMap2M: 477184 kB
|
||||||
|
// (could also run 'free', but easier to read a file than run a program)
|
||||||
|
avail_physical_mem_kb = -1 ;
|
||||||
|
avail_virtual_mem_kb = -1 ;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
//do not know how to collect available memory info for other systems.
|
//do not know how to collect available memory info for other systems.
|
||||||
@@ -708,56 +881,285 @@ void LLMemoryInfo::getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_v
|
|||||||
|
|
||||||
void LLMemoryInfo::stream(std::ostream& s) const
|
void LLMemoryInfo::stream(std::ostream& s) const
|
||||||
{
|
{
|
||||||
|
// We want these memory stats to be easy to grep from the log, along with
|
||||||
|
// the timestamp. So preface each line with the timestamp and a
|
||||||
|
// distinctive marker. Without that, we'd have to search the log for the
|
||||||
|
// introducer line, then read subsequent lines, etc...
|
||||||
|
std::string pfx(LLError::utcTime() + " <mem> ");
|
||||||
|
|
||||||
|
// Max key length
|
||||||
|
size_t key_width(0);
|
||||||
|
BOOST_FOREACH(const MapEntry& pair, inMap(mStatsMap))
|
||||||
|
{
|
||||||
|
size_t len(pair.first.length());
|
||||||
|
if (len > key_width)
|
||||||
|
{
|
||||||
|
key_width = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now stream stats
|
||||||
|
BOOST_FOREACH(const MapEntry& pair, inMap(mStatsMap))
|
||||||
|
{
|
||||||
|
s << pfx << std::setw(key_width+1) << (pair.first + ':') << ' ';
|
||||||
|
LLSD value(pair.second);
|
||||||
|
if (value.isInteger())
|
||||||
|
s << std::setw(12) << value.asInteger();
|
||||||
|
else if (value.isReal())
|
||||||
|
s << std::fixed << std::setprecision(1) << value.asReal();
|
||||||
|
else if (value.isDate())
|
||||||
|
value.asDate().toStream(s);
|
||||||
|
else
|
||||||
|
s << value; // just use default LLSD formatting
|
||||||
|
s << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LLSD LLMemoryInfo::getStatsMap() const
|
||||||
|
{
|
||||||
|
return mStatsMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLMemoryInfo& LLMemoryInfo::refresh()
|
||||||
|
{
|
||||||
|
mStatsMap = loadStatsMap();
|
||||||
|
|
||||||
|
LL_DEBUGS("LLMemoryInfo") << "Populated mStatsMap:\n";
|
||||||
|
LLSDSerialize::toPrettyXML(mStatsMap, LL_CONT);
|
||||||
|
LL_ENDL;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLSD LLMemoryInfo::loadStatsMap()
|
||||||
|
{
|
||||||
|
// This implementation is derived from stream() code (as of 2011-06-29).
|
||||||
|
Stats stats;
|
||||||
|
|
||||||
|
// associate timestamp for analysis over time
|
||||||
|
stats.add("timestamp", LLDate::now());
|
||||||
|
|
||||||
#if LL_WINDOWS
|
#if LL_WINDOWS
|
||||||
MEMORYSTATUSEX state;
|
MEMORYSTATUSEX state;
|
||||||
state.dwLength = sizeof(state);
|
state.dwLength = sizeof(state);
|
||||||
GlobalMemoryStatusEx(&state);
|
GlobalMemoryStatusEx(&state);
|
||||||
|
|
||||||
s << "Percent Memory use: " << (U32)state.dwMemoryLoad << '%' << std::endl;
|
DWORDLONG div = 1024;
|
||||||
s << "Total Physical KB: " << (U32)(state.ullTotalPhys/1024) << std::endl;
|
|
||||||
s << "Avail Physical KB: " << (U32)(state.ullAvailPhys/1024) << std::endl;
|
stats.add("Percent Memory use", state.dwMemoryLoad/div);
|
||||||
s << "Total page KB: " << (U32)(state.ullTotalPageFile/1024) << std::endl;
|
stats.add("Total Physical KB", state.ullTotalPhys/div);
|
||||||
s << "Avail page KB: " << (U32)(state.ullAvailPageFile/1024) << std::endl;
|
stats.add("Avail Physical KB", state.ullAvailPhys/div);
|
||||||
s << "Total Virtual KB: " << (U32)(state.ullTotalVirtual/1024) << std::endl;
|
stats.add("Total page KB", state.ullTotalPageFile/div);
|
||||||
s << "Avail Virtual KB: " << (U32)(state.ullAvailVirtual/1024) << std::endl;
|
stats.add("Avail page KB", state.ullAvailPageFile/div);
|
||||||
|
stats.add("Total Virtual KB", state.ullTotalVirtual/div);
|
||||||
|
stats.add("Avail Virtual KB", state.ullAvailVirtual/div);
|
||||||
|
|
||||||
|
PERFORMANCE_INFORMATION perf;
|
||||||
|
perf.cb = sizeof(perf);
|
||||||
|
GetPerformanceInfo(&perf, sizeof(perf));
|
||||||
|
|
||||||
|
SIZE_T pagekb(perf.PageSize/1024);
|
||||||
|
stats.add("CommitTotal KB", perf.CommitTotal * pagekb);
|
||||||
|
stats.add("CommitLimit KB", perf.CommitLimit * pagekb);
|
||||||
|
stats.add("CommitPeak KB", perf.CommitPeak * pagekb);
|
||||||
|
stats.add("PhysicalTotal KB", perf.PhysicalTotal * pagekb);
|
||||||
|
stats.add("PhysicalAvail KB", perf.PhysicalAvailable * pagekb);
|
||||||
|
stats.add("SystemCache KB", perf.SystemCache * pagekb);
|
||||||
|
stats.add("KernelTotal KB", perf.KernelTotal * pagekb);
|
||||||
|
stats.add("KernelPaged KB", perf.KernelPaged * pagekb);
|
||||||
|
stats.add("KernelNonpaged KB", perf.KernelNonpaged * pagekb);
|
||||||
|
stats.add("PageSize KB", pagekb);
|
||||||
|
stats.add("HandleCount", perf.HandleCount);
|
||||||
|
stats.add("ProcessCount", perf.ProcessCount);
|
||||||
|
stats.add("ThreadCount", perf.ThreadCount);
|
||||||
|
|
||||||
|
PROCESS_MEMORY_COUNTERS_EX pmem;
|
||||||
|
pmem.cb = sizeof(pmem);
|
||||||
|
// GetProcessMemoryInfo() is documented to accept either
|
||||||
|
// PROCESS_MEMORY_COUNTERS* or PROCESS_MEMORY_COUNTERS_EX*, presumably
|
||||||
|
// using the redundant size info to distinguish. But its prototype
|
||||||
|
// specifically accepts PROCESS_MEMORY_COUNTERS*, and since this is a
|
||||||
|
// classic-C API, PROCESS_MEMORY_COUNTERS_EX isn't a subclass. Cast the
|
||||||
|
// pointer.
|
||||||
|
GetProcessMemoryInfo(GetCurrentProcess(), PPROCESS_MEMORY_COUNTERS(&pmem), sizeof(pmem));
|
||||||
|
|
||||||
|
stats.add("Page Fault Count", pmem.PageFaultCount);
|
||||||
|
stats.add("PeakWorkingSetSize KB", pmem.PeakWorkingSetSize/div);
|
||||||
|
stats.add("WorkingSetSize KB", pmem.WorkingSetSize/div);
|
||||||
|
stats.add("QutaPeakPagedPoolUsage KB", pmem.QuotaPeakPagedPoolUsage/div);
|
||||||
|
stats.add("QuotaPagedPoolUsage KB", pmem.QuotaPagedPoolUsage/div);
|
||||||
|
stats.add("QuotaPeakNonPagedPoolUsage KB", pmem.QuotaPeakNonPagedPoolUsage/div);
|
||||||
|
stats.add("QuotaNonPagedPoolUsage KB", pmem.QuotaNonPagedPoolUsage/div);
|
||||||
|
stats.add("PagefileUsage KB", pmem.PagefileUsage/div);
|
||||||
|
stats.add("PeakPagefileUsage KB", pmem.PeakPagefileUsage/div);
|
||||||
|
stats.add("PrivateUsage KB", pmem.PrivateUsage/div);
|
||||||
|
|
||||||
#elif LL_DARWIN
|
#elif LL_DARWIN
|
||||||
uint64_t phys = 0;
|
|
||||||
|
|
||||||
size_t len = sizeof(phys);
|
const vm_size_t pagekb(vm_page_size / 1024);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Collect the vm_stat's
|
||||||
|
//
|
||||||
|
|
||||||
if(sysctlbyname("hw.memsize", &phys, &len, NULL, 0) == 0)
|
|
||||||
{
|
{
|
||||||
s << "Total Physical KB: " << phys/1024 << std::endl;
|
vm_statistics_data_t vmstat;
|
||||||
}
|
mach_msg_type_number_t vmstatCount = HOST_VM_INFO_COUNT;
|
||||||
else
|
|
||||||
{
|
|
||||||
s << "Unable to collect memory information";
|
|
||||||
}
|
|
||||||
#elif LL_SOLARIS
|
|
||||||
U64 phys = 0;
|
|
||||||
|
|
||||||
phys = (U64)(sysconf(_SC_PHYS_PAGES)) * (U64)(sysconf(_SC_PAGESIZE)/1024);
|
if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t) &vmstat, &vmstatCount) != KERN_SUCCESS)
|
||||||
|
|
||||||
s << "Total Physical KB: " << phys << std::endl;
|
|
||||||
#else
|
|
||||||
// *NOTE: This works on linux. What will it do on other systems?
|
|
||||||
LLFILE* meminfo = LLFile::fopen(MEMINFO_FILE,"rb");
|
|
||||||
if(meminfo)
|
|
||||||
{
|
{
|
||||||
char line[MAX_STRING]; /* Flawfinder: ignore */
|
LL_WARNS("LLMemoryInfo") << "Unable to collect memory information" << LL_ENDL;
|
||||||
memset(line, 0, MAX_STRING);
|
}
|
||||||
while(fgets(line, MAX_STRING, meminfo))
|
else
|
||||||
{
|
{
|
||||||
line[strlen(line)-1] = ' '; /*Flawfinder: ignore*/
|
stats.add("Pages free KB", pagekb * vmstat.free_count);
|
||||||
s << line;
|
stats.add("Pages active KB", pagekb * vmstat.active_count);
|
||||||
|
stats.add("Pages inactive KB", pagekb * vmstat.inactive_count);
|
||||||
|
stats.add("Pages wired KB", pagekb * vmstat.wire_count);
|
||||||
|
|
||||||
|
stats.add("Pages zero fill", vmstat.zero_fill_count);
|
||||||
|
stats.add("Page reactivations", vmstat.reactivations);
|
||||||
|
stats.add("Page-ins", vmstat.pageins);
|
||||||
|
stats.add("Page-outs", vmstat.pageouts);
|
||||||
|
|
||||||
|
stats.add("Faults", vmstat.faults);
|
||||||
|
stats.add("Faults copy-on-write", vmstat.cow_faults);
|
||||||
|
|
||||||
|
stats.add("Cache lookups", vmstat.lookups);
|
||||||
|
stats.add("Cache hits", vmstat.hits);
|
||||||
|
|
||||||
|
stats.add("Page purgeable count", vmstat.purgeable_count);
|
||||||
|
stats.add("Page purges", vmstat.purges);
|
||||||
|
|
||||||
|
stats.add("Page speculative reads", vmstat.speculative_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Collect the misc task info
|
||||||
|
//
|
||||||
|
|
||||||
|
{
|
||||||
|
task_events_info_data_t taskinfo;
|
||||||
|
unsigned taskinfoSize = sizeof(taskinfo);
|
||||||
|
|
||||||
|
if (task_info(mach_task_self(), TASK_EVENTS_INFO, (task_info_t) &taskinfo, &taskinfoSize) != KERN_SUCCESS)
|
||||||
|
{
|
||||||
|
LL_WARNS("LLMemoryInfo") << "Unable to collect task information" << LL_ENDL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stats.add("Task page-ins", taskinfo.pageins);
|
||||||
|
stats.add("Task copy-on-write faults", taskinfo.cow_faults);
|
||||||
|
stats.add("Task messages sent", taskinfo.messages_sent);
|
||||||
|
stats.add("Task messages received", taskinfo.messages_received);
|
||||||
|
stats.add("Task mach system call count", taskinfo.syscalls_mach);
|
||||||
|
stats.add("Task unix system call count", taskinfo.syscalls_unix);
|
||||||
|
stats.add("Task context switch count", taskinfo.csw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Collect the basic task info
|
||||||
|
//
|
||||||
|
|
||||||
|
{
|
||||||
|
task_basic_info_64_data_t taskinfo;
|
||||||
|
unsigned taskinfoSize = sizeof(taskinfo);
|
||||||
|
|
||||||
|
if (task_info(mach_task_self(), TASK_BASIC_INFO_64, (task_info_t) &taskinfo, &taskinfoSize) != KERN_SUCCESS)
|
||||||
|
{
|
||||||
|
LL_WARNS("LLMemoryInfo") << "Unable to collect task information" << LL_ENDL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stats.add("Basic suspend count", taskinfo.suspend_count);
|
||||||
|
stats.add("Basic virtual memory KB", taskinfo.virtual_size / 1024);
|
||||||
|
stats.add("Basic resident memory KB", taskinfo.resident_size / 1024);
|
||||||
|
stats.add("Basic new thread policy", taskinfo.policy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif LL_SOLARIS
|
||||||
|
U64 phys = 0;
|
||||||
|
|
||||||
|
phys = (U64)(sysconf(_SC_PHYS_PAGES)) * (U64)(sysconf(_SC_PAGESIZE)/1024);
|
||||||
|
|
||||||
|
stats.add("Total Physical KB", phys);
|
||||||
|
|
||||||
|
#elif LL_LINUX
|
||||||
|
std::ifstream meminfo(MEMINFO_FILE);
|
||||||
|
if (meminfo.is_open())
|
||||||
|
{
|
||||||
|
// MemTotal: 4108424 kB
|
||||||
|
// MemFree: 1244064 kB
|
||||||
|
// Buffers: 85164 kB
|
||||||
|
// Cached: 1990264 kB
|
||||||
|
// SwapCached: 0 kB
|
||||||
|
// Active: 1176648 kB
|
||||||
|
// Inactive: 1427532 kB
|
||||||
|
// ...
|
||||||
|
// VmallocTotal: 122880 kB
|
||||||
|
// VmallocUsed: 65252 kB
|
||||||
|
// VmallocChunk: 52356 kB
|
||||||
|
// HardwareCorrupted: 0 kB
|
||||||
|
// HugePages_Total: 0
|
||||||
|
// HugePages_Free: 0
|
||||||
|
// HugePages_Rsvd: 0
|
||||||
|
// HugePages_Surp: 0
|
||||||
|
// Hugepagesize: 2048 kB
|
||||||
|
// DirectMap4k: 434168 kB
|
||||||
|
// DirectMap2M: 477184 kB
|
||||||
|
|
||||||
|
// Intentionally don't pass the boost::no_except flag. This
|
||||||
|
// boost::regex object is constructed with a string literal, so it
|
||||||
|
// should be valid every time. If it becomes invalid, we WANT an
|
||||||
|
// exception, hopefully even before the dev checks in.
|
||||||
|
boost::regex stat_rx("(.+): +([0-9]+)( kB)?");
|
||||||
|
boost::smatch matched;
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(meminfo, line))
|
||||||
|
{
|
||||||
|
LL_DEBUGS("LLMemoryInfo") << line << LL_ENDL;
|
||||||
|
if (regex_match_no_exc(line, matched, stat_rx))
|
||||||
|
{
|
||||||
|
// e.g. "MemTotal: 4108424 kB"
|
||||||
|
LLSD::String key(matched[1].first, matched[1].second);
|
||||||
|
LLSD::String value_str(matched[2].first, matched[2].second);
|
||||||
|
LLSD::Integer value(0);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
value = boost::lexical_cast<LLSD::Integer>(value_str);
|
||||||
|
}
|
||||||
|
catch (const boost::bad_lexical_cast&)
|
||||||
|
{
|
||||||
|
LL_WARNS("LLMemoryInfo") << "couldn't parse '" << value_str
|
||||||
|
<< "' in " << MEMINFO_FILE << " line: "
|
||||||
|
<< line << LL_ENDL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Store this statistic.
|
||||||
|
stats.add(key, value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LL_WARNS("LLMemoryInfo") << "unrecognized " << MEMINFO_FILE << " line: "
|
||||||
|
<< line << LL_ENDL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fclose(meminfo);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s << "Unable to collect memory information";
|
LL_WARNS("LLMemoryInfo") << "Unable to collect memory information" << LL_ENDL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
LL_WARNS("LLMemoryInfo") << "Unknown system; unable to collect memory information" << LL_ENDL;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return stats.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& s, const LLOSInfo& info)
|
std::ostream& operator<<(std::ostream& s, const LLOSInfo& info)
|
||||||
@@ -778,6 +1180,143 @@ std::ostream& operator<<(std::ostream& s, const LLMemoryInfo& info)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FrameWatcher
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FrameWatcher():
|
||||||
|
// Hooking onto the "mainloop" event pump gets us one call per frame.
|
||||||
|
mConnection(LLEventPumps::instance()
|
||||||
|
.obtain("mainloop")
|
||||||
|
.listen("FrameWatcher", boost::bind(&FrameWatcher::tick, this, _1))),
|
||||||
|
// Initializing mSampleStart to an invalid timestamp alerts us to skip
|
||||||
|
// trying to compute framerate on the first call.
|
||||||
|
mSampleStart(-1),
|
||||||
|
// Initializing mSampleEnd to 0 ensures that we treat the first call
|
||||||
|
// as the completion of a sample window.
|
||||||
|
mSampleEnd(0),
|
||||||
|
mFrames(0),
|
||||||
|
// Both MEM_INFO_WINDOW and MEM_INFO_THROTTLE are in seconds. We need
|
||||||
|
// the number of integer MEM_INFO_THROTTLE sample slots that will fit
|
||||||
|
// in MEM_INFO_WINDOW. Round up.
|
||||||
|
mSamples(int((MEM_INFO_WINDOW / MEM_INFO_THROTTLE) + 0.7)),
|
||||||
|
// Initializing to F32_MAX means that the first real frame will become
|
||||||
|
// the slowest ever, which sounds like a good idea.
|
||||||
|
mSlowest(F32_MAX)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool tick(const LLSD&)
|
||||||
|
{
|
||||||
|
F32 timestamp(mTimer.getElapsedTimeF32());
|
||||||
|
|
||||||
|
// Count this frame in the interval just completed.
|
||||||
|
++mFrames;
|
||||||
|
|
||||||
|
// Have we finished a sample window yet?
|
||||||
|
if (timestamp < mSampleEnd)
|
||||||
|
{
|
||||||
|
// no, just keep waiting
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up for next sample window. Capture values for previous frame in
|
||||||
|
// local variables and reset data members.
|
||||||
|
U32 frames(mFrames);
|
||||||
|
F32 sampleStart(mSampleStart);
|
||||||
|
// No frames yet in next window
|
||||||
|
mFrames = 0;
|
||||||
|
// which starts right now
|
||||||
|
mSampleStart = timestamp;
|
||||||
|
// and ends MEM_INFO_THROTTLE seconds in the future
|
||||||
|
mSampleEnd = mSampleStart + MEM_INFO_THROTTLE;
|
||||||
|
|
||||||
|
// On the very first call, that's all we can do, no framerate
|
||||||
|
// computation is possible.
|
||||||
|
if (sampleStart < 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// How long did this actually take? As framerate slows, the duration
|
||||||
|
// of the frame we just finished could push us WELL beyond our desired
|
||||||
|
// sample window size.
|
||||||
|
F32 elapsed(timestamp - sampleStart);
|
||||||
|
F32 framerate(frames/elapsed);
|
||||||
|
|
||||||
|
// Remember previous slowest framerate because we're just about to
|
||||||
|
// update it.
|
||||||
|
F32 slowest(mSlowest);
|
||||||
|
// Remember previous number of samples.
|
||||||
|
boost::circular_buffer<F32>::size_type prevSize(mSamples.size());
|
||||||
|
|
||||||
|
// Capture new framerate in our samples buffer. Once the buffer is
|
||||||
|
// full (after MEM_INFO_WINDOW seconds), this will displace the oldest
|
||||||
|
// sample. ("So they all rolled over, and one fell out...")
|
||||||
|
mSamples.push_back(framerate);
|
||||||
|
|
||||||
|
// Calculate the new minimum framerate. I know of no way to update a
|
||||||
|
// rolling minimum without ever rescanning the buffer. But since there
|
||||||
|
// are only a few tens of items in this buffer, rescanning it is
|
||||||
|
// probably cheaper (and certainly easier to reason about) than
|
||||||
|
// attempting to optimize away some of the scans.
|
||||||
|
mSlowest = framerate; // pick an arbitrary entry to start
|
||||||
|
for (boost::circular_buffer<F32>::const_iterator si(mSamples.begin()), send(mSamples.end());
|
||||||
|
si != send; ++si)
|
||||||
|
{
|
||||||
|
if (*si < mSlowest)
|
||||||
|
{
|
||||||
|
mSlowest = *si;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We're especially interested in memory as framerate drops. Only log
|
||||||
|
// when framerate drops below the slowest framerate we remember.
|
||||||
|
// (Should always be true for the end of the very first sample
|
||||||
|
// window.)
|
||||||
|
if (framerate >= slowest)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Congratulations, we've hit a new low. :-P
|
||||||
|
|
||||||
|
LL_INFOS("FrameWatcher") << ' ';
|
||||||
|
if (! prevSize)
|
||||||
|
{
|
||||||
|
LL_CONT << "initial framerate ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LL_CONT << "slowest framerate for last " << int(prevSize * MEM_INFO_THROTTLE)
|
||||||
|
<< " seconds ";
|
||||||
|
}
|
||||||
|
LL_CONT << std::fixed << std::setprecision(1) << framerate << '\n'
|
||||||
|
<< LLMemoryInfo() << LL_ENDL;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Storing the connection in an LLTempBoundListener ensures it will be
|
||||||
|
// disconnected when we're destroyed.
|
||||||
|
LLTempBoundListener mConnection;
|
||||||
|
// Track elapsed time
|
||||||
|
LLTimer mTimer;
|
||||||
|
// Some of what you see here is in fact redundant with functionality you
|
||||||
|
// can get from LLTimer. Unfortunately the LLTimer API is missing the
|
||||||
|
// feature we need: has at least the stated interval elapsed, and if so,
|
||||||
|
// exactly how long has passed? So we have to do it by hand, sigh.
|
||||||
|
// Time at start, end of sample window
|
||||||
|
F32 mSampleStart, mSampleEnd;
|
||||||
|
// Frames this sample window
|
||||||
|
U32 mFrames;
|
||||||
|
// Sliding window of framerate samples
|
||||||
|
boost::circular_buffer<F32> mSamples;
|
||||||
|
// Slowest framerate in mSamples
|
||||||
|
F32 mSlowest;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Need an instance of FrameWatcher before it does any good
|
||||||
|
static FrameWatcher sFrameWatcher;
|
||||||
|
|
||||||
BOOL gunzip_file(const std::string& srcfile, const std::string& dstfile)
|
BOOL gunzip_file(const std::string& srcfile, const std::string& dstfile)
|
||||||
{
|
{
|
||||||
std::string tmpfile;
|
std::string tmpfile;
|
||||||
|
|||||||
@@ -117,6 +117,27 @@ public:
|
|||||||
|
|
||||||
//get the available memory infomation in KiloBytes.
|
//get the available memory infomation in KiloBytes.
|
||||||
static void getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_virtual_mem_kb);
|
static void getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_virtual_mem_kb);
|
||||||
|
|
||||||
|
// Retrieve a map of memory statistics. The keys of the map are platform-
|
||||||
|
// dependent. The values are in kilobytes to try to avoid integer overflow.
|
||||||
|
LLSD getStatsMap() const;
|
||||||
|
|
||||||
|
// Re-fetch memory data (as reported by stream() and getStatsMap()) from the
|
||||||
|
// system. Normally this is fetched at construction time. Return (*this)
|
||||||
|
// to permit usage of the form:
|
||||||
|
// @code
|
||||||
|
// LLMemoryInfo info;
|
||||||
|
// ...
|
||||||
|
// info.refresh().getStatsMap();
|
||||||
|
// @endcode
|
||||||
|
LLMemoryInfo& refresh();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// set mStatsMap
|
||||||
|
static LLSD loadStatsMap();
|
||||||
|
|
||||||
|
// Memory stats for getStatsMap().
|
||||||
|
LLSD mStatsMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -41,10 +41,15 @@
|
|||||||
#include "llmd5.h"
|
#include "llmd5.h"
|
||||||
#include "llstring.h"
|
#include "llstring.h"
|
||||||
#include "lltimer.h"
|
#include "lltimer.h"
|
||||||
|
#include "llthread.h"
|
||||||
|
|
||||||
const LLUUID LLUUID::null;
|
const LLUUID LLUUID::null;
|
||||||
const LLTransactionID LLTransactionID::tnull;
|
const LLTransactionID LLTransactionID::tnull;
|
||||||
|
|
||||||
|
// static
|
||||||
|
LLMutex * LLUUID::mMutex = NULL;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
NOT DONE YET!!!
|
NOT DONE YET!!!
|
||||||
@@ -731,6 +736,7 @@ void LLUUID::getCurrentTime(uuid_time_t *timestamp)
|
|||||||
getSystemTime(&time_last);
|
getSystemTime(&time_last);
|
||||||
uuids_this_tick = uuids_per_tick;
|
uuids_this_tick = uuids_per_tick;
|
||||||
init = TRUE;
|
init = TRUE;
|
||||||
|
mMutex = new LLMutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
uuid_time_t time_now = {0,0};
|
uuid_time_t time_now = {0,0};
|
||||||
@@ -782,6 +788,7 @@ void LLUUID::generate()
|
|||||||
#endif
|
#endif
|
||||||
if (!has_init)
|
if (!has_init)
|
||||||
{
|
{
|
||||||
|
has_init = 1;
|
||||||
if (getNodeID(node_id) <= 0)
|
if (getNodeID(node_id) <= 0)
|
||||||
{
|
{
|
||||||
get_random_bytes(node_id, 6);
|
get_random_bytes(node_id, 6);
|
||||||
@@ -803,18 +810,24 @@ void LLUUID::generate()
|
|||||||
#else
|
#else
|
||||||
clock_seq = (U16)ll_rand(65536);
|
clock_seq = (U16)ll_rand(65536);
|
||||||
#endif
|
#endif
|
||||||
has_init = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get current time
|
// get current time
|
||||||
getCurrentTime(×tamp);
|
getCurrentTime(×tamp);
|
||||||
|
U16 our_clock_seq = clock_seq;
|
||||||
|
|
||||||
// if clock went backward change clockseq
|
// if clock hasn't changed or went backward, change clockseq
|
||||||
if (cmpTime(×tamp, &time_last) == -1) {
|
if (cmpTime(×tamp, &time_last) != 1)
|
||||||
|
{
|
||||||
|
LLMutexLock lock(mMutex);
|
||||||
clock_seq = (clock_seq + 1) & 0x3FFF;
|
clock_seq = (clock_seq + 1) & 0x3FFF;
|
||||||
if (clock_seq == 0) clock_seq++;
|
if (clock_seq == 0)
|
||||||
|
clock_seq++;
|
||||||
|
our_clock_seq = clock_seq; // Ensure we're using a different clock_seq value from previous time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
time_last = timestamp;
|
||||||
|
|
||||||
memcpy(mData+10, node_id, 6); /* Flawfinder: ignore */
|
memcpy(mData+10, node_id, 6); /* Flawfinder: ignore */
|
||||||
U32 tmp;
|
U32 tmp;
|
||||||
tmp = timestamp.low;
|
tmp = timestamp.low;
|
||||||
@@ -836,7 +849,8 @@ void LLUUID::generate()
|
|||||||
tmp >>= 8;
|
tmp >>= 8;
|
||||||
mData[6] = (unsigned char) tmp;
|
mData[6] = (unsigned char) tmp;
|
||||||
|
|
||||||
tmp = clock_seq;
|
tmp = our_clock_seq;
|
||||||
|
|
||||||
mData[9] = (unsigned char) tmp;
|
mData[9] = (unsigned char) tmp;
|
||||||
tmp >>= 8;
|
tmp >>= 8;
|
||||||
mData[8] = (unsigned char) tmp;
|
mData[8] = (unsigned char) tmp;
|
||||||
@@ -846,8 +860,6 @@ void LLUUID::generate()
|
|||||||
md5_uuid.update(mData,16);
|
md5_uuid.update(mData,16);
|
||||||
md5_uuid.finalize();
|
md5_uuid.finalize();
|
||||||
md5_uuid.raw_digest(mData);
|
md5_uuid.raw_digest(mData);
|
||||||
|
|
||||||
time_last = timestamp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLUUID::generate(const std::string& hash_string)
|
void LLUUID::generate(const std::string& hash_string)
|
||||||
@@ -861,8 +873,14 @@ U32 LLUUID::getRandomSeed()
|
|||||||
static unsigned char seed[16]; /* Flawfinder: ignore */
|
static unsigned char seed[16]; /* Flawfinder: ignore */
|
||||||
|
|
||||||
getNodeID(&seed[0]);
|
getNodeID(&seed[0]);
|
||||||
seed[6]='\0';
|
|
||||||
seed[7]='\0';
|
// Incorporate the pid into the seed to prevent
|
||||||
|
// processes that start on the same host at the same
|
||||||
|
// time from generating the same seed.
|
||||||
|
pid_t pid = LLApp::getPid();
|
||||||
|
|
||||||
|
seed[6]=(unsigned char)(pid >> 8);
|
||||||
|
seed[7]=(unsigned char)(pid);
|
||||||
getSystemTime((uuid_time_t *)(&seed[8]));
|
getSystemTime((uuid_time_t *)(&seed[8]));
|
||||||
|
|
||||||
LLMD5 md5_seed;
|
LLMD5 md5_seed;
|
||||||
|
|||||||
@@ -31,6 +31,8 @@
|
|||||||
#include "stdtypes.h"
|
#include "stdtypes.h"
|
||||||
#include "llpreprocessor.h"
|
#include "llpreprocessor.h"
|
||||||
|
|
||||||
|
class LLMutex;
|
||||||
|
|
||||||
const S32 UUID_BYTES = 16;
|
const S32 UUID_BYTES = 16;
|
||||||
const S32 UUID_WORDS = 4;
|
const S32 UUID_WORDS = 4;
|
||||||
const S32 UUID_STR_LENGTH = 37; // actually wrong, should be 36 and use size below
|
const S32 UUID_STR_LENGTH = 37; // actually wrong, should be 36 and use size below
|
||||||
@@ -118,6 +120,7 @@ public:
|
|||||||
static BOOL validate(const std::string& in_string); // Validate that the UUID string is legal.
|
static BOOL validate(const std::string& in_string); // Validate that the UUID string is legal.
|
||||||
|
|
||||||
static const LLUUID null;
|
static const LLUUID null;
|
||||||
|
static LLMutex * mMutex;
|
||||||
|
|
||||||
static U32 getRandomSeed();
|
static U32 getRandomSeed();
|
||||||
static S32 getNodeID(unsigned char * node_id);
|
static S32 getNodeID(unsigned char * node_id);
|
||||||
|
|||||||
@@ -680,7 +680,6 @@ void LLCircuitData::checkPacketInID(TPACKETID id, BOOL receive_resent)
|
|||||||
setPacketInID((id + 1) % LL_MAX_OUT_PACKET_ID);
|
setPacketInID((id + 1) % LL_MAX_OUT_PACKET_ID);
|
||||||
|
|
||||||
mLastPacketGap = 0;
|
mLastPacketGap = 0;
|
||||||
mOutOfOrderRate.count(0);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -776,7 +775,6 @@ void LLCircuitData::checkPacketInID(TPACKETID id, BOOL receive_resent)
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mOutOfOrderRate.count(gap);
|
|
||||||
mLastPacketGap = gap;
|
mLastPacketGap = gap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,6 @@
|
|||||||
#include "llpacketack.h"
|
#include "llpacketack.h"
|
||||||
#include "lluuid.h"
|
#include "lluuid.h"
|
||||||
#include "llthrottle.h"
|
#include "llthrottle.h"
|
||||||
#include "llstat.h"
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Constants
|
// Constants
|
||||||
@@ -126,8 +125,6 @@ public:
|
|||||||
S32 getUnackedPacketCount() const { return mUnackedPacketCount; }
|
S32 getUnackedPacketCount() const { return mUnackedPacketCount; }
|
||||||
S32 getUnackedPacketBytes() const { return mUnackedPacketBytes; }
|
S32 getUnackedPacketBytes() const { return mUnackedPacketBytes; }
|
||||||
F64 getNextPingSendTime() const { return mNextPingSendTime; }
|
F64 getNextPingSendTime() const { return mNextPingSendTime; }
|
||||||
F32 getOutOfOrderRate(LLStatAccum::TimeScale scale = LLStatAccum::SCALE_MINUTE)
|
|
||||||
{ return mOutOfOrderRate.meanValue(scale); }
|
|
||||||
U32 getLastPacketGap() const { return mLastPacketGap; }
|
U32 getLastPacketGap() const { return mLastPacketGap; }
|
||||||
LLHost getHost() const { return mHost; }
|
LLHost getHost() const { return mHost; }
|
||||||
F64 getLastPacketInTime() const { return mLastPacketInTime; }
|
F64 getLastPacketInTime() const { return mLastPacketInTime; }
|
||||||
@@ -275,7 +272,6 @@ protected:
|
|||||||
LLTimer mExistenceTimer; // initialized when circuit created, used to track bandwidth numbers
|
LLTimer mExistenceTimer; // initialized when circuit created, used to track bandwidth numbers
|
||||||
|
|
||||||
S32 mCurrentResendCount; // Number of resent packets since last spam
|
S32 mCurrentResendCount; // Number of resent packets since last spam
|
||||||
LLStatRate mOutOfOrderRate; // Rate of out of order packets coming in.
|
|
||||||
U32 mLastPacketGap; // Gap in sequence number of last packet.
|
U32 mLastPacketGap; // Gap in sequence number of last packet.
|
||||||
|
|
||||||
const F32 mHeartbeatInterval;
|
const F32 mHeartbeatInterval;
|
||||||
|
|||||||
@@ -141,6 +141,11 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_PIPE("HTTP Pipe");
|
static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_PIPE("HTTP Pipe");
|
||||||
|
static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_GET("HTTP Get");
|
||||||
|
static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_PUT("HTTP Put");
|
||||||
|
static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_POST("HTTP Post");
|
||||||
|
static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_DELETE("HTTP Delete");
|
||||||
|
|
||||||
LLIOPipe::EStatus LLHTTPPipe::process_impl(
|
LLIOPipe::EStatus LLHTTPPipe::process_impl(
|
||||||
const LLChannelDescriptors& channels,
|
const LLChannelDescriptors& channels,
|
||||||
buffer_ptr_t& buffer,
|
buffer_ptr_t& buffer,
|
||||||
@@ -177,12 +182,12 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
|
|||||||
std::string verb = context[CONTEXT_REQUEST][CONTEXT_VERB];
|
std::string verb = context[CONTEXT_REQUEST][CONTEXT_VERB];
|
||||||
if(verb == HTTP_VERB_GET)
|
if(verb == HTTP_VERB_GET)
|
||||||
{
|
{
|
||||||
LLPerfBlock getblock("http_get");
|
LLFastTimer _(FTM_PROCESS_HTTP_GET);
|
||||||
mNode.get(LLHTTPNode::ResponsePtr(mResponse), context);
|
mNode.get(LLHTTPNode::ResponsePtr(mResponse), context);
|
||||||
}
|
}
|
||||||
else if(verb == HTTP_VERB_PUT)
|
else if(verb == HTTP_VERB_PUT)
|
||||||
{
|
{
|
||||||
LLPerfBlock putblock("http_put");
|
LLFastTimer _(FTM_PROCESS_HTTP_PUT);
|
||||||
LLSD input;
|
LLSD input;
|
||||||
if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD)
|
if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD)
|
||||||
{
|
{
|
||||||
@@ -198,7 +203,7 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
|
|||||||
}
|
}
|
||||||
else if(verb == HTTP_VERB_POST)
|
else if(verb == HTTP_VERB_POST)
|
||||||
{
|
{
|
||||||
LLPerfBlock postblock("http_post");
|
LLFastTimer _(FTM_PROCESS_HTTP_POST);
|
||||||
LLSD input;
|
LLSD input;
|
||||||
if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD)
|
if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD)
|
||||||
{
|
{
|
||||||
@@ -214,7 +219,7 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
|
|||||||
}
|
}
|
||||||
else if(verb == HTTP_VERB_DELETE)
|
else if(verb == HTTP_VERB_DELETE)
|
||||||
{
|
{
|
||||||
LLPerfBlock delblock("http_delete");
|
LLFastTimer _(FTM_PROCESS_HTTP_DELETE);
|
||||||
mNode.del(LLHTTPNode::ResponsePtr(mResponse), context);
|
mNode.del(LLHTTPNode::ResponsePtr(mResponse), context);
|
||||||
}
|
}
|
||||||
else if(verb == HTTP_VERB_OPTIONS)
|
else if(verb == HTTP_VERB_OPTIONS)
|
||||||
|
|||||||
@@ -364,7 +364,6 @@ public:
|
|||||||
{
|
{
|
||||||
if (mHandlerFunc)
|
if (mHandlerFunc)
|
||||||
{
|
{
|
||||||
LLPerfBlock msg_cb_time("msg_cb", mName);
|
|
||||||
mHandlerFunc(msgsystem, mUserData);
|
mHandlerFunc(msgsystem, mUserData);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -454,6 +454,7 @@ void LLPumpIO::pump()
|
|||||||
}
|
}
|
||||||
|
|
||||||
static LLFastTimer::DeclareTimer FTM_PUMP_IO("Pump IO");
|
static LLFastTimer::DeclareTimer FTM_PUMP_IO("Pump IO");
|
||||||
|
static LLFastTimer::DeclareTimer FTM_PUMP_POLL("Pump Poll");
|
||||||
|
|
||||||
LLPumpIO::current_chain_t LLPumpIO::removeRunningChain(LLPumpIO::current_chain_t& run_chain)
|
LLPumpIO::current_chain_t LLPumpIO::removeRunningChain(LLPumpIO::current_chain_t& run_chain)
|
||||||
{
|
{
|
||||||
@@ -549,7 +550,7 @@ void LLPumpIO::pump(const S32& poll_timeout)
|
|||||||
S32 count = 0;
|
S32 count = 0;
|
||||||
S32 client_id = 0;
|
S32 client_id = 0;
|
||||||
{
|
{
|
||||||
LLPerfBlock polltime("pump_poll");
|
LLFastTimer _(FTM_PUMP_POLL);
|
||||||
apr_pollset_poll(mPollset, poll_timeout, &count, &poll_fd);
|
apr_pollset_poll(mPollset, poll_timeout, &count, &poll_fd);
|
||||||
}
|
}
|
||||||
PUMP_DEBUG;
|
PUMP_DEBUG;
|
||||||
|
|||||||
@@ -99,8 +99,10 @@ typedef enum e_control_type
|
|||||||
|
|
||||||
class LLControlVariable : public LLRefCount
|
class LLControlVariable : public LLRefCount
|
||||||
{
|
{
|
||||||
friend class LLControlGroup;
|
LOG_CLASS(LLControlVariable);
|
||||||
|
|
||||||
|
friend class LLControlGroup;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef boost::signals2::signal<bool(LLControlVariable* control, const LLSD&), boost_boolean_combiner> validate_signal_t;
|
typedef boost::signals2::signal<bool(LLControlVariable* control, const LLSD&), boost_boolean_combiner> validate_signal_t;
|
||||||
typedef boost::signals2::signal<void(LLControlVariable* control, const LLSD&)> commit_signal_t;
|
typedef boost::signals2::signal<void(LLControlVariable* control, const LLSD&)> commit_signal_t;
|
||||||
@@ -208,6 +210,7 @@ T convert_from_llsd(const LLSD& sd, eControlType type, const std::string& contro
|
|||||||
//const U32 STRING_CACHE_SIZE = 10000;
|
//const U32 STRING_CACHE_SIZE = 10000;
|
||||||
class LLControlGroup : public LLInstanceTracker<LLControlGroup, std::string>
|
class LLControlGroup : public LLInstanceTracker<LLControlGroup, std::string>
|
||||||
{
|
{
|
||||||
|
LOG_CLASS(LLControlGroup);
|
||||||
protected:
|
protected:
|
||||||
typedef std::map<std::string, LLControlVariablePtr > ctrl_name_table_t;
|
typedef std::map<std::string, LLControlVariablePtr > ctrl_name_table_t;
|
||||||
ctrl_name_table_t mNameTable;
|
ctrl_name_table_t mNameTable;
|
||||||
@@ -283,6 +286,7 @@ public:
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
llwarns << "Control " << name << " not found." << llendl;
|
llwarns << "Control " << name << " not found." << llendl;
|
||||||
|
return T();
|
||||||
}
|
}
|
||||||
return convert_from_llsd<T>(value, type, name);
|
return convert_from_llsd<T>(value, type, name);
|
||||||
}
|
}
|
||||||
@@ -313,7 +317,7 @@ public:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
llerrs << "Invalid control " << name << llendl;
|
llwarns << "Invalid control " << name << llendl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -268,7 +268,7 @@
|
|||||||
<key>Value</key>
|
<key>Value</key>
|
||||||
<integer>1</integer>
|
<integer>1</integer>
|
||||||
</map>
|
</map>
|
||||||
<key>AscentUseTag</key>
|
<key>AscentBroadcastTag</key>
|
||||||
<map>
|
<map>
|
||||||
<key>Comment</key>
|
<key>Comment</key>
|
||||||
<string>Broadcast client tag</string>
|
<string>Broadcast client tag</string>
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/**
|
||||||
|
* @file previewF.glsl
|
||||||
|
*
|
||||||
|
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
|
||||||
|
* Second Life Viewer Source Code
|
||||||
|
* Copyright (C) 2011, 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$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef DEFINE_GL_FRAGCOLOR
|
||||||
|
out vec4 frag_color;
|
||||||
|
#else
|
||||||
|
#define frag_color gl_FragColor
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uniform sampler2D diffuseMap;
|
||||||
|
|
||||||
|
VARYING vec4 vertex_color;
|
||||||
|
VARYING vec2 vary_texcoord0;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
|
||||||
|
frag_color = color;
|
||||||
|
}
|
||||||
@@ -32,12 +32,51 @@ ATTRIBUTE vec3 position;
|
|||||||
ATTRIBUTE vec3 normal;
|
ATTRIBUTE vec3 normal;
|
||||||
ATTRIBUTE vec2 texcoord0;
|
ATTRIBUTE vec2 texcoord0;
|
||||||
|
|
||||||
|
uniform vec4 color;
|
||||||
|
|
||||||
VARYING vec4 vertex_color;
|
VARYING vec4 vertex_color;
|
||||||
VARYING vec2 vary_texcoord0;
|
VARYING vec2 vary_texcoord0;
|
||||||
|
|
||||||
|
uniform vec4 light_position[8];
|
||||||
|
uniform vec3 light_direction[8];
|
||||||
|
uniform vec3 light_attenuation[8];
|
||||||
|
uniform vec3 light_diffuse[8];
|
||||||
|
|
||||||
|
//===================================================================================================
|
||||||
|
//declare these here explicitly to separate them from atmospheric lighting elsewhere to work around
|
||||||
|
//drivers that are picky about functions being declared but not defined even if they aren't called
|
||||||
|
float calcDirectionalLight(vec3 n, vec3 l)
|
||||||
|
{
|
||||||
|
float a = max(dot(n,l),0.0);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight)
|
||||||
|
{
|
||||||
|
//get light vector
|
||||||
|
vec3 lv = lp.xyz-v;
|
||||||
|
|
||||||
|
//get distance
|
||||||
|
float d = length(lv);
|
||||||
|
|
||||||
|
//normalize light vector
|
||||||
|
lv *= 1.0/d;
|
||||||
|
|
||||||
|
//distance attenuation
|
||||||
|
float da = clamp(1.0/(la * d), 0.0, 1.0);
|
||||||
|
|
||||||
|
// spotlight coefficient.
|
||||||
|
float spot = max(dot(-ln, lv), is_pointlight);
|
||||||
|
da *= spot*spot; // GL_SPOT_EXPONENT=2
|
||||||
|
|
||||||
|
//angular attenuation
|
||||||
|
da *= calcDirectionalLight(n, lv);
|
||||||
|
|
||||||
|
return da;
|
||||||
|
}
|
||||||
|
//====================================================================================================
|
||||||
|
|
||||||
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
|
|
||||||
void calcAtmospherics(vec3 inPositionEye);
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
@@ -45,13 +84,15 @@ void main()
|
|||||||
vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0));
|
vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0));
|
||||||
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
|
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
|
||||||
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
|
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
|
||||||
|
|
||||||
vec3 norm = normalize(normal_matrix * normal);
|
vec3 norm = normalize(normal_matrix * normal);
|
||||||
|
|
||||||
calcAtmospherics(pos.xyz);
|
vec4 col = vec4(0,0,0,1);
|
||||||
|
|
||||||
vec4 color = calcLighting(pos.xyz, norm, vec4(1,1,1,1), vec4(0.));
|
// Collect normal lights (need to be divided by two, as we later multiply by 2)
|
||||||
vertex_color = color;
|
col.rgb += light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz);
|
||||||
|
col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z);
|
||||||
|
col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z);
|
||||||
|
|
||||||
|
vertex_color = col*color;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ void LLPrefsAscentVan::refreshValues()
|
|||||||
mAnnounceStreamMetadata = gSavedSettings.getBOOL("AnnounceStreamMetadata");
|
mAnnounceStreamMetadata = gSavedSettings.getBOOL("AnnounceStreamMetadata");
|
||||||
|
|
||||||
//Tags\Colors ----------------------------------------------------------------------------
|
//Tags\Colors ----------------------------------------------------------------------------
|
||||||
mAscentUseTag = gSavedSettings.getBOOL("AscentUseTag");
|
mAscentBroadcastTag = gSavedSettings.getBOOL("AscentBroadcastTag");
|
||||||
mReportClientUUID = gSavedSettings.getString("AscentReportClientUUID");
|
mReportClientUUID = gSavedSettings.getString("AscentReportClientUUID");
|
||||||
mSelectedClient = gSavedSettings.getU32("AscentReportClientIndex");
|
mSelectedClient = gSavedSettings.getU32("AscentReportClientIndex");
|
||||||
mShowSelfClientTag = gSavedSettings.getBOOL("AscentShowSelfTag");
|
mShowSelfClientTag = gSavedSettings.getBOOL("AscentShowSelfTag");
|
||||||
@@ -276,7 +276,7 @@ void LLPrefsAscentVan::cancel()
|
|||||||
gSavedSettings.setBOOL("AnnounceStreamMetadata", mAnnounceStreamMetadata);
|
gSavedSettings.setBOOL("AnnounceStreamMetadata", mAnnounceStreamMetadata);
|
||||||
|
|
||||||
//Tags\Colors ----------------------------------------------------------------------------
|
//Tags\Colors ----------------------------------------------------------------------------
|
||||||
gSavedSettings.setBOOL("AscentUseTag", mAscentUseTag);
|
gSavedSettings.setBOOL("AscentBroadcastTag", mAscentBroadcastTag);
|
||||||
gSavedSettings.setString("AscentReportClientUUID", mReportClientUUID);
|
gSavedSettings.setString("AscentReportClientUUID", mReportClientUUID);
|
||||||
gSavedSettings.setU32("AscentReportClientIndex", mSelectedClient);
|
gSavedSettings.setU32("AscentReportClientIndex", mSelectedClient);
|
||||||
gSavedSettings.setBOOL("AscentShowSelfTag", mShowSelfClientTag);
|
gSavedSettings.setBOOL("AscentShowSelfTag", mShowSelfClientTag);
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ protected:
|
|||||||
bool mAnnounceSnapshots;
|
bool mAnnounceSnapshots;
|
||||||
bool mAnnounceStreamMetadata;
|
bool mAnnounceStreamMetadata;
|
||||||
//Tags\Colors
|
//Tags\Colors
|
||||||
BOOL mAscentUseTag;
|
BOOL mAscentBroadcastTag;
|
||||||
std::string mReportClientUUID;
|
std::string mReportClientUUID;
|
||||||
U32 mSelectedClient;
|
U32 mSelectedClient;
|
||||||
BOOL mShowSelfClientTag;
|
BOOL mShowSelfClientTag;
|
||||||
|
|||||||
@@ -690,9 +690,6 @@ bool LLAppViewer::init()
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// *FIX: The following code isn't grouped into functions yet.
|
// *FIX: The following code isn't grouped into functions yet.
|
||||||
|
|
||||||
// Statistics / debug timer initialization
|
|
||||||
init_statistics();
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Various introspection concerning the libs we're using - particularly
|
// Various introspection concerning the libs we're using - particularly
|
||||||
// the libs involved in getting to a full login screen.
|
// the libs involved in getting to a full login screen.
|
||||||
@@ -3969,7 +3966,7 @@ void LLAppViewer::idle()
|
|||||||
idle_afk_check();
|
idle_afk_check();
|
||||||
|
|
||||||
// Update statistics for this frame
|
// Update statistics for this frame
|
||||||
update_statistics(gFrameCount);
|
update_statistics();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
|
|||||||
@@ -500,18 +500,9 @@ void LLFloaterAvatarList::assessColumns()
|
|||||||
|
|
||||||
if(!client_hidden)
|
if(!client_hidden)
|
||||||
{
|
{
|
||||||
name_col->setWidth(width_name);
|
name_col->setWidth(llmax(width_name.get(),10));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!hide_client)
|
|
||||||
{
|
|
||||||
mAvatarList->getColumn(LIST_CLIENT)->setWidth(0);
|
|
||||||
mAvatarList->getColumn(LIST_AVATAR_NAME)->setWidth(0);
|
|
||||||
mAvatarList->getColumn(LIST_AVATAR_NAME)->mDynamicWidth = FALSE;
|
|
||||||
mAvatarList->getColumn(LIST_AVATAR_NAME)->mRelWidth = 0;
|
|
||||||
mAvatarList->getColumn(LIST_CLIENT)->mDynamicWidth = TRUE;
|
|
||||||
mAvatarList->getColumn(LIST_CLIENT)->mRelWidth = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
mAvatarList->updateLayout();
|
mAvatarList->updateLayout();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,26 +58,36 @@
|
|||||||
|
|
||||||
#include "hippogridmanager.h"
|
#include "hippogridmanager.h"
|
||||||
|
|
||||||
LLFloaterBuyContents* LLFloaterBuyContents::sInstance = NULL;
|
|
||||||
|
|
||||||
LLFloaterBuyContents::LLFloaterBuyContents()
|
LLFloaterBuyContents::LLFloaterBuyContents()
|
||||||
: LLFloater(std::string("floater_buy_contents"), std::string("FloaterBuyContentsRect"), LLStringUtil::null)
|
: LLFloater(std::string("floater_buy_contents"), std::string("FloaterBuyContentsRect"), LLStringUtil::null)
|
||||||
{
|
{
|
||||||
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_buy_contents.xml");
|
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_buy_contents.xml");
|
||||||
|
}
|
||||||
|
|
||||||
childSetAction("cancel_btn", onClickCancel, this);
|
BOOL LLFloaterBuyContents::postBuild()
|
||||||
childSetAction("buy_btn", onClickBuy, this);
|
{
|
||||||
|
|
||||||
childDisable("item_list");
|
getChild<LLUICtrl>("cancel_btn")->setCommitCallback( boost::bind(&LLFloaterBuyContents::onClickCancel, this));
|
||||||
childDisable("buy_btn");
|
getChild<LLUICtrl>("buy_btn")->setCommitCallback( boost::bind(&LLFloaterBuyContents::onClickBuy, this));
|
||||||
childDisable("wear_check");
|
|
||||||
|
getChildView("item_list")->setEnabled(FALSE);
|
||||||
|
getChildView("buy_btn")->setEnabled(FALSE);
|
||||||
|
getChildView("wear_check")->setEnabled(FALSE);
|
||||||
|
|
||||||
setDefaultBtn("cancel_btn"); // to avoid accidental buy (SL-43130)
|
setDefaultBtn("cancel_btn"); // to avoid accidental buy (SL-43130)
|
||||||
|
|
||||||
|
// Always center the dialog. User can change the size,
|
||||||
|
// but purchases are important and should be center screen.
|
||||||
|
// This also avoids problems where the user resizes the application window
|
||||||
|
// mid-session and the saved rect is off-center.
|
||||||
|
center();
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
LLFloaterBuyContents::~LLFloaterBuyContents()
|
LLFloaterBuyContents::~LLFloaterBuyContents()
|
||||||
{
|
{
|
||||||
sInstance = NULL;
|
removeVOInventoryListener();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -92,26 +102,20 @@ void LLFloaterBuyContents::show(const LLSaleInfo& sale_info)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new instance only if needed
|
LLFloaterBuyContents* floater = getInstance();
|
||||||
if (sInstance)
|
LLScrollListCtrl* list = floater->getChild<LLScrollListCtrl>("item_list");
|
||||||
{
|
if (list)
|
||||||
LLScrollListCtrl* list = sInstance->getChild<LLScrollListCtrl>("item_list");
|
list->deleteAllItems();
|
||||||
if (list) list->deleteAllItems();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sInstance = new LLFloaterBuyContents();
|
|
||||||
}
|
|
||||||
|
|
||||||
sInstance->open(); /*Flawfinder: ignore*/
|
floater->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
|
||||||
sInstance->setFocus(TRUE);
|
|
||||||
sInstance->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
|
|
||||||
|
|
||||||
|
floater->open(); /*Flawfinder: ignore*/
|
||||||
|
floater->setFocus(TRUE);
|
||||||
// Always center the dialog. User can change the size,
|
// Always center the dialog. User can change the size,
|
||||||
// but purchases are important and should be center screen.
|
// but purchases are important and should be center screen.
|
||||||
// This also avoids problems where the user resizes the application window
|
// This also avoids problems where the user resizes the application window
|
||||||
// mid-session and the saved rect is off-center.
|
// mid-session and the saved rect is off-center.
|
||||||
sInstance->center();
|
floater->center();
|
||||||
|
|
||||||
LLUUID owner_id;
|
LLUUID owner_id;
|
||||||
std::string owner_name;
|
std::string owner_name;
|
||||||
@@ -122,7 +126,7 @@ void LLFloaterBuyContents::show(const LLSaleInfo& sale_info)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sInstance->mSaleInfo = sale_info;
|
floater->mSaleInfo = sale_info;
|
||||||
|
|
||||||
// Update the display
|
// Update the display
|
||||||
LLSelectNode* node = selection->getFirstRootNode();
|
LLSelectNode* node = selection->getFirstRootNode();
|
||||||
@@ -132,17 +136,17 @@ void LLFloaterBuyContents::show(const LLSaleInfo& sale_info)
|
|||||||
gCacheName->getGroupName(owner_id, owner_name);
|
gCacheName->getGroupName(owner_id, owner_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
sInstance->childSetTextArg("contains_text", "[NAME]", node->mName);
|
floater->getChild<LLUICtrl>("contains_text")->setTextArg("[NAME]", node->mName);
|
||||||
sInstance->childSetTextArg("buy_text", "[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol());
|
floater->getChild<LLUICtrl>("buy_text")->setTextArg("[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol());
|
||||||
sInstance->childSetTextArg("buy_text", "[AMOUNT]", llformat("%d", sale_info.getSalePrice()));
|
floater->getChild<LLUICtrl>("buy_text")->setTextArg("[AMOUNT]", llformat("%d", sale_info.getSalePrice()));
|
||||||
sInstance->childSetTextArg("buy_text", "[NAME]", owner_name);
|
floater->getChild<LLUICtrl>("buy_text")->setTextArg("[NAME]", owner_name);
|
||||||
|
|
||||||
// Must do this after the floater is created, because
|
// Must do this after the floater is created, because
|
||||||
// sometimes the inventory is already there and
|
// sometimes the inventory is already there and
|
||||||
// the callback is called immediately.
|
// the callback is called immediately.
|
||||||
LLViewerObject* obj = selection->getFirstRootObject();
|
LLViewerObject* obj = selection->getFirstRootObject();
|
||||||
sInstance->registerVOInventoryListener(obj,NULL);
|
floater->registerVOInventoryListener(obj,NULL);
|
||||||
sInstance->requestVOInventory();
|
floater->requestVOInventory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -157,23 +161,26 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!inv)
|
LLScrollListCtrl* item_list = getChild<LLScrollListCtrl>("item_list");
|
||||||
{
|
|
||||||
llwarns << "No inventory in LLFloaterBuyContents::inventoryChanged"
|
|
||||||
<< llendl;
|
|
||||||
removeVOInventoryListener();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LLCtrlListInterface *item_list = childGetListInterface("item_list");
|
|
||||||
if (!item_list)
|
if (!item_list)
|
||||||
{
|
{
|
||||||
removeVOInventoryListener();
|
removeVOInventoryListener();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item_list->deleteAllItems();
|
||||||
|
|
||||||
|
if (!inv)
|
||||||
|
{
|
||||||
|
llwarns << "No inventory in LLFloaterBuyContents::inventoryChanged"
|
||||||
|
<< llendl;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// default to turning off the buy button.
|
// default to turning off the buy button.
|
||||||
childDisable("buy_btn");
|
LLView* buy_btn = getChildView("buy_btn");
|
||||||
|
buy_btn->setEnabled(FALSE);
|
||||||
|
|
||||||
LLUUID owner_id;
|
LLUUID owner_id;
|
||||||
BOOL is_group_owned;
|
BOOL is_group_owned;
|
||||||
@@ -214,13 +221,15 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj,
|
|||||||
|
|
||||||
// There will be at least one item shown in the display, so go
|
// There will be at least one item shown in the display, so go
|
||||||
// ahead and enable the buy button.
|
// ahead and enable the buy button.
|
||||||
childEnable("buy_btn");
|
buy_btn->setEnabled(TRUE);
|
||||||
|
|
||||||
// Create the line in the list
|
// Create the line in the list
|
||||||
LLSD row;
|
LLSD row;
|
||||||
|
|
||||||
BOOL item_is_multi = FALSE;
|
BOOL item_is_multi = FALSE;
|
||||||
if ( inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_LANDMARK_VISITED )
|
if ((inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_LANDMARK_VISITED
|
||||||
|
|| inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS)
|
||||||
|
&& !(inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK))
|
||||||
{
|
{
|
||||||
item_is_multi = TRUE;
|
item_is_multi = TRUE;
|
||||||
}
|
}
|
||||||
@@ -260,28 +269,25 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj,
|
|||||||
|
|
||||||
if (wearable_count > 0)
|
if (wearable_count > 0)
|
||||||
{
|
{
|
||||||
childEnable("wear_check");
|
getChildView("wear_check")->setEnabled(TRUE);
|
||||||
childSetValue("wear_check", LLSD(false) );
|
getChild<LLUICtrl>("wear_check")->setValue(LLSD(false) );
|
||||||
}
|
}
|
||||||
|
|
||||||
removeVOInventoryListener();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
void LLFloaterBuyContents::onClickBuy()
|
||||||
void LLFloaterBuyContents::onClickBuy(void*)
|
|
||||||
{
|
{
|
||||||
// Make sure this wasn't selected through other mechanisms
|
// Make sure this wasn't selected through other mechanisms
|
||||||
// (ie, being the default button and pressing enter.
|
// (ie, being the default button and pressing enter.
|
||||||
if(!sInstance->childIsEnabled("buy_btn"))
|
if(!getChildView("buy_btn")->getEnabled())
|
||||||
{
|
{
|
||||||
// We shouldn't be enabled. Just close.
|
// We shouldn't be enabled. Just close.
|
||||||
sInstance->close();
|
close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We may want to wear this item
|
// We may want to wear this item
|
||||||
if (sInstance->childGetValue("wear_check"))
|
if (getChild<LLUICtrl>("wear_check")->getValue())
|
||||||
{
|
{
|
||||||
LLInventoryState::sWearNewClothing = TRUE;
|
LLInventoryState::sWearNewClothing = TRUE;
|
||||||
}
|
}
|
||||||
@@ -293,14 +299,14 @@ void LLFloaterBuyContents::onClickBuy(void*)
|
|||||||
// *NOTE: doesn't work for multiple object buy, which UI does not
|
// *NOTE: doesn't work for multiple object buy, which UI does not
|
||||||
// currently support sale info is used for verification only, if
|
// currently support sale info is used for verification only, if
|
||||||
// it doesn't match region info then sale is canceled.
|
// it doesn't match region info then sale is canceled.
|
||||||
LLSelectMgr::getInstance()->sendBuy(gAgent.getID(), category_id, sInstance->mSaleInfo);
|
LLSelectMgr::getInstance()->sendBuy(gAgent.getID(), category_id, mSaleInfo);
|
||||||
|
|
||||||
sInstance->close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void LLFloaterBuyContents::onClickCancel(void*)
|
void LLFloaterBuyContents::onClickCancel()
|
||||||
{
|
{
|
||||||
sInstance->close();
|
close();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,27 +47,26 @@ class LLViewerObject;
|
|||||||
class LLObjectSelection;
|
class LLObjectSelection;
|
||||||
|
|
||||||
class LLFloaterBuyContents
|
class LLFloaterBuyContents
|
||||||
: public LLFloater, public LLVOInventoryListener
|
: public LLFloater, public LLVOInventoryListener, public LLSingleton<LLFloaterBuyContents>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void show(const LLSaleInfo& sale_info);
|
static void show(const LLSaleInfo& sale_info);
|
||||||
|
|
||||||
protected:
|
|
||||||
LLFloaterBuyContents();
|
LLFloaterBuyContents();
|
||||||
~LLFloaterBuyContents();
|
~LLFloaterBuyContents();
|
||||||
|
/*virtual*/ BOOL postBuild();
|
||||||
|
|
||||||
|
protected:
|
||||||
void requestObjectInventories();
|
void requestObjectInventories();
|
||||||
/*virtual*/ void inventoryChanged(LLViewerObject* obj,
|
/*virtual*/ void inventoryChanged(LLViewerObject* obj,
|
||||||
LLInventoryObject::object_list_t* inv,
|
LLInventoryObject::object_list_t* inv,
|
||||||
S32 serial_num,
|
S32 serial_num,
|
||||||
void* data);
|
void* data);
|
||||||
|
|
||||||
static void onClickBuy(void*);
|
void onClickBuy();
|
||||||
static void onClickCancel(void*);
|
void onClickCancel();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static LLFloaterBuyContents* sInstance;
|
|
||||||
|
|
||||||
LLSafeHandle<LLObjectSelection> mObjectSelection;
|
LLSafeHandle<LLObjectSelection> mObjectSelection;
|
||||||
LLSaleInfo mSaleInfo;
|
LLSaleInfo mSaleInfo;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -973,11 +973,13 @@ BOOL LLImagePreviewSculpted::render()
|
|||||||
{
|
{
|
||||||
gObjectPreviewProgram.bind();
|
gObjectPreviewProgram.bind();
|
||||||
}
|
}
|
||||||
|
gPipeline.enableLightsPreview();
|
||||||
|
|
||||||
gGL.pushMatrix();
|
gGL.pushMatrix();
|
||||||
const F32 SCALE = 1.25f;
|
const F32 SCALE = 1.25f;
|
||||||
gGL.scalef(SCALE, SCALE, SCALE);
|
gGL.scalef(SCALE, SCALE, SCALE);
|
||||||
const F32 BRIGHTNESS = 0.9f;
|
const F32 BRIGHTNESS = 0.9f;
|
||||||
gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
|
gGL.diffuseColor3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
|
||||||
|
|
||||||
mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0);
|
mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0);
|
||||||
mVertexBuffer->draw(LLRender::TRIANGLES, num_indices, 0);
|
mVertexBuffer->draw(LLRender::TRIANGLES, num_indices, 0);
|
||||||
|
|||||||
@@ -106,7 +106,8 @@ BOOL LLFloaterJoystick::postBuild()
|
|||||||
for (U32 i = 0; i < 6; i++)
|
for (U32 i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
axis.setArg("[NUM]", llformat("%d", i));
|
axis.setArg("[NUM]", llformat("%d", i));
|
||||||
mAxisStats[i] = new LLStat(4);
|
std::string stat_name(llformat("Joystick axis %d", i));
|
||||||
|
mAxisStats[i] = new LLStat(stat_name,4);
|
||||||
mAxisStatsBar[i] = mAxisStatsView->addStat(axis, mAxisStats[i]);
|
mAxisStatsBar[i] = mAxisStatsView->addStat(axis, mAxisStats[i]);
|
||||||
mAxisStatsBar[i]->mMinBar = -range;
|
mAxisStatsBar[i]->mMinBar = -range;
|
||||||
mAxisStatsBar[i]->mMaxBar = range;
|
mAxisStatsBar[i]->mMaxBar = range;
|
||||||
|
|||||||
@@ -1641,7 +1641,6 @@ bool LLModelLoader::doLoadModel()
|
|||||||
|
|
||||||
//If no skeleton, do a breadth-first search to get at specific joints
|
//If no skeleton, do a breadth-first search to get at specific joints
|
||||||
bool rootNode = false;
|
bool rootNode = false;
|
||||||
bool skeletonWithNoRootNode = false;
|
|
||||||
|
|
||||||
//Need to test for a skeleton that does not have a root node
|
//Need to test for a skeleton that does not have a root node
|
||||||
//This occurs when your instance controller does not have an associated scene
|
//This occurs when your instance controller does not have an associated scene
|
||||||
@@ -1652,10 +1651,6 @@ bool LLModelLoader::doLoadModel()
|
|||||||
{
|
{
|
||||||
rootNode = true;
|
rootNode = true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
skeletonWithNoRootNode = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!pSkeleton || !rootNode)
|
if (!pSkeleton || !rootNode)
|
||||||
@@ -5034,6 +5029,11 @@ BOOL LLModelPreview::render()
|
|||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (use_shaders)
|
||||||
|
{
|
||||||
|
gObjectPreviewProgram.bind();
|
||||||
|
}
|
||||||
|
|
||||||
gGL.loadIdentity();
|
gGL.loadIdentity();
|
||||||
gPipeline.enableLightsPreview();
|
gPipeline.enableLightsPreview();
|
||||||
|
|
||||||
@@ -5043,8 +5043,9 @@ BOOL LLModelPreview::render()
|
|||||||
LLQuaternion av_rot = camera_rot;
|
LLQuaternion av_rot = camera_rot;
|
||||||
LLViewerCamera::getInstance()->setOriginAndLookAt(
|
LLViewerCamera::getInstance()->setOriginAndLookAt(
|
||||||
target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + offset) * av_rot), // camera
|
target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + offset) * av_rot), // camera
|
||||||
LLVector3::z_axis, // up
|
LLVector3::z_axis, // up
|
||||||
target_pos); // point of interest
|
target_pos); // point of interest
|
||||||
|
|
||||||
|
|
||||||
z_near = llclamp(z_far * 0.001f, 0.001f, 0.1f);
|
z_near = llclamp(z_far * 0.001f, 0.001f, 0.1f);
|
||||||
|
|
||||||
@@ -5058,11 +5059,6 @@ BOOL LLModelPreview::render()
|
|||||||
|
|
||||||
const U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
|
const U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
|
||||||
|
|
||||||
if (use_shaders)
|
|
||||||
{
|
|
||||||
gObjectPreviewProgram.bind();
|
|
||||||
}
|
|
||||||
|
|
||||||
LLGLEnable normalize(GL_NORMALIZE);
|
LLGLEnable normalize(GL_NORMALIZE);
|
||||||
|
|
||||||
if (!mBaseModel.empty() && mVertexBuffer[5].empty())
|
if (!mBaseModel.empty() && mVertexBuffer[5].empty())
|
||||||
@@ -5248,10 +5244,10 @@ BOOL LLModelPreview::render()
|
|||||||
|
|
||||||
if (i + 1 >= hull_colors.size())
|
if (i + 1 >= hull_colors.size())
|
||||||
{
|
{
|
||||||
hull_colors.push_back(LLColor4U(rand()%128 + 127, rand()%128 + 127, rand()%128 + 127, 128));
|
hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 128));
|
||||||
}
|
}
|
||||||
|
|
||||||
glColor4ubv(hull_colors[i].mV);
|
gGL.diffuseColor4ubv(hull_colors[i].mV);
|
||||||
LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals);
|
LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals);
|
||||||
|
|
||||||
if (explode > 0.f)
|
if (explode > 0.f)
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
#include "pipeline.h"
|
#include "pipeline.h"
|
||||||
#include "llviewerobjectlist.h"
|
#include "llviewerobjectlist.h"
|
||||||
#include "llviewertexturelist.h"
|
#include "llviewertexturelist.h"
|
||||||
|
#include "lltexturefetch.h"
|
||||||
#include "sgmemstat.h"
|
#include "sgmemstat.h"
|
||||||
|
|
||||||
const S32 LL_SCROLL_BORDER = 1;
|
const S32 LL_SCROLL_BORDER = 1;
|
||||||
@@ -151,10 +152,36 @@ void LLFloaterStats::buildStats()
|
|||||||
stat_barp->mLabelSpacing = 500.f;
|
stat_barp->mLabelSpacing = 500.f;
|
||||||
stat_barp->mPerSec = TRUE;
|
stat_barp->mPerSec = TRUE;
|
||||||
|
|
||||||
|
stat_barp = render_statviewp->addStat("Object Cache Hit Rate", &(LLViewerStats::getInstance()->mNumNewObjectsStat), std::string(), false, true);
|
||||||
|
stat_barp->setLabel("Object Cache Hit Rate");
|
||||||
|
stat_barp->setUnitLabel("%");
|
||||||
|
stat_barp->mMinBar = 0.f;
|
||||||
|
stat_barp->mMaxBar = 100.f;
|
||||||
|
stat_barp->mTickSpacing = 20.f;
|
||||||
|
stat_barp->mLabelSpacing = 20.f;
|
||||||
|
stat_barp->mPerSec = FALSE;
|
||||||
|
|
||||||
// Texture statistics
|
// Texture statistics
|
||||||
LLStatView *texture_statviewp = render_statviewp->addStatView("texture stat view", "Texture", "OpenDebugStatTexture", rect);
|
LLStatView *texture_statviewp = render_statviewp->addStatView("texture stat view", "Texture", "OpenDebugStatTexture", rect);
|
||||||
|
|
||||||
|
stat_barp = texture_statviewp->addStat("Cache Hit Rate", &(LLTextureFetch::sCacheHitRate), std::string(), false, true);
|
||||||
|
stat_barp->setLabel("Cache Hit Rate");
|
||||||
|
stat_barp->setUnitLabel("%");
|
||||||
|
stat_barp->mMinBar = 0.f;
|
||||||
|
stat_barp->mMaxBar = 100.f;
|
||||||
|
stat_barp->mTickSpacing = 20.f;
|
||||||
|
stat_barp->mLabelSpacing = 20.f;
|
||||||
|
stat_barp->mPerSec = FALSE;
|
||||||
|
|
||||||
|
stat_barp = texture_statviewp->addStat("Cache Read Latency", &(LLTextureFetch::sCacheReadLatency), std::string(), false, true);
|
||||||
|
stat_barp->setUnitLabel("msec");
|
||||||
|
stat_barp->mMinBar = 0.f;
|
||||||
|
stat_barp->mMaxBar = 1000.f;
|
||||||
|
stat_barp->mTickSpacing = 100.f;
|
||||||
|
stat_barp->mLabelSpacing = 200.f;
|
||||||
|
stat_barp->mPerSec = FALSE;
|
||||||
|
stat_barp->mDisplayMean = FALSE;
|
||||||
|
|
||||||
stat_barp = texture_statviewp->addStat("Count", &(LLViewerStats::getInstance()->mNumImagesStat), "DebugStatModeTextureCount");
|
stat_barp = texture_statviewp->addStat("Count", &(LLViewerStats::getInstance()->mNumImagesStat), "DebugStatModeTextureCount");
|
||||||
stat_barp->setUnitLabel("");
|
stat_barp->setUnitLabel("");
|
||||||
stat_barp->mMinBar = 0.f;
|
stat_barp->mMinBar = 0.f;
|
||||||
@@ -365,6 +392,15 @@ void LLFloaterStats::buildStats()
|
|||||||
stat_barp->mPerSec = FALSE;
|
stat_barp->mPerSec = FALSE;
|
||||||
stat_barp->mDisplayMean = FALSE;
|
stat_barp->mDisplayMean = FALSE;
|
||||||
|
|
||||||
|
stat_barp = sim_statviewp->addStat("Scripts Run", &(LLViewerStats::getInstance()->mSimPctScriptsRun), std::string(), false, true);
|
||||||
|
stat_barp->setUnitLabel("%");
|
||||||
|
stat_barp->mPrecision = 3;
|
||||||
|
stat_barp->mMinBar = 0.f;
|
||||||
|
stat_barp->mMaxBar = 100.f;
|
||||||
|
stat_barp->mTickSpacing = 10.f;
|
||||||
|
stat_barp->mLabelSpacing = 20.f;
|
||||||
|
stat_barp->mPerSec = FALSE;
|
||||||
|
|
||||||
stat_barp = sim_statviewp->addStat("Script Events", &(LLViewerStats::getInstance()->mSimScriptEPS), "DebugStatModeSimScriptEvents");
|
stat_barp = sim_statviewp->addStat("Script Events", &(LLViewerStats::getInstance()->mSimScriptEPS), "DebugStatModeSimScriptEvents");
|
||||||
stat_barp->setUnitLabel(" eps");
|
stat_barp->setUnitLabel(" eps");
|
||||||
stat_barp->mPrecision = 0;
|
stat_barp->mPrecision = 0;
|
||||||
@@ -375,6 +411,35 @@ void LLFloaterStats::buildStats()
|
|||||||
stat_barp->mPerSec = FALSE;
|
stat_barp->mPerSec = FALSE;
|
||||||
stat_barp->mDisplayMean = FALSE;
|
stat_barp->mDisplayMean = FALSE;
|
||||||
|
|
||||||
|
LLStatView *pathfinding_viewp = sim_statviewp->addStatView("pathfinding view", "Pathfinding Details", std::string(), rect);
|
||||||
|
stat_barp = pathfinding_viewp->addStat("AI Step Time", &(LLViewerStats::getInstance()->mSimSimAIStepMsec));
|
||||||
|
stat_barp->setUnitLabel("ms");
|
||||||
|
stat_barp->mPrecision = 3;
|
||||||
|
stat_barp->mMinBar = 0.f;
|
||||||
|
stat_barp->mMaxBar = 40.f;
|
||||||
|
stat_barp->mTickSpacing = 10.f;
|
||||||
|
stat_barp->mLabelSpacing = 20.f;
|
||||||
|
stat_barp->mPerSec = FALSE;
|
||||||
|
stat_barp->mDisplayMean = FALSE;
|
||||||
|
|
||||||
|
stat_barp = render_statviewp->addStat("Skipped Silhouette Steps", &(LLViewerStats::getInstance()->mSimSimSkippedSilhouetteSteps));
|
||||||
|
stat_barp->setUnitLabel("/sec");
|
||||||
|
stat_barp->mMinBar = 0.f;
|
||||||
|
stat_barp->mMaxBar = 45.f;
|
||||||
|
stat_barp->mTickSpacing = 4.f;
|
||||||
|
stat_barp->mLabelSpacing = 8.f;
|
||||||
|
stat_barp->mPrecision = 0;
|
||||||
|
|
||||||
|
stat_barp = pathfinding_viewp->addStat("Characters Updated", &(LLViewerStats::getInstance()->mSimSimPctSteppedCharacters));
|
||||||
|
stat_barp->setUnitLabel("%");
|
||||||
|
stat_barp->mPrecision = 1;
|
||||||
|
stat_barp->mMinBar = 0.f;
|
||||||
|
stat_barp->mMaxBar = 100.f;
|
||||||
|
stat_barp->mTickSpacing = 10.f;
|
||||||
|
stat_barp->mLabelSpacing = 20.f;
|
||||||
|
stat_barp->mPerSec = FALSE;
|
||||||
|
stat_barp->mDisplayMean = TRUE;
|
||||||
|
|
||||||
stat_barp = sim_statviewp->addStat("Packets In", &(LLViewerStats::getInstance()->mSimInPPS), "DebugStatModeSimInPPS");
|
stat_barp = sim_statviewp->addStat("Packets In", &(LLViewerStats::getInstance()->mSimInPPS), "DebugStatModeSimInPPS");
|
||||||
stat_barp->setUnitLabel(" pps");
|
stat_barp->setUnitLabel(" pps");
|
||||||
stat_barp->mPrecision = 0;
|
stat_barp->mPrecision = 0;
|
||||||
|
|||||||
@@ -103,27 +103,6 @@ LLFloaterURLEntry::LLFloaterURLEntry(LLHandle<LLPanel> parent)
|
|||||||
mPanelLandMediaHandle(parent)
|
mPanelLandMediaHandle(parent)
|
||||||
{
|
{
|
||||||
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_url_entry.xml");
|
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_url_entry.xml");
|
||||||
|
|
||||||
mMediaURLEdit = getChild<LLComboBox>("media_entry");
|
|
||||||
|
|
||||||
// Cancel button
|
|
||||||
childSetAction("cancel_btn", onBtnCancel, this);
|
|
||||||
|
|
||||||
// Cancel button
|
|
||||||
childSetAction("clear_btn", onBtnClear, this);
|
|
||||||
|
|
||||||
// clear media list button
|
|
||||||
LLSD parcel_history = LLURLHistory::getURLHistory("parcel");
|
|
||||||
bool enable_clear_button = parcel_history.size() > 0 ? true : false;
|
|
||||||
childSetEnabled( "clear_btn", enable_clear_button );
|
|
||||||
|
|
||||||
// OK button
|
|
||||||
childSetAction("ok_btn", onBtnOK, this);
|
|
||||||
|
|
||||||
setDefaultBtn("ok_btn");
|
|
||||||
buildURLHistory();
|
|
||||||
|
|
||||||
sInstance = this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -134,6 +113,28 @@ LLFloaterURLEntry::~LLFloaterURLEntry()
|
|||||||
sInstance = NULL;
|
sInstance = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL LLFloaterURLEntry::postBuild()
|
||||||
|
{
|
||||||
|
mMediaURLEdit = getChild<LLComboBox>("media_entry");
|
||||||
|
|
||||||
|
// Cancel button
|
||||||
|
childSetAction("cancel_btn", onBtnCancel, this);
|
||||||
|
|
||||||
|
// Cancel button
|
||||||
|
childSetAction("clear_btn", onBtnClear, this);
|
||||||
|
// clear media list button
|
||||||
|
LLSD parcel_history = LLURLHistory::getURLHistory("parcel");
|
||||||
|
bool enable_clear_button = parcel_history.size() > 0 ? true : false;
|
||||||
|
getChildView("clear_btn")->setEnabled(enable_clear_button );
|
||||||
|
|
||||||
|
// OK button
|
||||||
|
childSetAction("ok_btn", onBtnOK, this);
|
||||||
|
|
||||||
|
setDefaultBtn("ok_btn");
|
||||||
|
buildURLHistory();
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
void LLFloaterURLEntry::buildURLHistory()
|
void LLFloaterURLEntry::buildURLHistory()
|
||||||
{
|
{
|
||||||
LLCtrlListInterface* url_list = childGetListInterface("media_entry");
|
LLCtrlListInterface* url_list = childGetListInterface("media_entry");
|
||||||
@@ -157,7 +158,7 @@ void LLFloaterURLEntry::buildURLHistory()
|
|||||||
|
|
||||||
void LLFloaterURLEntry::headerFetchComplete(U32 status, const std::string& mime_type)
|
void LLFloaterURLEntry::headerFetchComplete(U32 status, const std::string& mime_type)
|
||||||
{
|
{
|
||||||
LLPanelLandMedia* panel_media = (LLPanelLandMedia*)mPanelLandMediaHandle.get();
|
LLPanelLandMedia* panel_media = dynamic_cast<LLPanelLandMedia*>(mPanelLandMediaHandle.get());
|
||||||
if (panel_media)
|
if (panel_media)
|
||||||
{
|
{
|
||||||
// status is ignored for now -- error = "none/none"
|
// status is ignored for now -- error = "none/none"
|
||||||
@@ -166,21 +167,18 @@ void LLFloaterURLEntry::headerFetchComplete(U32 status, const std::string& mime_
|
|||||||
}
|
}
|
||||||
// Decrement the cursor
|
// Decrement the cursor
|
||||||
getWindow()->decBusyCount();
|
getWindow()->decBusyCount();
|
||||||
childSetVisible("loading_label", false);
|
getChildView("loading_label")->setVisible( false);
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
LLHandle<LLFloater> LLFloaterURLEntry::show(LLHandle<LLPanel> parent)
|
LLHandle<LLFloater> LLFloaterURLEntry::show(LLHandle<LLPanel> parent)
|
||||||
{
|
{
|
||||||
if (sInstance)
|
if (!sInstance)
|
||||||
{
|
|
||||||
sInstance->open();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
sInstance = new LLFloaterURLEntry(parent);
|
sInstance = new LLFloaterURLEntry(parent);
|
||||||
}
|
}
|
||||||
|
sInstance->open();
|
||||||
sInstance->updateFromLandMediaPanel();
|
sInstance->updateFromLandMediaPanel();
|
||||||
return sInstance->getHandle();
|
return sInstance->getHandle();
|
||||||
}
|
}
|
||||||
@@ -239,7 +237,8 @@ void LLFloaterURLEntry::onBtnOK( void* userdata )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Discover the MIME type only for "http" scheme.
|
// Discover the MIME type only for "http" scheme.
|
||||||
if(scheme == "http" || scheme == "https")
|
if(!media_url.empty() &&
|
||||||
|
(scheme == "http" || scheme == "https"))
|
||||||
{
|
{
|
||||||
LLHTTPClient::getHeaderOnly( media_url,
|
LLHTTPClient::getHeaderOnly( media_url,
|
||||||
new LLMediaTypeResponder(self->getHandle()));
|
new LLMediaTypeResponder(self->getHandle()));
|
||||||
@@ -250,13 +249,13 @@ void LLFloaterURLEntry::onBtnOK( void* userdata )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Grey the buttons until we get the header response
|
// Grey the buttons until we get the header response
|
||||||
self->childSetEnabled("ok_btn", false);
|
self->getChildView("ok_btn")->setEnabled(false);
|
||||||
self->childSetEnabled("cancel_btn", false);
|
self->getChildView("cancel_btn")->setEnabled(false);
|
||||||
self->childSetEnabled("media_entry", false);
|
self->getChildView("media_entry")->setEnabled(false);
|
||||||
|
|
||||||
// show progress bar here?
|
// show progress bar here?
|
||||||
getWindow()->incBusyCount();
|
getWindow()->incBusyCount();
|
||||||
self->childSetVisible("loading_label", true);
|
self->getChildView("loading_label")->setVisible( true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
@@ -298,7 +297,7 @@ bool LLFloaterURLEntry::callback_clear_url_list(const LLSD& notification, const
|
|||||||
LLURLHistory::clear("parcel");
|
LLURLHistory::clear("parcel");
|
||||||
|
|
||||||
// cleared the list so disable Clear button
|
// cleared the list so disable Clear button
|
||||||
childSetEnabled( "clear_btn", false );
|
getChildView("clear_btn")->setEnabled(false );
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public:
|
|||||||
// Can only be shown by LLPanelLandMedia, and pushes data back into
|
// Can only be shown by LLPanelLandMedia, and pushes data back into
|
||||||
// that panel via the handle.
|
// that panel via the handle.
|
||||||
static LLHandle<LLFloater> show(LLHandle<LLPanel> panel_land_media_handle);
|
static LLHandle<LLFloater> show(LLHandle<LLPanel> panel_land_media_handle);
|
||||||
|
/*virtual*/ BOOL postBuild();
|
||||||
void updateFromLandMediaPanel();
|
void updateFromLandMediaPanel();
|
||||||
|
|
||||||
void headerFetchComplete(U32 status, const std::string& mime_type);
|
void headerFetchComplete(U32 status, const std::string& mime_type);
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ void LLMemoryView::refreshProfile()
|
|||||||
|
|
||||||
mLines.clear();
|
mLines.clear();
|
||||||
|
|
||||||
|
#if MEM_TRACK_MEM
|
||||||
if(mAlloc->isProfiling())
|
if(mAlloc->isProfiling())
|
||||||
{
|
{
|
||||||
const LLAllocatorHeapProfile &prof = mAlloc->getProfile();
|
const LLAllocatorHeapProfile &prof = mAlloc->getProfile();
|
||||||
@@ -118,6 +119,7 @@ void LLMemoryView::refreshProfile()
|
|||||||
mLines.push_back(utf8string_to_wstring(ss.str()));
|
mLines.push_back(utf8string_to_wstring(ss.str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLMemoryView::draw()
|
void LLMemoryView::draw()
|
||||||
|
|||||||
@@ -53,6 +53,7 @@
|
|||||||
#include "llviewertexture.h"
|
#include "llviewertexture.h"
|
||||||
#include "llviewerregion.h"
|
#include "llviewerregion.h"
|
||||||
#include "llviewerstats.h"
|
#include "llviewerstats.h"
|
||||||
|
#include "llviewerstatsrecorder.h"
|
||||||
#include "llworld.h"
|
#include "llworld.h"
|
||||||
#include "llstartup.h"
|
#include "llstartup.h"
|
||||||
#include "llbuffer.h"
|
#include "llbuffer.h"
|
||||||
@@ -61,6 +62,9 @@ class AIHTTPTimeoutPolicy;
|
|||||||
extern AIHTTPTimeoutPolicy HTTPGetResponder_timeout;
|
extern AIHTTPTimeoutPolicy HTTPGetResponder_timeout;
|
||||||
extern AIHTTPTimeoutPolicy lcl_responder_timeout;
|
extern AIHTTPTimeoutPolicy lcl_responder_timeout;
|
||||||
|
|
||||||
|
LLStat LLTextureFetch::sCacheHitRate("texture_cache_hits", 128);
|
||||||
|
LLStat LLTextureFetch::sCacheReadLatency("texture_cache_read_latency", 128);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
class LLTextureFetchWorker : public LLWorkerClass
|
class LLTextureFetchWorker : public LLWorkerClass
|
||||||
{
|
{
|
||||||
@@ -250,6 +254,8 @@ private:
|
|||||||
S32 mDecodedDiscard;
|
S32 mDecodedDiscard;
|
||||||
LLFrameTimer mRequestedTimer;
|
LLFrameTimer mRequestedTimer;
|
||||||
LLFrameTimer mFetchTimer;
|
LLFrameTimer mFetchTimer;
|
||||||
|
LLTimer mCacheReadTimer;
|
||||||
|
F32 mCacheReadTime;
|
||||||
LLTextureCache::handle_t mCacheReadHandle;
|
LLTextureCache::handle_t mCacheReadHandle;
|
||||||
LLTextureCache::handle_t mCacheWriteHandle;
|
LLTextureCache::handle_t mCacheWriteHandle;
|
||||||
std::vector<U8> mHttpBuffer;
|
std::vector<U8> mHttpBuffer;
|
||||||
@@ -289,9 +295,6 @@ private:
|
|||||||
S32 mLastPacket;
|
S32 mLastPacket;
|
||||||
U16 mTotalPackets;
|
U16 mTotalPackets;
|
||||||
U8 mImageCodec;
|
U8 mImageCodec;
|
||||||
#if HTTP_METRICS
|
|
||||||
LLViewerAssetStats::duration_t mMetricsStartTime;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -384,20 +387,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
mFetcher->removeFromHTTPQueue(mID, data_size);
|
mFetcher->removeFromHTTPQueue(mID, data_size);
|
||||||
|
|
||||||
#if HTTP_METRICS
|
|
||||||
if (worker->mMetricsStartTime)
|
|
||||||
{
|
|
||||||
LLViewerAssetStatsFF::record_response_thread1(LLViewerAssetType::AT_TEXTURE,
|
|
||||||
true,
|
|
||||||
LLImageBase::TYPE_AVATAR_BAKE == worker->mType,
|
|
||||||
LLViewerAssetStatsFF::get_timestamp() - worker->mMetricsStartTime);
|
|
||||||
worker->mMetricsStartTime = 0;
|
|
||||||
}
|
|
||||||
LLViewerAssetStatsFF::record_dequeue_thread1(LLViewerAssetType::AT_TEXTURE,
|
|
||||||
true,
|
|
||||||
LLImageBase::TYPE_AVATAR_BAKE == worker->mType);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -514,230 +503,6 @@ static bool sgConnectionThrottle() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HTTP_METRICS
|
|
||||||
// Cross-thread messaging for asset metrics.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Base class for cross-thread requests made of the fetcher
|
|
||||||
*
|
|
||||||
* I believe the intent of the LLQueuedThread class was to
|
|
||||||
* have these operations derived from LLQueuedThread::QueuedRequest
|
|
||||||
* but the texture fetcher has elected to manage the queue
|
|
||||||
* in its own manner. So these are free-standing objects which are
|
|
||||||
* managed in simple FIFO order on the mCommands queue of the
|
|
||||||
* LLTextureFetch object.
|
|
||||||
*
|
|
||||||
* What each represents is a simple command sent from an
|
|
||||||
* outside thread into the TextureFetch thread to be processed
|
|
||||||
* in order and in a timely fashion (though not an absolute
|
|
||||||
* higher priority than other operations of the thread).
|
|
||||||
* Each operation derives a new class from the base customizing
|
|
||||||
* members, constructors and the doWork() method to effect
|
|
||||||
* the command.
|
|
||||||
*
|
|
||||||
* The flow is one-directional. There are two global instances
|
|
||||||
* of the LLViewerAssetStats collector, one for the main program's
|
|
||||||
* thread pointed to by gViewerAssetStatsMain and one for the
|
|
||||||
* TextureFetch thread pointed to by gViewerAssetStatsThread1.
|
|
||||||
* Common operations has each thread recording metrics events
|
|
||||||
* into the respective collector unconcerned with locking and
|
|
||||||
* the state of any other thread. But when the agent moves into
|
|
||||||
* a different region or the metrics timer expires and a report
|
|
||||||
* needs to be sent back to the grid, messaging across threads
|
|
||||||
* is required to distribute data and perform global actions.
|
|
||||||
* In pseudo-UML, it looks like:
|
|
||||||
*
|
|
||||||
* Main Thread1
|
|
||||||
* . .
|
|
||||||
* . .
|
|
||||||
* +-----+ .
|
|
||||||
* | AM | .
|
|
||||||
* +--+--+ .
|
|
||||||
* +-------+ | .
|
|
||||||
* | Main | +--+--+ .
|
|
||||||
* | | | SRE |---. .
|
|
||||||
* | Stats | +-----+ \ .
|
|
||||||
* | | | \ (uuid) +-----+
|
|
||||||
* | Coll. | +--+--+ `-------->| SR |
|
|
||||||
* +-------+ | MSC | +--+--+
|
|
||||||
* | ^ +-----+ |
|
|
||||||
* | | (uuid) / . +-----+ (uuid)
|
|
||||||
* | `--------' . | MSC |---------.
|
|
||||||
* | . +-----+ |
|
|
||||||
* | +-----+ . v
|
|
||||||
* | | TE | . +-------+
|
|
||||||
* | +--+--+ . | Thd1 |
|
|
||||||
* | | . | |
|
|
||||||
* | +-----+ . | Stats |
|
|
||||||
* `--------->| RSC | . | |
|
|
||||||
* +--+--+ . | Coll. |
|
|
||||||
* | . +-------+
|
|
||||||
* +--+--+ . |
|
|
||||||
* | SME |---. . |
|
|
||||||
* +-----+ \ . |
|
|
||||||
* . \ (clone) +-----+ |
|
|
||||||
* . `-------->| SM | |
|
|
||||||
* . +--+--+ |
|
|
||||||
* . | |
|
|
||||||
* . +-----+ |
|
|
||||||
* . | RSC |<--------'
|
|
||||||
* . +-----+
|
|
||||||
* . |
|
|
||||||
* . +-----+
|
|
||||||
* . | CP |--> HTTP POST
|
|
||||||
* . +-----+
|
|
||||||
* . .
|
|
||||||
* . .
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Key:
|
|
||||||
*
|
|
||||||
* SRE - Set Region Enqueued. Enqueue a 'Set Region' command in
|
|
||||||
* the other thread providing the new UUID of the region.
|
|
||||||
* TFReqSetRegion carries the data.
|
|
||||||
* SR - Set Region. New region UUID is sent to the thread-local
|
|
||||||
* collector.
|
|
||||||
* SME - Send Metrics Enqueued. Enqueue a 'Send Metrics' command
|
|
||||||
* including an ownership transfer of a cloned LLViewerAssetStats.
|
|
||||||
* TFReqSendMetrics carries the data.
|
|
||||||
* SM - Send Metrics. Global metrics reporting operation. Takes
|
|
||||||
* the cloned stats from the command, merges it with the
|
|
||||||
* thread's local stats, converts to LLSD and sends it on
|
|
||||||
* to the grid.
|
|
||||||
* AM - Agent Moved. Agent has completed some sort of move to a
|
|
||||||
* new region.
|
|
||||||
* TE - Timer Expired. Metrics timer has expired (on the order
|
|
||||||
* of 10 minutes).
|
|
||||||
* CP - CURL Post
|
|
||||||
* MSC - Modify Stats Collector. State change in the thread-local
|
|
||||||
* collector. Typically a region change which affects the
|
|
||||||
* global pointers used to find the 'current stats'.
|
|
||||||
* RSC - Read Stats Collector. Extract collector data cloning it
|
|
||||||
* (i.e. deep copy) when necessary.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class LLTextureFetch::TFRequest // : public LLQueuedThread::QueuedRequest
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// Default ctors and assignment operator are correct.
|
|
||||||
|
|
||||||
virtual ~TFRequest()
|
|
||||||
{}
|
|
||||||
|
|
||||||
// Patterned after QueuedRequest's method but expected behavior
|
|
||||||
// is different. Always expected to complete on the first call
|
|
||||||
// and work dispatcher will assume the same and delete the
|
|
||||||
// request after invocation.
|
|
||||||
virtual bool doWork(LLTextureFetch * fetcher) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Implements a 'Set Region' cross-thread command.
|
|
||||||
*
|
|
||||||
* When an agent moves to a new region, subsequent metrics need
|
|
||||||
* to be binned into a new or existing stats collection in 1:1
|
|
||||||
* relationship with the region. We communicate this region
|
|
||||||
* change across the threads involved in the communication with
|
|
||||||
* this message.
|
|
||||||
*
|
|
||||||
* Corresponds to LLTextureFetch::commandSetRegion()
|
|
||||||
*/
|
|
||||||
class TFReqSetRegion : public LLTextureFetch::TFRequest
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
TFReqSetRegion(U64 region_handle)
|
|
||||||
: LLTextureFetch::TFRequest(),
|
|
||||||
mRegionHandle(region_handle)
|
|
||||||
{}
|
|
||||||
TFReqSetRegion & operator=(const TFReqSetRegion &); // Not defined
|
|
||||||
|
|
||||||
virtual ~TFReqSetRegion()
|
|
||||||
{}
|
|
||||||
|
|
||||||
virtual bool doWork(LLTextureFetch * fetcher);
|
|
||||||
|
|
||||||
public:
|
|
||||||
const U64 mRegionHandle;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Implements a 'Send Metrics' cross-thread command.
|
|
||||||
*
|
|
||||||
* This is the big operation. The main thread gathers metrics
|
|
||||||
* for a period of minutes into LLViewerAssetStats and other
|
|
||||||
* objects then makes a snapshot of the data by cloning the
|
|
||||||
* collector. This command transfers the clone, along with a few
|
|
||||||
* additional arguments (UUIDs), handing ownership to the
|
|
||||||
* TextureFetch thread. It then merges its own data into the
|
|
||||||
* cloned copy, converts to LLSD and kicks off an HTTP POST of
|
|
||||||
* the resulting data to the currently active metrics collector.
|
|
||||||
*
|
|
||||||
* Corresponds to LLTextureFetch::commandSendMetrics()
|
|
||||||
*/
|
|
||||||
|
|
||||||
class TFReqSendMetrics : public LLTextureFetch::TFRequest
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Construct the 'Send Metrics' command to have the TextureFetch
|
|
||||||
* thread add and log metrics data.
|
|
||||||
*
|
|
||||||
* @param caps_url URL of a "ViewerMetrics" Caps target
|
|
||||||
* to receive the data. Does not have to
|
|
||||||
* be associated with a particular region.
|
|
||||||
*
|
|
||||||
* @param session_id UUID of the agent's session.
|
|
||||||
*
|
|
||||||
* @param agent_id UUID of the agent. (Being pure here...)
|
|
||||||
*
|
|
||||||
* @param main_stats Pointer to a clone of the main thread's
|
|
||||||
* LLViewerAssetStats data. Thread1 takes
|
|
||||||
* ownership of the copy and disposes of it
|
|
||||||
* when done.
|
|
||||||
*/
|
|
||||||
|
|
||||||
TFReqSendMetrics(const std::string & caps_url,
|
|
||||||
const LLUUID & session_id,
|
|
||||||
const LLUUID & agent_id,
|
|
||||||
LLViewerAssetStats * main_stats)
|
|
||||||
: LLTextureFetch::TFRequest(),
|
|
||||||
mCapsURL(caps_url),
|
|
||||||
mSessionID(session_id),
|
|
||||||
mAgentID(agent_id),
|
|
||||||
mMainStats(main_stats)
|
|
||||||
{}
|
|
||||||
TFReqSendMetrics & operator=(const TFReqSendMetrics &); // Not defined
|
|
||||||
|
|
||||||
virtual ~TFReqSendMetrics();
|
|
||||||
|
|
||||||
virtual bool doWork(LLTextureFetch * fetcher);
|
|
||||||
|
|
||||||
public:
|
|
||||||
const std::string mCapsURL;
|
|
||||||
const LLUUID mSessionID;
|
|
||||||
const LLUUID mAgentID;
|
|
||||||
LLViewerAssetStats * mMainStats;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Examines the merged viewer metrics report and if found to be too long,
|
|
||||||
* will attempt to truncate it in some reasonable fashion.
|
|
||||||
*
|
|
||||||
* @param max_regions Limit of regions allowed in report.
|
|
||||||
*
|
|
||||||
* @param metrics Full, merged viewer metrics report.
|
|
||||||
*
|
|
||||||
* @returns If data was truncated, returns true.
|
|
||||||
*/
|
|
||||||
bool truncate_viewer_metrics(int max_regions, LLSD & metrics);
|
|
||||||
|
|
||||||
} // end of anonymous namespace
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
//static
|
//static
|
||||||
@@ -757,11 +522,6 @@ const char* LLTextureFetchWorker::sStateDescs[] = {
|
|||||||
"DONE",
|
"DONE",
|
||||||
};
|
};
|
||||||
|
|
||||||
#if HTTP_METRICS
|
|
||||||
// static
|
|
||||||
volatile bool LLTextureFetch::svMetricsDataBreak(true); // Start with a data break
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// called from MAIN THREAD
|
// called from MAIN THREAD
|
||||||
|
|
||||||
LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
|
LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
|
||||||
@@ -786,6 +546,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
|
|||||||
mRequestedDiscard(-1),
|
mRequestedDiscard(-1),
|
||||||
mLoadedDiscard(-1),
|
mLoadedDiscard(-1),
|
||||||
mDecodedDiscard(-1),
|
mDecodedDiscard(-1),
|
||||||
|
mCacheReadTime(0.f),
|
||||||
mCacheReadHandle(LLTextureCache::nullHandle()),
|
mCacheReadHandle(LLTextureCache::nullHandle()),
|
||||||
mCacheWriteHandle(LLTextureCache::nullHandle()),
|
mCacheWriteHandle(LLTextureCache::nullHandle()),
|
||||||
mRequestedSize(0),
|
mRequestedSize(0),
|
||||||
@@ -810,9 +571,6 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
|
|||||||
mLastPacket(-1),
|
mLastPacket(-1),
|
||||||
mTotalPackets(0),
|
mTotalPackets(0),
|
||||||
mImageCodec(IMG_CODEC_INVALID)
|
mImageCodec(IMG_CODEC_INVALID)
|
||||||
#if HTTP_METRICS
|
|
||||||
,mMetricsStartTime(0)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
mCanUseNET = mUrl.empty() ;
|
mCanUseNET = mUrl.empty() ;
|
||||||
|
|
||||||
@@ -1064,6 +822,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||||||
CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
|
CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
|
||||||
mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, cache_priority,
|
mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, cache_priority,
|
||||||
offset, size, responder);
|
offset, size, responder);
|
||||||
|
mCacheReadTimer.reset();
|
||||||
}
|
}
|
||||||
else if (mUrl.empty())
|
else if (mUrl.empty())
|
||||||
{
|
{
|
||||||
@@ -1072,8 +831,9 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||||||
CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
|
CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
|
||||||
mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID, cache_priority,
|
mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID, cache_priority,
|
||||||
offset, size, responder);
|
offset, size, responder);
|
||||||
|
mCacheReadTimer.reset();
|
||||||
}
|
}
|
||||||
else if(mCanUseHTTP)
|
else if(!mUrl.empty() && mCanUseHTTP)
|
||||||
{
|
{
|
||||||
if (!(mUrl.compare(0, 7, "http://") == 0))
|
if (!(mUrl.compare(0, 7, "http://") == 0))
|
||||||
{
|
{
|
||||||
@@ -1101,6 +861,9 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
//
|
||||||
|
//This should never happen
|
||||||
|
//
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1124,7 +887,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||||||
LL_DEBUGS("Texture") << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize()
|
LL_DEBUGS("Texture") << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize()
|
||||||
<< " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight())
|
<< " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight())
|
||||||
<< " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL;
|
<< " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL;
|
||||||
// fall through
|
LLTextureFetch::sCacheHitRate.addValue(100.f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1139,7 +902,9 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||||||
LL_DEBUGS("Texture") << mID << ": Not in Cache" << LL_ENDL;
|
LL_DEBUGS("Texture") << mID << ": Not in Cache" << LL_ENDL;
|
||||||
mState = LOAD_FROM_NETWORK;
|
mState = LOAD_FROM_NETWORK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fall through
|
// fall through
|
||||||
|
LLTextureFetch::sCacheHitRate.addValue(0.f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1198,15 +963,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||||||
mRequestedDiscard = mDesiredDiscard;
|
mRequestedDiscard = mDesiredDiscard;
|
||||||
mSentRequest = QUEUED;
|
mSentRequest = QUEUED;
|
||||||
mFetcher->addToNetworkQueue(this);
|
mFetcher->addToNetworkQueue(this);
|
||||||
#if HTTP_METRICS
|
|
||||||
if (! mMetricsStartTime)
|
|
||||||
{
|
|
||||||
mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp();
|
|
||||||
}
|
|
||||||
LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE,
|
|
||||||
false,
|
|
||||||
LLImageBase::TYPE_AVATAR_BAKE == mType);
|
|
||||||
#endif
|
|
||||||
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
|
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -1217,12 +973,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||||||
//llassert_always(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end());
|
//llassert_always(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end());
|
||||||
// Make certain this is in the network queue
|
// Make certain this is in the network queue
|
||||||
//mFetcher->addToNetworkQueue(this);
|
//mFetcher->addToNetworkQueue(this);
|
||||||
//if (! mMetricsStartTime)
|
|
||||||
//{
|
|
||||||
// mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp();
|
|
||||||
//}
|
|
||||||
//LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE, false,
|
|
||||||
// LLImageBase::TYPE_AVATAR_BAKE == mType);
|
|
||||||
//setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
|
//setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1247,33 +997,10 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||||||
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
|
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
|
||||||
mState = DECODE_IMAGE;
|
mState = DECODE_IMAGE;
|
||||||
mWriteToCacheState = SHOULD_WRITE;
|
mWriteToCacheState = SHOULD_WRITE;
|
||||||
|
|
||||||
#if HTTP_METRICS
|
|
||||||
if (mMetricsStartTime)
|
|
||||||
{
|
|
||||||
LLViewerAssetStatsFF::record_response_thread1(LLViewerAssetType::AT_TEXTURE,
|
|
||||||
false,
|
|
||||||
LLImageBase::TYPE_AVATAR_BAKE == mType,
|
|
||||||
LLViewerAssetStatsFF::get_timestamp() - mMetricsStartTime);
|
|
||||||
mMetricsStartTime = 0;
|
|
||||||
}
|
|
||||||
LLViewerAssetStatsFF::record_dequeue_thread1(LLViewerAssetType::AT_TEXTURE,
|
|
||||||
false,
|
|
||||||
LLImageBase::TYPE_AVATAR_BAKE == mType);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mFetcher->addToNetworkQueue(this); // failsafe
|
mFetcher->addToNetworkQueue(this); // failsafe
|
||||||
#if HTTP_METRICS
|
|
||||||
if (! mMetricsStartTime)
|
|
||||||
{
|
|
||||||
mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp();
|
|
||||||
}
|
|
||||||
LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE,
|
|
||||||
false,
|
|
||||||
LLImageBase::TYPE_AVATAR_BAKE == mType);
|
|
||||||
#endif
|
|
||||||
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
|
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -1340,15 +1067,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||||||
mState = WAIT_HTTP_REQ;
|
mState = WAIT_HTTP_REQ;
|
||||||
|
|
||||||
mFetcher->addToHTTPQueue(mID);
|
mFetcher->addToHTTPQueue(mID);
|
||||||
#if HTTP_METRICS
|
|
||||||
if (! mMetricsStartTime)
|
|
||||||
{
|
|
||||||
mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp();
|
|
||||||
}
|
|
||||||
LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE,
|
|
||||||
true,
|
|
||||||
LLImageBase::TYPE_AVATAR_BAKE == mType);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(mRequestedOffset>0)
|
if(mRequestedOffset>0)
|
||||||
{
|
{
|
||||||
@@ -1573,11 +1291,12 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||||||
if (mState == DECODE_IMAGE)
|
if (mState == DECODE_IMAGE)
|
||||||
{
|
{
|
||||||
static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled");
|
static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled");
|
||||||
if(textures_decode_disabled)
|
|
||||||
|
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
|
||||||
|
if (textures_decode_disabled)
|
||||||
{
|
{
|
||||||
// for debug use, don't decode
|
// for debug use, don't decode
|
||||||
mState = DONE;
|
mState = DONE;
|
||||||
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1585,7 +1304,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||||||
{
|
{
|
||||||
// We aborted, don't decode
|
// We aborted, don't decode
|
||||||
mState = DONE;
|
mState = DONE;
|
||||||
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1595,7 +1313,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||||||
|
|
||||||
//abort, don't decode
|
//abort, don't decode
|
||||||
mState = DONE;
|
mState = DONE;
|
||||||
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (mLoadedDiscard < 0)
|
if (mLoadedDiscard < 0)
|
||||||
@@ -1604,10 +1321,9 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||||||
|
|
||||||
//abort, don't decode
|
//abort, don't decode
|
||||||
mState = DONE;
|
mState = DONE;
|
||||||
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
|
|
||||||
mRawImage = NULL;
|
mRawImage = NULL;
|
||||||
mAuxImage = NULL;
|
mAuxImage = NULL;
|
||||||
llassert_always(mFormattedImage.notNull());
|
llassert_always(mFormattedImage.notNull());
|
||||||
@@ -1899,6 +1615,7 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,
|
|||||||
LL_DEBUGS("Texture") << "HTTP RECEIVED: " << mID.asString() << " Bytes: " << data_size << LL_ENDL;
|
LL_DEBUGS("Texture") << "HTTP RECEIVED: " << mID.asString() << " Bytes: " << data_size << LL_ENDL;
|
||||||
if (data_size > 0)
|
if (data_size > 0)
|
||||||
{
|
{
|
||||||
|
LLViewerStatsRecorder::instance().textureFetch(data_size);
|
||||||
// *TODO: set the formatted image data here directly to avoid the copy
|
// *TODO: set the formatted image data here directly to avoid the copy
|
||||||
llassert(mHttpBuffer.empty());
|
llassert(mHttpBuffer.empty());
|
||||||
mHttpBuffer.resize(data_size);
|
mHttpBuffer.resize(data_size);
|
||||||
@@ -1932,6 +1649,7 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,
|
|||||||
mLoaded = TRUE;
|
mLoaded = TRUE;
|
||||||
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
|
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
|
||||||
|
|
||||||
|
LLViewerStatsRecorder::instance().log(0.2f);
|
||||||
return data_size ;
|
return data_size ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2017,6 +1735,7 @@ void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImag
|
|||||||
mDecoded = TRUE;
|
mDecoded = TRUE;
|
||||||
// llinfos << mID << " : DECODE COMPLETE " << llendl;
|
// llinfos << mID << " : DECODE COMPLETE " << llendl;
|
||||||
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
|
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
|
||||||
|
mCacheReadTime = mCacheReadTimer.getElapsedTimeF32();
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -2058,13 +1777,7 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
|
|||||||
mTextureBandwidth(0),
|
mTextureBandwidth(0),
|
||||||
mHTTPTextureBits(0),
|
mHTTPTextureBits(0),
|
||||||
mTotalHTTPRequests(0)
|
mTotalHTTPRequests(0)
|
||||||
#if HTTP_METRICS
|
|
||||||
,mQAMode(qa_mode)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
#if HTTP_METRICS
|
|
||||||
mCurlPOSTRequestCount = 0;
|
|
||||||
#endif
|
|
||||||
mTextureInfo.setUpLogging(gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog"), gSavedSettings.getBOOL("LogTextureDownloadsToSimulator"), gSavedSettings.getU32("TextureLoggingThreshold"));
|
mTextureInfo.setUpLogging(gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog"), gSavedSettings.getBOOL("LogTextureDownloadsToSimulator"), gSavedSettings.getU32("TextureLoggingThreshold"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2072,14 +1785,6 @@ LLTextureFetch::~LLTextureFetch()
|
|||||||
{
|
{
|
||||||
clearDeleteList() ;
|
clearDeleteList() ;
|
||||||
|
|
||||||
#if HTTP_METRICS
|
|
||||||
while (! mCommands.empty())
|
|
||||||
{
|
|
||||||
TFRequest * req(mCommands.front());
|
|
||||||
mCommands.erase(mCommands.begin());
|
|
||||||
delete req;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ~LLQueuedThread() called here
|
// ~LLQueuedThread() called here
|
||||||
}
|
}
|
||||||
@@ -2341,6 +2046,11 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,
|
|||||||
discard_level = worker->mDecodedDiscard;
|
discard_level = worker->mDecodedDiscard;
|
||||||
raw = worker->mRawImage;
|
raw = worker->mRawImage;
|
||||||
aux = worker->mAuxImage;
|
aux = worker->mAuxImage;
|
||||||
|
F32 cache_read_time = worker->mCacheReadTime;
|
||||||
|
if (cache_read_time != 0.f)
|
||||||
|
{
|
||||||
|
sCacheReadLatency.addValue(cache_read_time * 1000.f);
|
||||||
|
}
|
||||||
res = true;
|
res = true;
|
||||||
LL_DEBUGS("Texture") << id << ": Request Finished. State: " << worker->mState << " Discard: " << discard_level << LL_ENDL;
|
LL_DEBUGS("Texture") << id << ": Request Finished. State: " << worker->mState << " Discard: " << discard_level << LL_ENDL;
|
||||||
worker->unlockWorkMutex();
|
worker->unlockWorkMutex();
|
||||||
@@ -2393,10 +2103,6 @@ S32 LLTextureFetch::getPending()
|
|||||||
LLMutexLock lock(&mQueueMutex);
|
LLMutexLock lock(&mQueueMutex);
|
||||||
|
|
||||||
res = mRequestQueue.size();
|
res = mRequestQueue.size();
|
||||||
#if HTTP_METRICS
|
|
||||||
res += mCurlPOSTRequestCount;
|
|
||||||
res += mCommands.size();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
unlockData();
|
unlockData();
|
||||||
return res;
|
return res;
|
||||||
@@ -2414,22 +2120,7 @@ bool LLTextureFetch::runCondition()
|
|||||||
//
|
//
|
||||||
// Changes here may need to be reflected in getPending().
|
// Changes here may need to be reflected in getPending().
|
||||||
|
|
||||||
#if HTTP_METRICS
|
return ! (mRequestQueue.empty() && mIdleThread); // From base class
|
||||||
bool have_no_commands(false);
|
|
||||||
{
|
|
||||||
LLMutexLock lock(&mQueueMutex);
|
|
||||||
|
|
||||||
have_no_commands = mCommands.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool have_no_curl_requests(0 == mCurlPOSTRequestCount);
|
|
||||||
|
|
||||||
return ! (have_no_commands
|
|
||||||
&& have_no_curl_requests
|
|
||||||
&& (mRequestQueue.empty() && mIdleThread)); // From base class
|
|
||||||
#else
|
|
||||||
return !(mRequestQueue.empty() && mIdleThread);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -2437,10 +2128,6 @@ bool LLTextureFetch::runCondition()
|
|||||||
// MAIN THREAD (unthreaded envs), WORKER THREAD (threaded envs)
|
// MAIN THREAD (unthreaded envs), WORKER THREAD (threaded envs)
|
||||||
void LLTextureFetch::commonUpdate()
|
void LLTextureFetch::commonUpdate()
|
||||||
{
|
{
|
||||||
#if HTTP_METRICS
|
|
||||||
// Run a cross-thread command, if any.
|
|
||||||
cmdDoWork();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2799,11 +2486,16 @@ bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8
|
|||||||
mNetworkQueueMutex.unlock() ;
|
mNetworkQueueMutex.unlock() ;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LLViewerStatsRecorder::instance().textureFetch(data_size);
|
||||||
|
LLViewerStatsRecorder::instance().log(0.1f);
|
||||||
|
|
||||||
worker->lockWorkMutex();
|
worker->lockWorkMutex();
|
||||||
|
|
||||||
// Copy header data into image object
|
|
||||||
worker->mImageCodec = codec;
|
// Copy header data into image object
|
||||||
worker->mTotalPackets = packets;
|
worker->mImageCodec = codec;
|
||||||
|
worker->mTotalPackets = packets;
|
||||||
worker->mFileSize = (S32)totalbytes;
|
worker->mFileSize = (S32)totalbytes;
|
||||||
llassert_always(totalbytes > 0);
|
llassert_always(totalbytes > 0);
|
||||||
llassert_always(data_size == FIRST_PACKET_SIZE || data_size == worker->mFileSize);
|
llassert_always(data_size == FIRST_PACKET_SIZE || data_size == worker->mFileSize);
|
||||||
@@ -2844,8 +2536,12 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1
|
|||||||
mNetworkQueueMutex.unlock() ;
|
mNetworkQueueMutex.unlock() ;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LLViewerStatsRecorder::instance().textureFetch(data_size);
|
||||||
|
LLViewerStatsRecorder::instance().log(0.1f);
|
||||||
|
|
||||||
worker->lockWorkMutex();
|
worker->lockWorkMutex();
|
||||||
|
|
||||||
|
|
||||||
res = worker->insertPacket(packet_num, data, data_size);
|
res = worker->insertPacket(packet_num, data, data_size);
|
||||||
|
|
||||||
@@ -2959,277 +2655,12 @@ void LLTextureFetch::dump()
|
|||||||
<< " STATE: " << worker->sStateDescs[worker->mState]
|
<< " STATE: " << worker->sStateDescs[worker->mState]
|
||||||
<< llendl;
|
<< llendl;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
llinfos << "LLTextureFetch ACTIVE_HTTP:" << llendl;
|
||||||
|
for (queue_t::const_iterator iter(mHTTPTextureQueue.begin());
|
||||||
// cross-thread command methods
|
mHTTPTextureQueue.end() != iter;
|
||||||
|
++iter)
|
||||||
#if HTTP_METRICS
|
|
||||||
void LLTextureFetch::commandSetRegion(U64 region_handle)
|
|
||||||
{
|
|
||||||
TFReqSetRegion * req = new TFReqSetRegion(region_handle);
|
|
||||||
|
|
||||||
cmdEnqueue(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LLTextureFetch::commandSendMetrics(const std::string & caps_url,
|
|
||||||
const LLUUID & session_id,
|
|
||||||
const LLUUID & agent_id,
|
|
||||||
LLViewerAssetStats * main_stats)
|
|
||||||
{
|
|
||||||
TFReqSendMetrics * req = new TFReqSendMetrics(caps_url, session_id, agent_id, main_stats);
|
|
||||||
|
|
||||||
cmdEnqueue(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LLTextureFetch::commandDataBreak()
|
|
||||||
{
|
|
||||||
// The pedantically correct way to implement this is to create a command
|
|
||||||
// request object in the above fashion and enqueue it. However, this is
|
|
||||||
// simple data of an advisorial not operational nature and this case
|
|
||||||
// of shared-write access is tolerable.
|
|
||||||
|
|
||||||
LLTextureFetch::svMetricsDataBreak = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LLTextureFetch::cmdEnqueue(TFRequest * req)
|
|
||||||
{
|
|
||||||
lockQueue();
|
|
||||||
mCommands.push_back(req);
|
|
||||||
unlockQueue();
|
|
||||||
|
|
||||||
unpause();
|
|
||||||
}
|
|
||||||
|
|
||||||
LLTextureFetch::TFRequest * LLTextureFetch::cmdDequeue()
|
|
||||||
{
|
|
||||||
TFRequest * ret = 0;
|
|
||||||
|
|
||||||
lockQueue();
|
|
||||||
if (! mCommands.empty())
|
|
||||||
{
|
{
|
||||||
ret = mCommands.front();
|
llinfos << " ID: " << (*iter) << llendl;
|
||||||
mCommands.erase(mCommands.begin());
|
|
||||||
}
|
|
||||||
unlockQueue();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LLTextureFetch::cmdDoWork()
|
|
||||||
{
|
|
||||||
if (mDebugPause)
|
|
||||||
{
|
|
||||||
return; // debug: don't do any work
|
|
||||||
}
|
|
||||||
|
|
||||||
TFRequest * req = cmdDequeue();
|
|
||||||
if (req)
|
|
||||||
{
|
|
||||||
// One request per pass should really be enough for this.
|
|
||||||
req->doWork(this);
|
|
||||||
delete req;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// Private (anonymous) class methods implementing the command scheme.
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements the 'Set Region' command.
|
|
||||||
*
|
|
||||||
* Thread: Thread1 (TextureFetch)
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
TFReqSetRegion::doWork(LLTextureFetch *)
|
|
||||||
{
|
|
||||||
LLViewerAssetStatsFF::set_region_thread1(mRegionHandle);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TFReqSendMetrics::~TFReqSendMetrics()
|
|
||||||
{
|
|
||||||
delete mMainStats;
|
|
||||||
mMainStats = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements the 'Send Metrics' command. Takes over
|
|
||||||
* ownership of the passed LLViewerAssetStats pointer.
|
|
||||||
*
|
|
||||||
* Thread: Thread1 (TextureFetch)
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* HTTP POST responder. Doesn't do much but tries to
|
|
||||||
* detect simple breaks in recording the metrics stream.
|
|
||||||
*
|
|
||||||
* The 'volatile' modifiers don't indicate signals,
|
|
||||||
* mmap'd memory or threads, really. They indicate that
|
|
||||||
* the referenced data is part of a pseudo-closure for
|
|
||||||
* this responder rather than being required for correct
|
|
||||||
* operation.
|
|
||||||
*
|
|
||||||
* We don't try very hard with the POST request. We give
|
|
||||||
* it one shot and that's more-or-less it. With a proper
|
|
||||||
* refactoring of the LLQueuedThread usage, these POSTs
|
|
||||||
* could be put in a request object and made more reliable.
|
|
||||||
*/
|
|
||||||
class lcl_responder : public LLHTTPClient::ResponderWithResult
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
lcl_responder(LLTextureFetch * fetcher,
|
|
||||||
S32 expected_sequence,
|
|
||||||
volatile const S32 & live_sequence,
|
|
||||||
volatile bool & reporting_break,
|
|
||||||
volatile bool & reporting_started)
|
|
||||||
: mFetcher(fetcher),
|
|
||||||
mExpectedSequence(expected_sequence),
|
|
||||||
mLiveSequence(live_sequence),
|
|
||||||
mReportingBreak(reporting_break),
|
|
||||||
mReportingStarted(reporting_started)
|
|
||||||
{
|
|
||||||
mFetcher->incrCurlPOSTCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
~lcl_responder()
|
|
||||||
{
|
|
||||||
mFetcher->decrCurlPOSTCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*virtual*/ void error(U32 status_num, const std::string & reason)
|
|
||||||
{
|
|
||||||
if (mLiveSequence == mExpectedSequence)
|
|
||||||
{
|
|
||||||
mReportingBreak = true;
|
|
||||||
}
|
|
||||||
LL_WARNS("Texture") << "Break in metrics stream due to POST failure to metrics collection service. Reason: "
|
|
||||||
<< reason << LL_ENDL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*virtual*/ void result(const LLSD & content)
|
|
||||||
{
|
|
||||||
if (mLiveSequence == mExpectedSequence)
|
|
||||||
{
|
|
||||||
mReportingBreak = false;
|
|
||||||
mReportingStarted = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return lcl_responder_timeout; }
|
|
||||||
/*virtual*/ char const* getName(void) const { return "lcl_responder"; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
LLTextureFetch * mFetcher;
|
|
||||||
S32 mExpectedSequence;
|
|
||||||
volatile const S32 & mLiveSequence;
|
|
||||||
volatile bool & mReportingBreak;
|
|
||||||
volatile bool & mReportingStarted;
|
|
||||||
|
|
||||||
}; // class lcl_responder
|
|
||||||
|
|
||||||
if (! gViewerAssetStatsThread1)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
static volatile bool reporting_started(false);
|
|
||||||
static volatile S32 report_sequence(0);
|
|
||||||
|
|
||||||
// We've taken over ownership of the stats copy at this
|
|
||||||
// point. Get a working reference to it for merging here
|
|
||||||
// but leave it in 'this'. Destructor will rid us of it.
|
|
||||||
LLViewerAssetStats & main_stats = *mMainStats;
|
|
||||||
|
|
||||||
// Merge existing stats into those from main, convert to LLSD
|
|
||||||
main_stats.merge(*gViewerAssetStatsThread1);
|
|
||||||
LLSD merged_llsd = main_stats.asLLSD(true);
|
|
||||||
|
|
||||||
// Add some additional meta fields to the content
|
|
||||||
merged_llsd["session_id"] = mSessionID;
|
|
||||||
merged_llsd["agent_id"] = mAgentID;
|
|
||||||
merged_llsd["message"] = "ViewerAssetMetrics"; // Identifies the type of metrics
|
|
||||||
merged_llsd["sequence"] = report_sequence; // Sequence number
|
|
||||||
merged_llsd["initial"] = ! reporting_started; // Initial data from viewer
|
|
||||||
merged_llsd["break"] = LLTextureFetch::svMetricsDataBreak; // Break in data prior to this report
|
|
||||||
|
|
||||||
// Update sequence number
|
|
||||||
if (S32_MAX == ++report_sequence)
|
|
||||||
report_sequence = 0;
|
|
||||||
|
|
||||||
// Limit the size of the stats report if necessary.
|
|
||||||
merged_llsd["truncated"] = truncate_viewer_metrics(10, merged_llsd);
|
|
||||||
|
|
||||||
if (! mCapsURL.empty())
|
|
||||||
{
|
|
||||||
LLHTTPClient::post(mCapsURL,
|
|
||||||
merged_llsd,
|
|
||||||
new lcl_responder(fetcher,
|
|
||||||
report_sequence,
|
|
||||||
report_sequence,
|
|
||||||
LLTextureFetch::svMetricsDataBreak,
|
|
||||||
reporting_started));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LLTextureFetch::svMetricsDataBreak = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// In QA mode, Metrics submode, log the result for ease of testing
|
|
||||||
if (fetcher->isQAMode())
|
|
||||||
{
|
|
||||||
LL_INFOS("Textures") << merged_llsd << LL_ENDL;
|
|
||||||
}
|
|
||||||
|
|
||||||
gViewerAssetStatsThread1->reset();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
truncate_viewer_metrics(int max_regions, LLSD & metrics)
|
|
||||||
{
|
|
||||||
static const LLSD::String reg_tag("regions");
|
|
||||||
static const LLSD::String duration_tag("duration");
|
|
||||||
|
|
||||||
LLSD & reg_map(metrics[reg_tag]);
|
|
||||||
if (reg_map.size() <= max_regions)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build map of region hashes ordered by duration
|
|
||||||
typedef std::multimap<LLSD::Real, int> reg_ordered_list_t;
|
|
||||||
reg_ordered_list_t regions_by_duration;
|
|
||||||
|
|
||||||
int ind(0);
|
|
||||||
LLSD::array_const_iterator it_end(reg_map.endArray());
|
|
||||||
for (LLSD::array_const_iterator it(reg_map.beginArray()); it_end != it; ++it, ++ind)
|
|
||||||
{
|
|
||||||
LLSD::Real duration = (*it)[duration_tag].asReal();
|
|
||||||
regions_by_duration.insert(reg_ordered_list_t::value_type(duration, ind));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build a replacement regions array with the longest-persistence regions
|
|
||||||
LLSD new_region(LLSD::emptyArray());
|
|
||||||
reg_ordered_list_t::const_reverse_iterator it2_end(regions_by_duration.rend());
|
|
||||||
reg_ordered_list_t::const_reverse_iterator it2(regions_by_duration.rbegin());
|
|
||||||
for (int i(0); i < max_regions && it2_end != it2; ++i, ++it2)
|
|
||||||
{
|
|
||||||
new_region.append(reg_map[it2->second]);
|
|
||||||
}
|
|
||||||
reg_map = new_region;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end of anonymous namespace
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|||||||
@@ -46,9 +46,6 @@ class HTTPGetResponder;
|
|||||||
class LLTextureCache;
|
class LLTextureCache;
|
||||||
class LLImageDecodeThread;
|
class LLImageDecodeThread;
|
||||||
class LLHost;
|
class LLHost;
|
||||||
#if HTTP_METRICS
|
|
||||||
class LLViewerAssetStats;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Interface class
|
// Interface class
|
||||||
class LLTextureFetch : public LLWorkerThread
|
class LLTextureFetch : public LLWorkerThread
|
||||||
@@ -98,22 +95,6 @@ public:
|
|||||||
|
|
||||||
LLTextureInfo* getTextureInfo() { return &mTextureInfo; }
|
LLTextureInfo* getTextureInfo() { return &mTextureInfo; }
|
||||||
|
|
||||||
#if HTTP_METRICS
|
|
||||||
// Commands available to other threads to control metrics gathering operations.
|
|
||||||
void commandSetRegion(U64 region_handle);
|
|
||||||
void commandSendMetrics(const std::string & caps_url,
|
|
||||||
const LLUUID & session_id,
|
|
||||||
const LLUUID & agent_id,
|
|
||||||
LLViewerAssetStats * main_stats);
|
|
||||||
void commandDataBreak();
|
|
||||||
|
|
||||||
bool isQAMode() const { return mQAMode; }
|
|
||||||
|
|
||||||
// Curl POST counter maintenance
|
|
||||||
inline void incrCurlPOSTCount() { mCurlPOSTRequestCount++; }
|
|
||||||
inline void decrCurlPOSTCount() { mCurlPOSTRequestCount--; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void addToNetworkQueue(LLTextureFetchWorker* worker);
|
void addToNetworkQueue(LLTextureFetchWorker* worker);
|
||||||
void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel);
|
void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel);
|
||||||
@@ -129,37 +110,6 @@ private:
|
|||||||
/*virtual*/ void threadedUpdate(void);
|
/*virtual*/ void threadedUpdate(void);
|
||||||
void commonUpdate();
|
void commonUpdate();
|
||||||
|
|
||||||
#if HTTP_METRICS
|
|
||||||
// Metrics command helpers
|
|
||||||
/**
|
|
||||||
* Enqueues a command request at the end of the command queue
|
|
||||||
* and wakes up the thread as needed.
|
|
||||||
*
|
|
||||||
* Takes ownership of the TFRequest object.
|
|
||||||
*
|
|
||||||
* Method locks the command queue.
|
|
||||||
*/
|
|
||||||
void cmdEnqueue(TFRequest *);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the first TFRequest object in the command queue or
|
|
||||||
* NULL if none is present.
|
|
||||||
*
|
|
||||||
* Caller acquires ownership of the object and must dispose of it.
|
|
||||||
*
|
|
||||||
* Method locks the command queue.
|
|
||||||
*/
|
|
||||||
TFRequest * cmdDequeue();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Processes the first command in the queue disposing of the
|
|
||||||
* request on completion. Successive calls are needed to perform
|
|
||||||
* additional commands.
|
|
||||||
*
|
|
||||||
* Method locks the command queue.
|
|
||||||
*/
|
|
||||||
void cmdDoWork();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LLUUID mDebugID;
|
LLUUID mDebugID;
|
||||||
@@ -172,6 +122,11 @@ private:
|
|||||||
LLMutex mQueueMutex; //to protect mRequestMap only
|
LLMutex mQueueMutex; //to protect mRequestMap only
|
||||||
LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue.
|
LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue.
|
||||||
|
|
||||||
|
public:
|
||||||
|
static LLStat sCacheHitRate;
|
||||||
|
static LLStat sCacheReadLatency;
|
||||||
|
private:
|
||||||
|
|
||||||
LLTextureCache* mTextureCache;
|
LLTextureCache* mTextureCache;
|
||||||
LLImageDecodeThread* mImageDecodeThread;
|
LLImageDecodeThread* mImageDecodeThread;
|
||||||
|
|
||||||
@@ -193,30 +148,6 @@ private:
|
|||||||
//debug use
|
//debug use
|
||||||
U32 mTotalHTTPRequests ;
|
U32 mTotalHTTPRequests ;
|
||||||
|
|
||||||
#if HTTP_METRICS
|
|
||||||
// Out-of-band cross-thread command queue. This command queue
|
|
||||||
// is logically tied to LLQueuedThread's list of
|
|
||||||
// QueuedRequest instances and so must be covered by the
|
|
||||||
// same locks.
|
|
||||||
typedef std::vector<TFRequest *> command_queue_t;
|
|
||||||
command_queue_t mCommands;
|
|
||||||
|
|
||||||
// If true, modifies some behaviors that help with QA tasks.
|
|
||||||
const bool mQAMode;
|
|
||||||
|
|
||||||
// Count of POST requests outstanding. We maintain the count
|
|
||||||
// indirectly in the CURL request responder's ctor and dtor and
|
|
||||||
// use it when determining whether or not to sleep the thread. Can't
|
|
||||||
// use the LLCurl module's request counter as it isn't thread compatible.
|
|
||||||
// *NOTE: Don't mix Atomic and static, apr_initialize must be called first.
|
|
||||||
LLAtomic32<S32> mCurlPOSTRequestCount;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// A probabilistically-correct indicator that the current
|
|
||||||
// attempt to log metrics follows a break in the metrics stream
|
|
||||||
// reporting due to either startup or a problem POSTing data.
|
|
||||||
static volatile bool svMetricsDataBreak;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LL_LLTEXTUREFETCH_H
|
#endif // LL_LLTEXTUREFETCH_H
|
||||||
|
|||||||
@@ -5179,6 +5179,18 @@ void process_sim_stats(LLMessageSystem *msg, void **user_data)
|
|||||||
case LL_SIM_STAT_IOPUMPTIME:
|
case LL_SIM_STAT_IOPUMPTIME:
|
||||||
LLViewerStats::getInstance()->mSimPumpIOMsec.addValue(stat_value);
|
LLViewerStats::getInstance()->mSimPumpIOMsec.addValue(stat_value);
|
||||||
break;
|
break;
|
||||||
|
case LL_SIM_STAT_PCTSCRIPTSRUN:
|
||||||
|
LLViewerStats::getInstance()->mSimPctScriptsRun.addValue(stat_value);
|
||||||
|
break;
|
||||||
|
case LL_SIM_STAT_SIMAISTEPTIMEMS:
|
||||||
|
LLViewerStats::getInstance()->mSimSimAIStepMsec.addValue(stat_value);
|
||||||
|
break;
|
||||||
|
case LL_SIM_STAT_SKIPPEDAISILSTEPS_PS:
|
||||||
|
LLViewerStats::getInstance()->mSimSimSkippedSilhouetteSteps.addValue(stat_value);
|
||||||
|
break;
|
||||||
|
case LL_SIM_STAT_PCTSTEPPEDCHARACTERS:
|
||||||
|
LLViewerStats::getInstance()->mSimSimPctSteppedCharacters.addValue(stat_value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// Used to be a commented out warning.
|
// Used to be a commented out warning.
|
||||||
LL_DEBUGS("Messaging") << "Unknown stat id" << stat_id << LL_ENDL;
|
LL_DEBUGS("Messaging") << "Unknown stat id" << stat_id << LL_ENDL;
|
||||||
@@ -5799,6 +5811,35 @@ static std::string reason_from_transaction_type(S32 transaction_type,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void money_balance_group_notify(const LLUUID& group_id,
|
||||||
|
const std::string& name,
|
||||||
|
bool is_group,
|
||||||
|
std::string message,
|
||||||
|
std::string notification,
|
||||||
|
LLStringUtil::format_map_t args,
|
||||||
|
LLSD payload)
|
||||||
|
{
|
||||||
|
args["NAME"] = name;
|
||||||
|
LLSD msg_args;
|
||||||
|
msg_args["MESSAGE"] = LLTrans::getString(message,args);
|
||||||
|
LLNotificationsUtil::add(notification,msg_args,payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void money_balance_avatar_notify(const LLUUID& agent_id,
|
||||||
|
const LLAvatarName& av_name,
|
||||||
|
std::string message,
|
||||||
|
std::string notification,
|
||||||
|
LLStringUtil::format_map_t args,
|
||||||
|
LLSD payload)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
LLAvatarNameCache::getPNSName(av_name,name);
|
||||||
|
args["NAME"] = name;
|
||||||
|
LLSD msg_args;
|
||||||
|
msg_args["MESSAGE"] = LLTrans::getString(message,args);
|
||||||
|
LLNotificationsUtil::add(notification,msg_args,payload);
|
||||||
|
}
|
||||||
static void process_money_balance_reply_extended(LLMessageSystem* msg)
|
static void process_money_balance_reply_extended(LLMessageSystem* msg)
|
||||||
{
|
{
|
||||||
// Added in server 1.40 and viewer 2.1, support for localization
|
// Added in server 1.40 and viewer 2.1, support for localization
|
||||||
@@ -5831,26 +5872,6 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string source_slurl;
|
|
||||||
if (is_source_group)
|
|
||||||
{
|
|
||||||
gCacheName->getGroupName(source_id, source_slurl);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LLAvatarNameCache::getPNSName(source_id, source_slurl);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string dest_slurl;
|
|
||||||
if (is_dest_group)
|
|
||||||
{
|
|
||||||
gCacheName->getGroupName(dest_id, dest_slurl);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LLAvatarNameCache::getPNSName(dest_id, dest_slurl);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string reason =
|
std::string reason =
|
||||||
reason_from_transaction_type(transaction_type, item_description);
|
reason_from_transaction_type(transaction_type, item_description);
|
||||||
|
|
||||||
@@ -5865,60 +5886,55 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg)
|
|||||||
std::string message;
|
std::string message;
|
||||||
static LLCachedControl<bool> no_transaction_clutter("LiruNoTransactionClutter", false);
|
static LLCachedControl<bool> no_transaction_clutter("LiruNoTransactionClutter", false);
|
||||||
std::string notification = no_transaction_clutter ? "Payment" : "SystemMessage";
|
std::string notification = no_transaction_clutter ? "Payment" : "SystemMessage";
|
||||||
LLSD final_args;
|
|
||||||
LLSD payload;
|
LLSD payload;
|
||||||
|
|
||||||
bool you_paid_someone = (source_id == gAgentID);
|
bool you_paid_someone = (source_id == gAgentID);
|
||||||
if (you_paid_someone)
|
if (you_paid_someone)
|
||||||
{
|
{
|
||||||
args["NAME"] = dest_slurl;
|
|
||||||
is_name_group = is_dest_group;
|
is_name_group = is_dest_group;
|
||||||
name_id = dest_id;
|
name_id = dest_id;
|
||||||
if (!reason.empty())
|
if (!reason.empty())
|
||||||
{
|
{
|
||||||
if (dest_id.notNull())
|
if (dest_id.notNull())
|
||||||
{
|
{
|
||||||
message = success ? LLTrans::getString("you_paid_ldollars", args) :
|
message = success ? "you_paid_ldollars" :
|
||||||
LLTrans::getString("you_paid_failure_ldollars", args);
|
"you_paid_failure_ldollars";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// transaction fee to the system, eg, to create a group
|
// transaction fee to the system, eg, to create a group
|
||||||
message = success ? LLTrans::getString("you_paid_ldollars_no_name", args) :
|
message = success ? "you_paid_ldollars_no_name" :
|
||||||
LLTrans::getString("you_paid_failure_ldollars_no_name", args);
|
"you_paid_failure_ldollars_no_name";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (dest_id.notNull())
|
if (dest_id.notNull())
|
||||||
{
|
{
|
||||||
message = success ? LLTrans::getString("you_paid_ldollars_no_reason", args) :
|
message = success ? "you_paid_ldollars_no_reason" :
|
||||||
LLTrans::getString("you_paid_failure_ldollars_no_reason", args);
|
"you_paid_failure_ldollars_no_reason";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// no target, no reason, you just paid money
|
// no target, no reason, you just paid money
|
||||||
message = success ? LLTrans::getString("you_paid_ldollars_no_info", args) :
|
message = success ? "you_paid_ldollars_no_info" :
|
||||||
LLTrans::getString("you_paid_failure_ldollars_no_info", args);
|
"you_paid_failure_ldollars_no_info";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final_args["MESSAGE"] = message;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// ...someone paid you
|
// ...someone paid you
|
||||||
args["NAME"] = source_slurl;
|
|
||||||
is_name_group = is_source_group;
|
is_name_group = is_source_group;
|
||||||
name_id = source_id;
|
name_id = source_id;
|
||||||
if (!reason.empty())
|
if (!reason.empty())
|
||||||
{
|
{
|
||||||
message = LLTrans::getString("paid_you_ldollars", args);
|
message = "paid_you_ldollars";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
message = LLTrans::getString("paid_you_ldollars_no_reason", args);
|
message = "paid_you_ldollars_no_reason";
|
||||||
}
|
}
|
||||||
final_args["MESSAGE"] = message;
|
|
||||||
|
|
||||||
// make notification loggable
|
// make notification loggable
|
||||||
payload["from_id"] = source_id;
|
payload["from_id"] = source_id;
|
||||||
@@ -5930,14 +5946,15 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg)
|
|||||||
if (is_name_group)
|
if (is_name_group)
|
||||||
{
|
{
|
||||||
gCacheName->getGroup(name_id,
|
gCacheName->getGroup(name_id,
|
||||||
boost::bind(&LLNotificationsUtil::add,
|
boost::bind(&money_balance_group_notify,
|
||||||
notification, final_args, payload));
|
_1, _2, _3, message,
|
||||||
|
notification, args, payload));
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
LLAvatarNameCache::get(name_id,
|
LLAvatarNameCache::get(name_id,
|
||||||
boost::bind(&LLNotificationsUtil::add,
|
boost::bind(&money_balance_avatar_notify,
|
||||||
notification, final_args, payload));
|
_1, _2, message,
|
||||||
|
notification, args, payload));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,7 @@
|
|||||||
#include "llsdutil.h"
|
#include "llsdutil.h"
|
||||||
#include "llviewerregion.h"
|
#include "llviewerregion.h"
|
||||||
#include "llviewerstats.h"
|
#include "llviewerstats.h"
|
||||||
|
#include "llviewerstatsrecorder.h"
|
||||||
#include "llvovolume.h"
|
#include "llvovolume.h"
|
||||||
#include "llvoavatarself.h"
|
#include "llvoavatarself.h"
|
||||||
#include "lltoolmgr.h"
|
#include "lltoolmgr.h"
|
||||||
@@ -113,6 +114,7 @@ extern LLPipeline gPipeline;
|
|||||||
U32 LLViewerObjectList::sSimulatorMachineIndex = 1; // Not zero deliberately, to speed up index check.
|
U32 LLViewerObjectList::sSimulatorMachineIndex = 1; // Not zero deliberately, to speed up index check.
|
||||||
std::map<U64, U32> LLViewerObjectList::sIPAndPortToIndex;
|
std::map<U64, U32> LLViewerObjectList::sIPAndPortToIndex;
|
||||||
std::map<U64, LLUUID> LLViewerObjectList::sIndexAndLocalIDToUUID;
|
std::map<U64, LLUUID> LLViewerObjectList::sIndexAndLocalIDToUUID;
|
||||||
|
LLStat LLViewerObjectList::sCacheHitRate("object_cache_hits", 128);
|
||||||
|
|
||||||
LLViewerObjectList::LLViewerObjectList()
|
LLViewerObjectList::LLViewerObjectList()
|
||||||
{
|
{
|
||||||
@@ -384,11 +386,14 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
|||||||
U8 compressed_dpbuffer[2048];
|
U8 compressed_dpbuffer[2048];
|
||||||
LLDataPackerBinaryBuffer compressed_dp(compressed_dpbuffer, 2048);
|
LLDataPackerBinaryBuffer compressed_dp(compressed_dpbuffer, 2048);
|
||||||
LLDataPacker *cached_dpp = NULL;
|
LLDataPacker *cached_dpp = NULL;
|
||||||
|
LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instance();
|
||||||
|
|
||||||
for (i = 0; i < num_objects; i++)
|
for (i = 0; i < num_objects; i++)
|
||||||
{
|
{
|
||||||
|
// timer is unused?
|
||||||
LLTimer update_timer;
|
LLTimer update_timer;
|
||||||
BOOL justCreated = FALSE;
|
BOOL justCreated = FALSE;
|
||||||
|
S32 msg_size = 0;
|
||||||
|
|
||||||
if (cached)
|
if (cached)
|
||||||
{
|
{
|
||||||
@@ -396,6 +401,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
|||||||
U32 crc;
|
U32 crc;
|
||||||
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, id, i);
|
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, id, i);
|
||||||
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_CRC, crc, i);
|
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_CRC, crc, i);
|
||||||
|
msg_size += sizeof(U32) * 2;
|
||||||
|
|
||||||
// Lookup data packer and add this id to cache miss lists if necessary.
|
// Lookup data packer and add this id to cache miss lists if necessary.
|
||||||
U8 cache_miss_type = LLViewerRegion::CACHE_MISS_TYPE_NONE;
|
U8 cache_miss_type = LLViewerRegion::CACHE_MISS_TYPE_NONE;
|
||||||
@@ -411,9 +417,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Cache Miss.
|
// Cache Miss.
|
||||||
#if LL_RECORD_VIEWER_STATS
|
recorder.cacheMissEvent(id, update_type, cache_miss_type, msg_size);
|
||||||
LLViewerStatsRecorder::instance()->recordCacheMissEvent(id, update_type, cache_miss_type);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
continue; // no data packer, skip this object
|
continue; // no data packer, skip this object
|
||||||
}
|
}
|
||||||
@@ -433,8 +437,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
|||||||
mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compressed_dpbuffer, 0, i);
|
mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compressed_dpbuffer, 0, i);
|
||||||
compressed_dp.assignBuffer(compressed_dpbuffer, uncompressed_length);
|
compressed_dp.assignBuffer(compressed_dpbuffer, uncompressed_length);
|
||||||
|
|
||||||
|
if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?
|
||||||
if (update_type != OUT_TERSE_IMPROVED)
|
|
||||||
{
|
{
|
||||||
compressed_dp.unpackUUID(fullid, "ID");
|
compressed_dp.unpackUUID(fullid, "ID");
|
||||||
compressed_dp.unpackU32(local_id, "LocalID");
|
compressed_dp.unpackU32(local_id, "LocalID");
|
||||||
@@ -454,9 +457,11 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (update_type != OUT_FULL)
|
else if (update_type != OUT_FULL) // !compressed, !OUT_FULL ==> OUT_FULL_CACHED only?
|
||||||
{
|
{
|
||||||
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);
|
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);
|
||||||
|
msg_size += sizeof(U32);
|
||||||
|
|
||||||
getUUIDFromLocal(fullid,
|
getUUIDFromLocal(fullid,
|
||||||
local_id,
|
local_id,
|
||||||
gMessageSystem->getSenderIP(),
|
gMessageSystem->getSenderIP(),
|
||||||
@@ -467,10 +472,12 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
|||||||
mNumUnknownUpdates++;
|
mNumUnknownUpdates++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else // OUT_FULL only?
|
||||||
{
|
{
|
||||||
mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FullID, fullid, i);
|
mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FullID, fullid, i);
|
||||||
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);
|
mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);
|
||||||
|
msg_size += sizeof(LLUUID);
|
||||||
|
msg_size += sizeof(U32);
|
||||||
// llinfos << "Full Update, obj " << local_id << ", global ID" << fullid << "from " << mesgsys->getSender() << llendl;
|
// llinfos << "Full Update, obj " << local_id << ", global ID" << fullid << "from " << mesgsys->getSender() << llendl;
|
||||||
}
|
}
|
||||||
objectp = findObject(fullid);
|
objectp = findObject(fullid);
|
||||||
@@ -515,28 +522,33 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
|||||||
{
|
{
|
||||||
if (update_type == OUT_TERSE_IMPROVED)
|
if (update_type == OUT_TERSE_IMPROVED)
|
||||||
{
|
{
|
||||||
// llinfos << "terse update for an unknown object:" << fullid << llendl;
|
// llinfos << "terse update for an unknown object (compressed):" << fullid << llendl;
|
||||||
|
recorder.objectUpdateFailure(local_id, update_type, msg_size);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (cached)
|
else if (cached) // Cache hit only?
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (update_type != OUT_FULL)
|
if (update_type != OUT_FULL)
|
||||||
{
|
{
|
||||||
// llinfos << "terse update for an unknown object:" << fullid << llendl;
|
//llinfos << "terse update for an unknown object:" << fullid << llendl;
|
||||||
|
recorder.objectUpdateFailure(local_id, update_type, msg_size);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_PCode, pcode, i);
|
mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_PCode, pcode, i);
|
||||||
|
msg_size += sizeof(U8);
|
||||||
|
|
||||||
}
|
}
|
||||||
#ifdef IGNORE_DEAD
|
#ifdef IGNORE_DEAD
|
||||||
if (mDeadObjects.find(fullid) != mDeadObjects.end())
|
if (mDeadObjects.find(fullid) != mDeadObjects.end())
|
||||||
{
|
{
|
||||||
mNumDeadObjectUpdates++;
|
mNumDeadObjectUpdates++;
|
||||||
// llinfos << "update for a dead object:" << fullid << llendl;
|
//llinfos << "update for a dead object:" << fullid << llendl;
|
||||||
|
recorder.objectUpdateFailure(local_id, update_type, msg_size);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -553,10 +565,14 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
|||||||
objectp = createObject(pcode, regionp, fullid, local_id, gMessageSystem->getSender());
|
objectp = createObject(pcode, regionp, fullid, local_id, gMessageSystem->getSender());
|
||||||
if (!objectp)
|
if (!objectp)
|
||||||
{
|
{
|
||||||
|
llinfos << "createObject failure for object: " << fullid << llendl;
|
||||||
|
recorder.objectUpdateFailure(local_id, update_type, msg_size);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
justCreated = TRUE;
|
justCreated = TRUE;
|
||||||
mNumNewObjects++;
|
mNumNewObjects++;
|
||||||
|
sCacheHitRate.addValue(cached ? 100.f : 0.f);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -568,15 +584,16 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
|||||||
bool bCached = false;
|
bool bCached = false;
|
||||||
if (compressed)
|
if (compressed)
|
||||||
{
|
{
|
||||||
if (update_type != OUT_TERSE_IMPROVED)
|
if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?
|
||||||
{
|
{
|
||||||
objectp->mLocalID = local_id;
|
objectp->mLocalID = local_id;
|
||||||
}
|
}
|
||||||
processUpdateCore(objectp, user_data, i, update_type, &compressed_dp, justCreated);
|
processUpdateCore(objectp, user_data, i, update_type, &compressed_dp, justCreated);
|
||||||
if (update_type != OUT_TERSE_IMPROVED)
|
if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?
|
||||||
{
|
{
|
||||||
bCached = true;
|
bCached = true;
|
||||||
objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp);
|
LLViewerRegion::eCacheUpdateResult result = objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp);
|
||||||
|
recorder.cacheFullUpdate(local_id, update_type, result, objectp, msg_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (cached)
|
else if (cached)
|
||||||
@@ -592,11 +609,13 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
|||||||
}
|
}
|
||||||
processUpdateCore(objectp, user_data, i, update_type, NULL, justCreated);
|
processUpdateCore(objectp, user_data, i, update_type, NULL, justCreated);
|
||||||
}
|
}
|
||||||
|
recorder.objectUpdateEvent(local_id, update_type, objectp, msg_size);
|
||||||
objectp->setLastUpdateType(update_type);
|
objectp->setLastUpdateType(update_type);
|
||||||
objectp->setLastUpdateCached(bCached);
|
objectp->setLastUpdateCached(bCached);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recorder.log(0.2f);
|
||||||
|
|
||||||
LLVOAvatar::cullAvatarsByPixelArea();
|
LLVOAvatar::cullAvatarsByPixelArea();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -205,6 +205,8 @@ public:
|
|||||||
std::vector<OrphanInfo> mOrphanChildren; // UUID's of orphaned objects
|
std::vector<OrphanInfo> mOrphanChildren; // UUID's of orphaned objects
|
||||||
S32 mNumOrphans;
|
S32 mNumOrphans;
|
||||||
|
|
||||||
|
static LLStat sCacheHitRate;
|
||||||
|
|
||||||
typedef std::vector<LLPointer<LLViewerObject> > vobj_list_t;
|
typedef std::vector<LLPointer<LLViewerObject> > vobj_list_t;
|
||||||
|
|
||||||
vobj_list_t mObjects;
|
vobj_list_t mObjects;
|
||||||
|
|||||||
@@ -1405,11 +1405,8 @@ void LLViewerRegion::requestCacheMisses()
|
|||||||
|
|
||||||
mCacheDirty = TRUE ;
|
mCacheDirty = TRUE ;
|
||||||
// llinfos << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << llendl;
|
// llinfos << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << llendl;
|
||||||
#if LL_RECORD_VIEWER_STATS
|
LLViewerStatsRecorder::instance().requestCacheMissesEvent(full_count + crc_count);
|
||||||
LLViewerStatsRecorder::instance()->beginObjectUpdateEvents(this);
|
LLViewerStatsRecorder::instance().log(0.2f);
|
||||||
LLViewerStatsRecorder::instance()->recordRequestCacheMissesEvent(full_count + crc_count);
|
|
||||||
LLViewerStatsRecorder::instance()->endObjectUpdateEvents();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLViewerRegion::dumpCache()
|
void LLViewerRegion::dumpCache()
|
||||||
|
|||||||
@@ -1887,18 +1887,19 @@ BOOL LLViewerShaderMgr::loadShadersObject()
|
|||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
gObjectPreviewProgram.mName = "Simple Shader";
|
gObjectPreviewProgram.mName = "Simple Shader";
|
||||||
gObjectPreviewProgram.mFeatures.calculatesLighting = true;
|
gObjectPreviewProgram.mFeatures.calculatesLighting = false;
|
||||||
gObjectPreviewProgram.mFeatures.calculatesAtmospherics = true;
|
gObjectPreviewProgram.mFeatures.calculatesAtmospherics = false;
|
||||||
gObjectPreviewProgram.mFeatures.hasGamma = true;
|
gObjectPreviewProgram.mFeatures.hasGamma = false;
|
||||||
gObjectPreviewProgram.mFeatures.hasAtmospherics = true;
|
gObjectPreviewProgram.mFeatures.hasAtmospherics = false;
|
||||||
gObjectPreviewProgram.mFeatures.hasLighting = true;
|
gObjectPreviewProgram.mFeatures.hasLighting = false;
|
||||||
gObjectPreviewProgram.mFeatures.mIndexedTextureChannels = 0;
|
gObjectPreviewProgram.mFeatures.mIndexedTextureChannels = 0;
|
||||||
gObjectPreviewProgram.mFeatures.disableTextureIndex = true;
|
gObjectPreviewProgram.mFeatures.disableTextureIndex = true;
|
||||||
gObjectPreviewProgram.mShaderFiles.clear();
|
gObjectPreviewProgram.mShaderFiles.clear();
|
||||||
gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewV.glsl", GL_VERTEX_SHADER_ARB));
|
gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewV.glsl", GL_VERTEX_SHADER_ARB));
|
||||||
gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
|
gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewF.glsl", GL_FRAGMENT_SHADER_ARB));
|
||||||
gObjectPreviewProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
|
gObjectPreviewProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
|
||||||
success = gObjectPreviewProgram.createShader(NULL, NULL);
|
success = gObjectPreviewProgram.createShader(NULL, NULL);
|
||||||
|
gObjectPreviewProgram.mFeatures.hasLighting = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
|
|||||||
@@ -239,6 +239,9 @@ LLViewerStats::LLViewerStats() :
|
|||||||
mSimSimPhysicsStepMsec("simsimphysicsstepmsec"),
|
mSimSimPhysicsStepMsec("simsimphysicsstepmsec"),
|
||||||
mSimSimPhysicsShapeUpdateMsec("simsimphysicsshapeupdatemsec"),
|
mSimSimPhysicsShapeUpdateMsec("simsimphysicsshapeupdatemsec"),
|
||||||
mSimSimPhysicsOtherMsec("simsimphysicsothermsec"),
|
mSimSimPhysicsOtherMsec("simsimphysicsothermsec"),
|
||||||
|
mSimSimAIStepMsec("simsimaistepmsec"),
|
||||||
|
mSimSimSkippedSilhouetteSteps("simsimskippedsilhouettesteps"),
|
||||||
|
mSimSimPctSteppedCharacters("simsimpctsteppedcharacters"),
|
||||||
mSimAgentMsec("simagentmsec"),
|
mSimAgentMsec("simagentmsec"),
|
||||||
mSimImagesMsec("simimagesmsec"),
|
mSimImagesMsec("simimagesmsec"),
|
||||||
mSimScriptMsec("simscriptmsec"),
|
mSimScriptMsec("simscriptmsec"),
|
||||||
@@ -250,6 +253,7 @@ LLViewerStats::LLViewerStats() :
|
|||||||
mSimObjects("simobjects"),
|
mSimObjects("simobjects"),
|
||||||
mSimActiveObjects("simactiveobjects"),
|
mSimActiveObjects("simactiveobjects"),
|
||||||
mSimActiveScripts("simactivescripts"),
|
mSimActiveScripts("simactivescripts"),
|
||||||
|
mSimPctScriptsRun("simpctscriptsrun"),
|
||||||
mSimInPPS("siminpps"),
|
mSimInPPS("siminpps"),
|
||||||
mSimOutPPS("simoutpps"),
|
mSimOutPPS("simoutpps"),
|
||||||
mSimPendingDownloads("simpendingdownloads"),
|
mSimPendingDownloads("simpendingdownloads"),
|
||||||
@@ -292,19 +296,19 @@ LLViewerStats::~LLViewerStats()
|
|||||||
|
|
||||||
void LLViewerStats::resetStats()
|
void LLViewerStats::resetStats()
|
||||||
{
|
{
|
||||||
LLViewerStats::getInstance()->mKBitStat.reset();
|
LLViewerStats& stats = LLViewerStats::instance();
|
||||||
LLViewerStats::getInstance()->mLayersKBitStat.reset();
|
stats.mKBitStat.reset();
|
||||||
LLViewerStats::getInstance()->mObjectKBitStat.reset();
|
stats.mLayersKBitStat.reset();
|
||||||
LLViewerStats::getInstance()->mTextureKBitStat.reset();
|
stats.mObjectKBitStat.reset();
|
||||||
LLViewerStats::getInstance()->mVFSPendingOperations.reset();
|
stats.mTextureKBitStat.reset();
|
||||||
LLViewerStats::getInstance()->mAssetKBitStat.reset();
|
stats.mVFSPendingOperations.reset();
|
||||||
LLViewerStats::getInstance()->mPacketsInStat.reset();
|
stats.mAssetKBitStat.reset();
|
||||||
LLViewerStats::getInstance()->mPacketsLostStat.reset();
|
stats.mPacketsInStat.reset();
|
||||||
LLViewerStats::getInstance()->mPacketsOutStat.reset();
|
stats.mPacketsLostStat.reset();
|
||||||
LLViewerStats::getInstance()->mFPSStat.reset();
|
stats.mPacketsOutStat.reset();
|
||||||
LLViewerStats::getInstance()->mTexturePacketsStat.reset();
|
stats.mFPSStat.reset();
|
||||||
|
stats.mTexturePacketsStat.reset();
|
||||||
LLViewerStats::getInstance()->mAgentPositionSnaps.reset();
|
stats.mAgentPositionSnaps.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -329,55 +333,55 @@ void LLViewerStats::updateFrameStats(const F64 time_diff)
|
|||||||
{
|
{
|
||||||
if (mPacketsLostPercentStat.getCurrent() > 5.0)
|
if (mPacketsLostPercentStat.getCurrent() > 5.0)
|
||||||
{
|
{
|
||||||
incStat(LLViewerStats::ST_LOSS_05_SECONDS, time_diff);
|
incStat(ST_LOSS_05_SECONDS, time_diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSimFPS.getCurrent() < 20.f && mSimFPS.getCurrent() > 0.f)
|
if (mSimFPS.getCurrent() < 20.f && mSimFPS.getCurrent() > 0.f)
|
||||||
{
|
{
|
||||||
incStat(LLViewerStats::ST_SIM_FPS_20_SECONDS, time_diff);
|
incStat(ST_SIM_FPS_20_SECONDS, time_diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSimPhysicsFPS.getCurrent() < 20.f && mSimPhysicsFPS.getCurrent() > 0.f)
|
if (mSimPhysicsFPS.getCurrent() < 20.f && mSimPhysicsFPS.getCurrent() > 0.f)
|
||||||
{
|
{
|
||||||
incStat(LLViewerStats::ST_PHYS_FPS_20_SECONDS, time_diff);
|
incStat(ST_PHYS_FPS_20_SECONDS, time_diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (time_diff >= 0.5)
|
if (time_diff >= 0.5)
|
||||||
{
|
{
|
||||||
incStat(LLViewerStats::ST_FPS_2_SECONDS, time_diff);
|
incStat(ST_FPS_2_SECONDS, time_diff);
|
||||||
}
|
}
|
||||||
if (time_diff >= 0.125)
|
if (time_diff >= 0.125)
|
||||||
{
|
{
|
||||||
incStat(LLViewerStats::ST_FPS_8_SECONDS, time_diff);
|
incStat(ST_FPS_8_SECONDS, time_diff);
|
||||||
}
|
}
|
||||||
if (time_diff >= 0.1)
|
if (time_diff >= 0.1)
|
||||||
{
|
{
|
||||||
incStat(LLViewerStats::ST_FPS_10_SECONDS, time_diff);
|
incStat(ST_FPS_10_SECONDS, time_diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gFrameCount && mLastTimeDiff > 0.0)
|
if (gFrameCount && mLastTimeDiff > 0.0)
|
||||||
{
|
{
|
||||||
// new "stutter" meter
|
// new "stutter" meter
|
||||||
setStat(LLViewerStats::ST_FPS_DROP_50_RATIO,
|
setStat(ST_FPS_DROP_50_RATIO,
|
||||||
(getStat(LLViewerStats::ST_FPS_DROP_50_RATIO) * (F64)(gFrameCount - 1) +
|
(getStat(ST_FPS_DROP_50_RATIO) * (F64)(gFrameCount - 1) +
|
||||||
(time_diff >= 2.0 * mLastTimeDiff ? 1.0 : 0.0)) / gFrameCount);
|
(time_diff >= 2.0 * mLastTimeDiff ? 1.0 : 0.0)) / gFrameCount);
|
||||||
|
|
||||||
|
|
||||||
// old stats that were never really used
|
// old stats that were never really used
|
||||||
setStat(LLViewerStats::ST_FRAMETIME_JITTER,
|
setStat(ST_FRAMETIME_JITTER,
|
||||||
(getStat(LLViewerStats::ST_FRAMETIME_JITTER) * (gFrameCount - 1) +
|
(getStat(ST_FRAMETIME_JITTER) * (gFrameCount - 1) +
|
||||||
fabs(mLastTimeDiff - time_diff) / mLastTimeDiff) / gFrameCount);
|
fabs(mLastTimeDiff - time_diff) / mLastTimeDiff) / gFrameCount);
|
||||||
|
|
||||||
F32 average_frametime = gRenderStartTime.getElapsedTimeF32() / (F32)gFrameCount;
|
F32 average_frametime = gRenderStartTime.getElapsedTimeF32() / (F32)gFrameCount;
|
||||||
setStat(LLViewerStats::ST_FRAMETIME_SLEW,
|
setStat(ST_FRAMETIME_SLEW,
|
||||||
(getStat(LLViewerStats::ST_FRAMETIME_SLEW) * (gFrameCount - 1) +
|
(getStat(ST_FRAMETIME_SLEW) * (gFrameCount - 1) +
|
||||||
fabs(average_frametime - time_diff) / average_frametime) / gFrameCount);
|
fabs(average_frametime - time_diff) / average_frametime) / gFrameCount);
|
||||||
|
|
||||||
F32 max_bandwidth = gViewerThrottle.getMaxBandwidth();
|
F32 max_bandwidth = gViewerThrottle.getMaxBandwidth();
|
||||||
F32 delta_bandwidth = gViewerThrottle.getCurrentBandwidth() - max_bandwidth;
|
F32 delta_bandwidth = gViewerThrottle.getCurrentBandwidth() - max_bandwidth;
|
||||||
setStat(LLViewerStats::ST_DELTA_BANDWIDTH, delta_bandwidth / 1024.f);
|
setStat(ST_DELTA_BANDWIDTH, delta_bandwidth / 1024.f);
|
||||||
|
|
||||||
setStat(LLViewerStats::ST_MAX_BANDWIDTH, max_bandwidth / 1024.f);
|
setStat(ST_MAX_BANDWIDTH, max_bandwidth / 1024.f);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -571,25 +575,20 @@ F32 gWorstLandCompression = 0.f, gWorstWaterCompression = 0.f;
|
|||||||
U32 gTotalWorldBytes = 0, gTotalObjectBytes = 0, gTotalTextureBytes = 0, gSimPingCount = 0;
|
U32 gTotalWorldBytes = 0, gTotalObjectBytes = 0, gTotalTextureBytes = 0, gSimPingCount = 0;
|
||||||
U32 gObjectBits = 0;
|
U32 gObjectBits = 0;
|
||||||
F32 gAvgSimPing = 0.f;
|
F32 gAvgSimPing = 0.f;
|
||||||
U32 gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGORY] = {0};
|
U32 gTotalTextureBytesPerBoostLevel[LLGLTexture::MAX_GL_IMAGE_CATEGORY] = {0};
|
||||||
|
|
||||||
extern U32 gVisCompared;
|
extern U32 gVisCompared;
|
||||||
extern U32 gVisTested;
|
extern U32 gVisTested;
|
||||||
|
|
||||||
std::map<S32,LLFrameTimer> gDebugTimers;
|
LLFrameTimer gTextureTimer;
|
||||||
std::map<S32,std::string> gDebugTimerLabel;
|
|
||||||
|
|
||||||
void init_statistics()
|
void update_statistics()
|
||||||
{
|
|
||||||
// Label debug timers
|
|
||||||
gDebugTimerLabel[0] = "Texture";
|
|
||||||
}
|
|
||||||
|
|
||||||
void update_statistics(U32 frame_count)
|
|
||||||
{
|
{
|
||||||
gTotalWorldBytes += gVLManager.getTotalBytes();
|
gTotalWorldBytes += gVLManager.getTotalBytes();
|
||||||
gTotalObjectBytes += gObjectBits / 8;
|
gTotalObjectBytes += gObjectBits / 8;
|
||||||
|
|
||||||
|
LLViewerStats& stats = LLViewerStats::instance();
|
||||||
|
|
||||||
// make sure we have a valid time delta for this frame
|
// make sure we have a valid time delta for this frame
|
||||||
if (gFrameIntervalSeconds > 0.f)
|
if (gFrameIntervalSeconds > 0.f)
|
||||||
{
|
{
|
||||||
@@ -606,51 +605,51 @@ void update_statistics(U32 frame_count)
|
|||||||
LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TOOLBOX_SECONDS, gFrameIntervalSeconds);
|
LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TOOLBOX_SECONDS, gFrameIntervalSeconds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable"));
|
stats.setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable"));
|
||||||
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail());
|
stats.setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail());
|
||||||
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip"));
|
stats.setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip"));
|
||||||
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles"));
|
stats.setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles"));
|
||||||
#if 0 // 1.9.2
|
#if 0 // 1.9.2
|
||||||
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_OBJECTS, (F64)gSavedSettings.getS32("VertexShaderLevelObject"));
|
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_OBJECTS, (F64)gSavedSettings.getS32("VertexShaderLevelObject"));
|
||||||
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_AVATAR, (F64)gSavedSettings.getBOOL("VertexShaderLevelAvatar"));
|
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_AVATAR, (F64)gSavedSettings.getBOOL("VertexShaderLevelAvatar"));
|
||||||
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_ENVIRONMENT, (F64)gSavedSettings.getBOOL("VertexShaderLevelEnvironment"));
|
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_ENVIRONMENT, (F64)gSavedSettings.getBOOL("VertexShaderLevelEnvironment"));
|
||||||
#endif
|
#endif
|
||||||
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime("Frame"));
|
stats.setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime("Frame"));
|
||||||
F64 idle_secs = gDebugView->mFastTimerView->getTime("Idle");
|
F64 idle_secs = gDebugView->mFastTimerView->getTime("Idle");
|
||||||
F64 network_secs = gDebugView->mFastTimerView->getTime("Network");
|
F64 network_secs = gDebugView->mFastTimerView->getTime("Network");
|
||||||
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs);
|
stats.setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs);
|
||||||
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_NETWORK_SECS, network_secs);
|
stats.setStat(LLViewerStats::ST_NETWORK_SECS, network_secs);
|
||||||
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime("Update Images"));
|
stats.setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime("Update Images"));
|
||||||
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime("Sort Draw State"));
|
stats.setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime("Sort Draw State"));
|
||||||
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime("Geometry"));
|
stats.setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime("Geometry"));
|
||||||
|
|
||||||
LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost());
|
LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost());
|
||||||
if (cdp)
|
if (cdp)
|
||||||
{
|
{
|
||||||
LLViewerStats::getInstance()->mSimPingStat.addValue(cdp->getPingDelay());
|
stats.mSimPingStat.addValue(cdp->getPingDelay());
|
||||||
gAvgSimPing = ((gAvgSimPing * (F32)gSimPingCount) + (F32)(cdp->getPingDelay())) / ((F32)gSimPingCount + 1);
|
gAvgSimPing = ((gAvgSimPing * (F32)gSimPingCount) + (F32)(cdp->getPingDelay())) / ((F32)gSimPingCount + 1);
|
||||||
gSimPingCount++;
|
gSimPingCount++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LLViewerStats::getInstance()->mSimPingStat.addValue(10000);
|
stats.mSimPingStat.addValue(10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
LLViewerStats::getInstance()->mFPSStat.addValue(1);
|
stats.mFPSStat.addValue(1);
|
||||||
F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits());
|
F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits());
|
||||||
LLViewerStats::getInstance()->mLayersKBitStat.addValue(layer_bits/1024.f);
|
stats.mLayersKBitStat.addValue(layer_bits/1024.f);
|
||||||
LLViewerStats::getInstance()->mObjectKBitStat.addValue(gObjectBits/1024.f);
|
stats.mObjectKBitStat.addValue(gObjectBits/1024.f);
|
||||||
LLViewerStats::getInstance()->mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending());
|
stats.mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending());
|
||||||
LLViewerStats::getInstance()->mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f);
|
stats.mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f);
|
||||||
gTransferManager.resetTransferBitsIn(LLTCT_ASSET);
|
gTransferManager.resetTransferBitsIn(LLTCT_ASSET);
|
||||||
|
|
||||||
if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
|
if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
|
||||||
{
|
{
|
||||||
gDebugTimers[0].pause();
|
gTextureTimer.pause();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gDebugTimers[0].unpause();
|
gTextureTimer.unpause();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -662,7 +661,7 @@ void update_statistics(U32 frame_count)
|
|||||||
visible_avatar_frames = 1.f;
|
visible_avatar_frames = 1.f;
|
||||||
avg_visible_avatars = (avg_visible_avatars * (F32)(visible_avatar_frames - 1.f) + visible_avatars) / visible_avatar_frames;
|
avg_visible_avatars = (avg_visible_avatars * (F32)(visible_avatar_frames - 1.f) + visible_avatars) / visible_avatar_frames;
|
||||||
}
|
}
|
||||||
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_VISIBLE_AVATARS, (F64)avg_visible_avatars);
|
stats.setStat(LLViewerStats::ST_VISIBLE_AVATARS, (F64)avg_visible_avatars);
|
||||||
}
|
}
|
||||||
LLWorld::getInstance()->updateNetStats();
|
LLWorld::getInstance()->updateNetStats();
|
||||||
LLWorld::getInstance()->requestCacheMisses();
|
LLWorld::getInstance()->requestCacheMisses();
|
||||||
@@ -672,14 +671,14 @@ void update_statistics(U32 frame_count)
|
|||||||
gObjectBits = 0;
|
gObjectBits = 0;
|
||||||
// gDecodedBits = 0;
|
// gDecodedBits = 0;
|
||||||
|
|
||||||
//Update bandwidth stats often because texture fetch relies on them.
|
// Only update texture stats periodically so that they are less noisy
|
||||||
{
|
{
|
||||||
static const F32 texture_stats_freq = 0.1f;
|
static const F32 texture_stats_freq = 10.f;
|
||||||
static LLFrameTimer texture_stats_timer;
|
static LLFrameTimer texture_stats_timer;
|
||||||
if (texture_stats_timer.getElapsedTimeF32() >= texture_stats_freq)
|
if (texture_stats_timer.getElapsedTimeF32() >= texture_stats_freq)
|
||||||
{
|
{
|
||||||
LLViewerStats::getInstance()->mTextureKBitStat.addValue(LLViewerTextureList::sTextureBits/1024.f);
|
stats.mTextureKBitStat.addValue(LLViewerTextureList::sTextureBits/1024.f);
|
||||||
LLViewerStats::getInstance()->mTexturePacketsStat.addValue(LLViewerTextureList::sTexturePackets);
|
stats.mTexturePacketsStat.addValue(LLViewerTextureList::sTexturePackets);
|
||||||
LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerTextureList::sTextureBits/1024.f/texture_stats_timer.getElapsedTimeF32());
|
LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerTextureList::sTextureBits/1024.f/texture_stats_timer.getElapsedTimeF32());
|
||||||
gTotalTextureBytes += LLViewerTextureList::sTextureBits / 8;
|
gTotalTextureBytes += LLViewerTextureList::sTextureBits / 8;
|
||||||
LLViewerTextureList::sTextureBits = 0;
|
LLViewerTextureList::sTextureBits = 0;
|
||||||
@@ -693,7 +692,7 @@ void update_statistics(U32 frame_count)
|
|||||||
static LLFrameTimer mem_stats_timer;
|
static LLFrameTimer mem_stats_timer;
|
||||||
if (mem_stats_timer.getElapsedTimeF32() >= mem_stats_freq)
|
if (mem_stats_timer.getElapsedTimeF32() >= mem_stats_freq)
|
||||||
{
|
{
|
||||||
LLViewerStats::getInstance()->mMallocStat.addValue(SGMemStat::getMalloc()/1024.f/1024.f);
|
stats.mMallocStat.addValue(SGMemStat::getMalloc()/1024.f/1024.f);
|
||||||
mem_stats_timer.reset();
|
mem_stats_timer.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -813,6 +812,7 @@ void send_stats()
|
|||||||
system["gpu_class"] = (S32)LLFeatureManager::getInstance()->getGPUClass();
|
system["gpu_class"] = (S32)LLFeatureManager::getInstance()->getGPUClass();
|
||||||
system["gpu_vendor"] = gGLManager.mGLVendorShort;
|
system["gpu_vendor"] = gGLManager.mGLVendorShort;
|
||||||
system["gpu_version"] = gGLManager.mDriverVersionVendorString;
|
system["gpu_version"] = gGLManager.mDriverVersionVendorString;
|
||||||
|
system["opengl_version"] = gGLManager.mGLVersionString;
|
||||||
|
|
||||||
LLSD &download = body["downloads"];
|
LLSD &download = body["downloads"];
|
||||||
|
|
||||||
@@ -859,10 +859,7 @@ void send_stats()
|
|||||||
S32 window_height = gViewerWindow->getWindowHeightRaw();
|
S32 window_height = gViewerWindow->getWindowHeightRaw();
|
||||||
S32 window_size = (window_width * window_height) / 1024;
|
S32 window_size = (window_width * window_height) / 1024;
|
||||||
misc["string_1"] = llformat("%d", window_size);
|
misc["string_1"] = llformat("%d", window_size);
|
||||||
if (gDebugTimers.find(0) != gDebugTimers.end() && gFrameTimeSeconds > 0)
|
misc["string_2"] = llformat("Texture Time: %.2f, Total Time: %.2f", gTextureTimer.getElapsedTimeF32(), gFrameTimeSeconds);
|
||||||
{
|
|
||||||
misc["string_2"] = llformat("Texture Time: %.2f, Total Time: %.2f", gDebugTimers[0].getElapsedTimeF32(), gFrameTimeSeconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
// misc["int_1"] = LLSD::Integer(gSavedSettings.getU32("RenderQualityPerformance")); // Steve: 1.21
|
// misc["int_1"] = LLSD::Integer(gSavedSettings.getU32("RenderQualityPerformance")); // Steve: 1.21
|
||||||
// misc["int_2"] = LLSD::Integer(gFrameStalls); // Steve: 1.21
|
// misc["int_2"] = LLSD::Integer(gFrameStalls); // Steve: 1.21
|
||||||
|
|||||||
@@ -39,88 +39,91 @@
|
|||||||
class LLViewerStats : public LLSingleton<LLViewerStats>
|
class LLViewerStats : public LLSingleton<LLViewerStats>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LLStat mKBitStat;
|
LLStat mKBitStat,
|
||||||
LLStat mLayersKBitStat;
|
mLayersKBitStat,
|
||||||
LLStat mObjectKBitStat;
|
mObjectKBitStat,
|
||||||
LLStat mAssetKBitStat;
|
mAssetKBitStat,
|
||||||
LLStat mTextureKBitStat;
|
mTextureKBitStat,
|
||||||
LLStat mVFSPendingOperations;
|
mVFSPendingOperations,
|
||||||
LLStat mObjectsDrawnStat;
|
mObjectsDrawnStat,
|
||||||
LLStat mObjectsCulledStat;
|
mObjectsCulledStat,
|
||||||
LLStat mObjectsTestedStat;
|
mObjectsTestedStat,
|
||||||
LLStat mObjectsComparedStat;
|
mObjectsComparedStat,
|
||||||
LLStat mObjectsOccludedStat;
|
mObjectsOccludedStat,
|
||||||
LLStat mFPSStat;
|
mFPSStat,
|
||||||
LLStat mPacketsInStat;
|
mPacketsInStat,
|
||||||
LLStat mPacketsLostStat;
|
mPacketsLostStat,
|
||||||
LLStat mPacketsOutStat;
|
mPacketsOutStat,
|
||||||
LLStat mPacketsLostPercentStat;
|
mPacketsLostPercentStat,
|
||||||
LLStat mTexturePacketsStat;
|
mTexturePacketsStat,
|
||||||
LLStat mActualInKBitStat; // From the packet ring (when faking a bad connection)
|
mActualInKBitStat, // From the packet ring (when faking a bad connection)
|
||||||
LLStat mActualOutKBitStat; // From the packet ring (when faking a bad connection)
|
mActualOutKBitStat, // From the packet ring (when faking a bad connection)
|
||||||
LLStat mTrianglesDrawnStat;
|
mTrianglesDrawnStat,
|
||||||
LLStat mMallocStat;
|
mMallocStat;
|
||||||
|
|
||||||
// Simulator stats
|
// Simulator stats
|
||||||
LLStat mSimTimeDilation;
|
LLStat mSimTimeDilation,
|
||||||
|
|
||||||
LLStat mSimFPS;
|
mSimFPS,
|
||||||
LLStat mSimPhysicsFPS;
|
mSimPhysicsFPS,
|
||||||
LLStat mSimAgentUPS;
|
mSimAgentUPS,
|
||||||
LLStat mSimScriptEPS;
|
mSimScriptEPS,
|
||||||
|
|
||||||
LLStat mSimFrameMsec;
|
mSimFrameMsec,
|
||||||
LLStat mSimNetMsec;
|
mSimNetMsec,
|
||||||
LLStat mSimSimOtherMsec;
|
mSimSimOtherMsec,
|
||||||
LLStat mSimSimPhysicsMsec;
|
mSimSimPhysicsMsec,
|
||||||
|
|
||||||
LLStat mSimSimPhysicsStepMsec;
|
mSimSimPhysicsStepMsec,
|
||||||
LLStat mSimSimPhysicsShapeUpdateMsec;
|
mSimSimPhysicsShapeUpdateMsec,
|
||||||
LLStat mSimSimPhysicsOtherMsec;
|
mSimSimPhysicsOtherMsec,
|
||||||
|
mSimSimAIStepMsec,
|
||||||
|
mSimSimSkippedSilhouetteSteps,
|
||||||
|
mSimSimPctSteppedCharacters,
|
||||||
|
|
||||||
LLStat mSimAgentMsec;
|
mSimAgentMsec,
|
||||||
LLStat mSimImagesMsec;
|
mSimImagesMsec,
|
||||||
LLStat mSimScriptMsec;
|
mSimScriptMsec,
|
||||||
LLStat mSimSpareMsec;
|
mSimSpareMsec,
|
||||||
LLStat mSimSleepMsec;
|
mSimSleepMsec,
|
||||||
LLStat mSimPumpIOMsec;
|
mSimPumpIOMsec,
|
||||||
|
|
||||||
LLStat mSimMainAgents;
|
mSimMainAgents,
|
||||||
LLStat mSimChildAgents;
|
mSimChildAgents,
|
||||||
LLStat mSimObjects;
|
mSimObjects,
|
||||||
LLStat mSimActiveObjects;
|
mSimActiveObjects,
|
||||||
LLStat mSimActiveScripts;
|
mSimActiveScripts,
|
||||||
|
mSimPctScriptsRun,
|
||||||
|
|
||||||
LLStat mSimInPPS;
|
mSimInPPS,
|
||||||
LLStat mSimOutPPS;
|
mSimOutPPS,
|
||||||
LLStat mSimPendingDownloads;
|
mSimPendingDownloads,
|
||||||
LLStat mSimPendingUploads;
|
mSimPendingUploads,
|
||||||
LLStat mSimPendingLocalUploads;
|
mSimPendingLocalUploads,
|
||||||
LLStat mSimTotalUnackedBytes;
|
mSimTotalUnackedBytes,
|
||||||
|
|
||||||
LLStat mPhysicsPinnedTasks;
|
mPhysicsPinnedTasks,
|
||||||
LLStat mPhysicsLODTasks;
|
mPhysicsLODTasks,
|
||||||
LLStat mPhysicsMemoryAllocated;
|
mPhysicsMemoryAllocated,
|
||||||
|
|
||||||
LLStat mSimPingStat;
|
mSimPingStat,
|
||||||
|
|
||||||
LLStat mNumImagesStat;
|
mNumImagesStat,
|
||||||
LLStat mNumRawImagesStat;
|
mNumRawImagesStat,
|
||||||
LLStat mGLTexMemStat;
|
mGLTexMemStat,
|
||||||
LLStat mGLBoundMemStat;
|
mGLBoundMemStat,
|
||||||
LLStat mRawMemStat;
|
mRawMemStat,
|
||||||
LLStat mFormattedMemStat;
|
mFormattedMemStat,
|
||||||
|
|
||||||
LLStat mNumObjectsStat;
|
mNumObjectsStat,
|
||||||
LLStat mNumActiveObjectsStat;
|
mNumActiveObjectsStat,
|
||||||
LLStat mNumNewObjectsStat;
|
mNumNewObjectsStat,
|
||||||
LLStat mNumSizeCulledStat;
|
mNumSizeCulledStat,
|
||||||
LLStat mNumVisCulledStat;
|
mNumVisCulledStat;
|
||||||
|
|
||||||
void resetStats();
|
void resetStats();
|
||||||
public:
|
public:
|
||||||
// If you change this, please also add a corresponding text label
|
// If you change this, please also add a corresponding text label in llviewerstats.cpp
|
||||||
// in statTypeToText in llviewerstats.cpp
|
|
||||||
enum EStatType
|
enum EStatType
|
||||||
{
|
{
|
||||||
ST_VERSION = 0,
|
ST_VERSION = 0,
|
||||||
@@ -251,7 +254,7 @@ public:
|
|||||||
inline F32 getStdDev() const
|
inline F32 getStdDev() const
|
||||||
{
|
{
|
||||||
const F32 mean = getMean();
|
const F32 mean = getMean();
|
||||||
return (mCount == 0) ? 0.f : sqrt( mSumOfSquares/mCount - (mean * mean) );
|
return (mCount < 2) ? 0.f : sqrt(llmax(0.f,mSumOfSquares/mCount - (mean * mean)));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline U32 getCount() const
|
inline U32 getCount() const
|
||||||
@@ -291,14 +294,12 @@ private:
|
|||||||
static const F32 SEND_STATS_PERIOD = 300.0f;
|
static const F32 SEND_STATS_PERIOD = 300.0f;
|
||||||
|
|
||||||
// The following are from (older?) statistics code found in appviewer.
|
// The following are from (older?) statistics code found in appviewer.
|
||||||
void init_statistics();
|
|
||||||
void reset_statistics();
|
void reset_statistics();
|
||||||
void output_statistics(void*);
|
void output_statistics(void*);
|
||||||
void update_statistics(U32 frame_count);
|
void update_statistics();
|
||||||
void send_stats();
|
void send_stats();
|
||||||
|
|
||||||
extern std::map<S32,LLFrameTimer> gDebugTimers;
|
extern LLFrameTimer gTextureTimer;
|
||||||
extern std::map<S32,std::string> gDebugTimerLabel;
|
|
||||||
extern U32 gTotalTextureBytes;
|
extern U32 gTotalTextureBytes;
|
||||||
extern U32 gTotalObjectBytes;
|
extern U32 gTotalObjectBytes;
|
||||||
extern U32 gTotalTextureBytesPerBoostLevel[] ;
|
extern U32 gTotalTextureBytesPerBoostLevel[] ;
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
#include "llviewerprecompiledheaders.h"
|
#include "llviewerprecompiledheaders.h"
|
||||||
#include "llviewerstatsrecorder.h"
|
#include "llviewerstatsrecorder.h"
|
||||||
|
|
||||||
#if LL_RECORD_VIEWER_STATS
|
|
||||||
|
|
||||||
#include "llfile.h"
|
#include "llfile.h"
|
||||||
#include "llviewerregion.h"
|
#include "llviewerregion.h"
|
||||||
@@ -45,9 +44,8 @@ LLViewerStatsRecorder* LLViewerStatsRecorder::sInstance = NULL;
|
|||||||
LLViewerStatsRecorder::LLViewerStatsRecorder() :
|
LLViewerStatsRecorder::LLViewerStatsRecorder() :
|
||||||
mObjectCacheFile(NULL),
|
mObjectCacheFile(NULL),
|
||||||
mTimer(),
|
mTimer(),
|
||||||
mRegionp(NULL),
|
mStartTime(0.0),
|
||||||
mStartTime(0.f),
|
mLastSnapshotTime(0.0)
|
||||||
mProcessingTime(0.f)
|
|
||||||
{
|
{
|
||||||
if (NULL != sInstance)
|
if (NULL != sInstance)
|
||||||
{
|
{
|
||||||
@@ -61,112 +59,77 @@ LLViewerStatsRecorder::~LLViewerStatsRecorder()
|
|||||||
{
|
{
|
||||||
if (mObjectCacheFile != NULL)
|
if (mObjectCacheFile != NULL)
|
||||||
{
|
{
|
||||||
|
// last chance snapshot
|
||||||
|
writeToLog(0.f);
|
||||||
LLFile::close(mObjectCacheFile);
|
LLFile::close(mObjectCacheFile);
|
||||||
mObjectCacheFile = NULL;
|
mObjectCacheFile = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
|
||||||
void LLViewerStatsRecorder::initClass()
|
|
||||||
{
|
|
||||||
sInstance = new LLViewerStatsRecorder();
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
void LLViewerStatsRecorder::cleanupClass()
|
|
||||||
{
|
|
||||||
delete sInstance;
|
|
||||||
sInstance = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LLViewerStatsRecorder::initStatsRecorder(LLViewerRegion *regionp)
|
|
||||||
{
|
|
||||||
if (mObjectCacheFile == NULL)
|
|
||||||
{
|
|
||||||
mStartTime = LLTimer::getTotalTime();
|
|
||||||
mObjectCacheFile = LLFile::fopen(STATS_FILE_NAME, "wb");
|
|
||||||
if (mObjectCacheFile)
|
|
||||||
{ // Write column headers
|
|
||||||
std::ostringstream data_msg;
|
|
||||||
data_msg << "EventTime, "
|
|
||||||
<< "ProcessingTime, "
|
|
||||||
<< "CacheHits, "
|
|
||||||
<< "CacheFullMisses, "
|
|
||||||
<< "CacheCrcMisses, "
|
|
||||||
<< "FullUpdates, "
|
|
||||||
<< "TerseUpdates, "
|
|
||||||
<< "CacheMissRequests, "
|
|
||||||
<< "CacheMissResponses, "
|
|
||||||
<< "CacheUpdateDupes, "
|
|
||||||
<< "CacheUpdateChanges, "
|
|
||||||
<< "CacheUpdateAdds, "
|
|
||||||
<< "CacheUpdateReplacements, "
|
|
||||||
<< "UpdateFailures"
|
|
||||||
<< "\n";
|
|
||||||
|
|
||||||
fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LLViewerStatsRecorder::beginObjectUpdateEvents(LLViewerRegion *regionp)
|
|
||||||
{
|
|
||||||
initStatsRecorder(regionp);
|
|
||||||
mRegionp = regionp;
|
|
||||||
mProcessingTime = LLTimer::getTotalTime();
|
|
||||||
clearStats();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LLViewerStatsRecorder::clearStats()
|
void LLViewerStatsRecorder::clearStats()
|
||||||
{
|
{
|
||||||
mObjectCacheHitCount = 0;
|
mObjectCacheHitCount = 0;
|
||||||
|
mObjectCacheHitSize = 0;
|
||||||
mObjectCacheMissFullCount = 0;
|
mObjectCacheMissFullCount = 0;
|
||||||
|
mObjectCacheMissFullSize = 0;
|
||||||
mObjectCacheMissCrcCount = 0;
|
mObjectCacheMissCrcCount = 0;
|
||||||
|
mObjectCacheMissCrcSize = 0;
|
||||||
mObjectFullUpdates = 0;
|
mObjectFullUpdates = 0;
|
||||||
|
mObjectFullUpdatesSize = 0;
|
||||||
mObjectTerseUpdates = 0;
|
mObjectTerseUpdates = 0;
|
||||||
|
mObjectTerseUpdatesSize = 0;
|
||||||
mObjectCacheMissRequests = 0;
|
mObjectCacheMissRequests = 0;
|
||||||
mObjectCacheMissResponses = 0;
|
mObjectCacheMissResponses = 0;
|
||||||
|
mObjectCacheMissResponsesSize = 0;
|
||||||
mObjectCacheUpdateDupes = 0;
|
mObjectCacheUpdateDupes = 0;
|
||||||
mObjectCacheUpdateChanges = 0;
|
mObjectCacheUpdateChanges = 0;
|
||||||
mObjectCacheUpdateAdds = 0;
|
mObjectCacheUpdateAdds = 0;
|
||||||
mObjectCacheUpdateReplacements = 0;
|
mObjectCacheUpdateReplacements = 0;
|
||||||
mObjectUpdateFailures = 0;
|
mObjectUpdateFailures = 0;
|
||||||
|
mObjectUpdateFailuresSize = 0;
|
||||||
|
mTextureFetchSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LLViewerStatsRecorder::recordObjectUpdateFailure(U32 local_id, const EObjectUpdateType update_type)
|
void LLViewerStatsRecorder::recordObjectUpdateFailure(U32 local_id, const EObjectUpdateType update_type, S32 msg_size)
|
||||||
{
|
{
|
||||||
mObjectUpdateFailures++;
|
mObjectUpdateFailures++;
|
||||||
|
mObjectUpdateFailuresSize += msg_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLViewerStatsRecorder::recordCacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type)
|
void LLViewerStatsRecorder::recordCacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type, S32 msg_size)
|
||||||
{
|
{
|
||||||
if (LLViewerRegion::CACHE_MISS_TYPE_FULL == cache_miss_type)
|
if (LLViewerRegion::CACHE_MISS_TYPE_FULL == cache_miss_type)
|
||||||
{
|
{
|
||||||
mObjectCacheMissFullCount++;
|
mObjectCacheMissFullCount++;
|
||||||
|
mObjectCacheMissFullSize += msg_size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mObjectCacheMissCrcCount++;
|
mObjectCacheMissCrcCount++;
|
||||||
|
mObjectCacheMissCrcSize += msg_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLViewerStatsRecorder::recordObjectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp)
|
void LLViewerStatsRecorder::recordObjectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp, S32 msg_size)
|
||||||
{
|
{
|
||||||
switch (update_type)
|
switch (update_type)
|
||||||
{
|
{
|
||||||
case OUT_FULL:
|
case OUT_FULL:
|
||||||
mObjectFullUpdates++;
|
mObjectFullUpdates++;
|
||||||
|
mObjectFullUpdatesSize += msg_size;
|
||||||
break;
|
break;
|
||||||
case OUT_TERSE_IMPROVED:
|
case OUT_TERSE_IMPROVED:
|
||||||
mObjectTerseUpdates++;
|
mObjectTerseUpdates++;
|
||||||
|
mObjectTerseUpdatesSize += msg_size;
|
||||||
break;
|
break;
|
||||||
case OUT_FULL_COMPRESSED:
|
case OUT_FULL_COMPRESSED:
|
||||||
mObjectCacheMissResponses++;
|
mObjectCacheMissResponses++;
|
||||||
|
mObjectCacheMissResponsesSize += msg_size;
|
||||||
break;
|
break;
|
||||||
case OUT_FULL_CACHED:
|
case OUT_FULL_CACHED:
|
||||||
mObjectCacheHitCount++;
|
mObjectCacheHitCount++;
|
||||||
|
mObjectCacheHitSize += msg_size;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
llwarns << "Unknown update_type" << llendl;
|
llwarns << "Unknown update_type" << llendl;
|
||||||
@@ -174,7 +137,7 @@ void LLViewerStatsRecorder::recordObjectUpdateEvent(U32 local_id, const EObjectU
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLViewerStatsRecorder::recordCacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp)
|
void LLViewerStatsRecorder::recordCacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp, S32 msg_size)
|
||||||
{
|
{
|
||||||
switch (update_result)
|
switch (update_result)
|
||||||
{
|
{
|
||||||
@@ -201,9 +164,15 @@ void LLViewerStatsRecorder::recordRequestCacheMissesEvent(S32 count)
|
|||||||
mObjectCacheMissRequests += count;
|
mObjectCacheMissRequests += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLViewerStatsRecorder::endObjectUpdateEvents()
|
void LLViewerStatsRecorder::writeToLog( F32 interval )
|
||||||
{
|
{
|
||||||
llinfos << "ILX: "
|
F64 delta_time = LLTimer::getTotalSeconds() - mLastSnapshotTime;
|
||||||
|
S32 total_objects = mObjectCacheHitCount + mObjectCacheMissCrcCount + mObjectCacheMissFullCount + mObjectFullUpdates + mObjectTerseUpdates + mObjectCacheMissRequests + mObjectCacheMissResponses + mObjectCacheUpdateDupes + mObjectCacheUpdateChanges + mObjectCacheUpdateAdds + mObjectCacheUpdateReplacements + mObjectUpdateFailures;
|
||||||
|
|
||||||
|
if ( delta_time < interval || total_objects == 0) return;
|
||||||
|
|
||||||
|
mLastSnapshotTime = LLTimer::getTotalSeconds();
|
||||||
|
lldebugs << "ILX: "
|
||||||
<< mObjectCacheHitCount << " hits, "
|
<< mObjectCacheHitCount << " hits, "
|
||||||
<< mObjectCacheMissFullCount << " full misses, "
|
<< mObjectCacheMissFullCount << " full misses, "
|
||||||
<< mObjectCacheMissCrcCount << " crc misses, "
|
<< mObjectCacheMissCrcCount << " crc misses, "
|
||||||
@@ -218,41 +187,81 @@ void LLViewerStatsRecorder::endObjectUpdateEvents()
|
|||||||
<< mObjectUpdateFailures << " update failures"
|
<< mObjectUpdateFailures << " update failures"
|
||||||
<< llendl;
|
<< llendl;
|
||||||
|
|
||||||
S32 total_objects = mObjectCacheHitCount + mObjectCacheMissCrcCount + mObjectCacheMissFullCount + mObjectFullUpdates + mObjectTerseUpdates + mObjectCacheMissRequests + mObjectCacheMissResponses + mObjectCacheUpdateDupes + mObjectCacheUpdateChanges + mObjectCacheUpdateAdds + mObjectCacheUpdateReplacements + mObjectUpdateFailures;
|
if (mObjectCacheFile == NULL)
|
||||||
if (mObjectCacheFile != NULL &&
|
|
||||||
total_objects > 0)
|
|
||||||
{
|
{
|
||||||
std::ostringstream data_msg;
|
mStartTime = LLTimer::getTotalSeconds();
|
||||||
F32 processing32 = (F32) ((LLTimer::getTotalTime() - mProcessingTime) / 1000.0);
|
mObjectCacheFile = LLFile::fopen(STATS_FILE_NAME, "wb");
|
||||||
|
if (mObjectCacheFile)
|
||||||
|
{ // Write column headers
|
||||||
|
std::ostringstream data_msg;
|
||||||
|
data_msg << "EventTime(ms)\t"
|
||||||
|
<< "Cache Hits\t"
|
||||||
|
<< "Cache Full Misses\t"
|
||||||
|
<< "Cache Crc Misses\t"
|
||||||
|
<< "Full Updates\t"
|
||||||
|
<< "Terse Updates\t"
|
||||||
|
<< "Cache Miss Requests\t"
|
||||||
|
<< "Cache Miss Responses\t"
|
||||||
|
<< "Cache Update Dupes\t"
|
||||||
|
<< "Cache Update Changes\t"
|
||||||
|
<< "Cache Update Adds\t"
|
||||||
|
<< "Cache Update Replacements\t"
|
||||||
|
<< "Update Failures\t"
|
||||||
|
<< "Cache Hits bps\t"
|
||||||
|
<< "Cache Full Misses bps\t"
|
||||||
|
<< "Cache Crc Misses bps\t"
|
||||||
|
<< "Full Updates bps\t"
|
||||||
|
<< "Terse Updates bps\t"
|
||||||
|
<< "Cache Miss Responses bps\t"
|
||||||
|
<< "Texture Fetch bps\t"
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
data_msg << getTimeSinceStart()
|
fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile );
|
||||||
<< ", " << processing32
|
}
|
||||||
<< ", " << mObjectCacheHitCount
|
else
|
||||||
<< ", " << mObjectCacheMissFullCount
|
{
|
||||||
<< ", " << mObjectCacheMissCrcCount
|
llwarns << "Couldn't open " << STATS_FILE_NAME << " for logging." << llendl;
|
||||||
<< ", " << mObjectFullUpdates
|
return;
|
||||||
<< ", " << mObjectTerseUpdates
|
}
|
||||||
<< ", " << mObjectCacheMissRequests
|
|
||||||
<< ", " << mObjectCacheMissResponses
|
|
||||||
<< ", " << mObjectCacheUpdateDupes
|
|
||||||
<< ", " << mObjectCacheUpdateChanges
|
|
||||||
<< ", " << mObjectCacheUpdateAdds
|
|
||||||
<< ", " << mObjectCacheUpdateReplacements
|
|
||||||
<< ", " << mObjectUpdateFailures
|
|
||||||
<< "\n";
|
|
||||||
|
|
||||||
fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostringstream data_msg;
|
||||||
|
|
||||||
|
data_msg << getTimeSinceStart()
|
||||||
|
<< "\t " << mObjectCacheHitCount
|
||||||
|
<< "\t" << mObjectCacheMissFullCount
|
||||||
|
<< "\t" << mObjectCacheMissCrcCount
|
||||||
|
<< "\t" << mObjectFullUpdates
|
||||||
|
<< "\t" << mObjectTerseUpdates
|
||||||
|
<< "\t" << mObjectCacheMissRequests
|
||||||
|
<< "\t" << mObjectCacheMissResponses
|
||||||
|
<< "\t" << mObjectCacheUpdateDupes
|
||||||
|
<< "\t" << mObjectCacheUpdateChanges
|
||||||
|
<< "\t" << mObjectCacheUpdateAdds
|
||||||
|
<< "\t" << mObjectCacheUpdateReplacements
|
||||||
|
<< "\t" << mObjectUpdateFailures
|
||||||
|
<< "\t" << (mObjectCacheHitSize * 8 / delta_time)
|
||||||
|
<< "\t" << (mObjectCacheMissFullSize * 8 / delta_time)
|
||||||
|
<< "\t" << (mObjectCacheMissCrcSize * 8 / delta_time)
|
||||||
|
<< "\t" << (mObjectFullUpdatesSize * 8 / delta_time)
|
||||||
|
<< "\t" << (mObjectTerseUpdatesSize * 8 / delta_time)
|
||||||
|
<< "\t" << (mObjectCacheMissResponsesSize * 8 / delta_time)
|
||||||
|
<< "\t" << (mTextureFetchSize * 8 / delta_time)
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
|
fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile );
|
||||||
clearStats();
|
clearStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
F32 LLViewerStatsRecorder::getTimeSinceStart()
|
F32 LLViewerStatsRecorder::getTimeSinceStart()
|
||||||
{
|
{
|
||||||
return (F32) ((LLTimer::getTotalTime() - mStartTime) / 1000.0);
|
return (F32) (LLTimer::getTotalSeconds() - mStartTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
void LLViewerStatsRecorder::recordTextureFetch( S32 msg_size )
|
||||||
|
{
|
||||||
|
mTextureFetchSize += msg_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -35,63 +35,111 @@
|
|||||||
#define LL_RECORD_VIEWER_STATS 0
|
#define LL_RECORD_VIEWER_STATS 0
|
||||||
|
|
||||||
|
|
||||||
#if LL_RECORD_VIEWER_STATS
|
|
||||||
#include "llframetimer.h"
|
#include "llframetimer.h"
|
||||||
#include "llviewerobject.h"
|
#include "llviewerobject.h"
|
||||||
#include "llviewerregion.h"
|
#include "llviewerregion.h"
|
||||||
|
|
||||||
class LLMutex;
|
class LLMutex;
|
||||||
class LLViewerRegion;
|
|
||||||
class LLViewerObject;
|
class LLViewerObject;
|
||||||
|
|
||||||
class LLViewerStatsRecorder
|
class LLViewerStatsRecorder : public LLSingleton<LLViewerStatsRecorder>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
LOG_CLASS(LLViewerStatsRecorder);
|
||||||
LLViewerStatsRecorder();
|
LLViewerStatsRecorder();
|
||||||
~LLViewerStatsRecorder();
|
~LLViewerStatsRecorder();
|
||||||
|
|
||||||
static void initClass();
|
void objectUpdateFailure(U32 local_id, const EObjectUpdateType update_type, S32 msg_size)
|
||||||
static void cleanupClass();
|
{
|
||||||
static LLViewerStatsRecorder* instance() {return sInstance; }
|
#if LL_RECORD_VIEWER_STATS
|
||||||
|
recordObjectUpdateFailure(local_id, update_type, msg_size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void initStatsRecorder(LLViewerRegion *regionp);
|
void cacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type, S32 msg_size)
|
||||||
|
{
|
||||||
|
#if LL_RECORD_VIEWER_STATS
|
||||||
|
recordCacheMissEvent(local_id, update_type, cache_miss_type, msg_size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void beginObjectUpdateEvents(LLViewerRegion *regionp);
|
void objectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp, S32 msg_size)
|
||||||
void recordObjectUpdateFailure(U32 local_id, const EObjectUpdateType update_type);
|
{
|
||||||
void recordCacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type);
|
#if LL_RECORD_VIEWER_STATS
|
||||||
void recordObjectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp);
|
recordObjectUpdateEvent(local_id, update_type, objectp, msg_size);
|
||||||
void recordCacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp);
|
#endif
|
||||||
void recordRequestCacheMissesEvent(S32 count);
|
}
|
||||||
void endObjectUpdateEvents();
|
|
||||||
|
void cacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp, S32 msg_size)
|
||||||
|
{
|
||||||
|
#if LL_RECORD_VIEWER_STATS
|
||||||
|
recordCacheFullUpdate(local_id, update_type, update_result, objectp, msg_size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void requestCacheMissesEvent(S32 count)
|
||||||
|
{
|
||||||
|
#if LL_RECORD_VIEWER_STATS
|
||||||
|
recordRequestCacheMissesEvent(count);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void textureFetch(S32 msg_size)
|
||||||
|
{
|
||||||
|
#if LL_RECORD_VIEWER_STATS
|
||||||
|
recordTextureFetch(msg_size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void log(F32 interval)
|
||||||
|
{
|
||||||
|
#if LL_RECORD_VIEWER_STATS
|
||||||
|
writeToLog(interval);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
F32 getTimeSinceStart();
|
F32 getTimeSinceStart();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void recordObjectUpdateFailure(U32 local_id, const EObjectUpdateType update_type, S32 msg_size);
|
||||||
|
void recordCacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type, S32 msg_size);
|
||||||
|
void recordObjectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp, S32 msg_size);
|
||||||
|
void recordCacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp, S32 msg_size);
|
||||||
|
void recordRequestCacheMissesEvent(S32 count);
|
||||||
|
void recordTextureFetch(S32 msg_size);
|
||||||
|
void writeToLog(F32 interval);
|
||||||
|
|
||||||
static LLViewerStatsRecorder* sInstance;
|
static LLViewerStatsRecorder* sInstance;
|
||||||
|
|
||||||
LLFILE * mObjectCacheFile; // File to write data into
|
LLFILE * mObjectCacheFile; // File to write data into
|
||||||
LLFrameTimer mTimer;
|
LLFrameTimer mTimer;
|
||||||
LLViewerRegion* mRegionp;
|
|
||||||
F64 mStartTime;
|
F64 mStartTime;
|
||||||
F64 mProcessingTime;
|
F64 mLastSnapshotTime;
|
||||||
|
|
||||||
S32 mObjectCacheHitCount;
|
S32 mObjectCacheHitCount;
|
||||||
|
S32 mObjectCacheHitSize;
|
||||||
S32 mObjectCacheMissFullCount;
|
S32 mObjectCacheMissFullCount;
|
||||||
|
S32 mObjectCacheMissFullSize;
|
||||||
S32 mObjectCacheMissCrcCount;
|
S32 mObjectCacheMissCrcCount;
|
||||||
|
S32 mObjectCacheMissCrcSize;
|
||||||
S32 mObjectFullUpdates;
|
S32 mObjectFullUpdates;
|
||||||
|
S32 mObjectFullUpdatesSize;
|
||||||
S32 mObjectTerseUpdates;
|
S32 mObjectTerseUpdates;
|
||||||
|
S32 mObjectTerseUpdatesSize;
|
||||||
S32 mObjectCacheMissRequests;
|
S32 mObjectCacheMissRequests;
|
||||||
S32 mObjectCacheMissResponses;
|
S32 mObjectCacheMissResponses;
|
||||||
|
S32 mObjectCacheMissResponsesSize;
|
||||||
S32 mObjectCacheUpdateDupes;
|
S32 mObjectCacheUpdateDupes;
|
||||||
S32 mObjectCacheUpdateChanges;
|
S32 mObjectCacheUpdateChanges;
|
||||||
S32 mObjectCacheUpdateAdds;
|
S32 mObjectCacheUpdateAdds;
|
||||||
S32 mObjectCacheUpdateReplacements;
|
S32 mObjectCacheUpdateReplacements;
|
||||||
S32 mObjectUpdateFailures;
|
S32 mObjectUpdateFailures;
|
||||||
|
S32 mObjectUpdateFailuresSize;
|
||||||
|
S32 mTextureFetchSize;
|
||||||
|
|
||||||
|
|
||||||
void clearStats();
|
void clearStats();
|
||||||
};
|
};
|
||||||
#endif // LL_RECORD_VIEWER_STATS
|
|
||||||
|
|
||||||
#endif // LLVIEWERSTATSRECORDER_H
|
#endif // LLVIEWERSTATSRECORDER_H
|
||||||
|
|
||||||
|
|||||||
@@ -980,14 +980,6 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//if (fetch_count == 0)
|
|
||||||
//{
|
|
||||||
// gDebugTimers[0].pause();
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
// gDebugTimers[0].unpause();
|
|
||||||
//}
|
|
||||||
return image_op_timer.getElapsedTimeF32();
|
return image_op_timer.getElapsedTimeF32();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -318,27 +318,24 @@ public:
|
|||||||
static const LLCachedControl<bool> debug_show_time("DebugShowTime");
|
static const LLCachedControl<bool> debug_show_time("DebugShowTime");
|
||||||
if (debug_show_time)
|
if (debug_show_time)
|
||||||
{
|
{
|
||||||
const U32 y_inc2 = 15;
|
|
||||||
for (std::map<S32,LLFrameTimer>::reverse_iterator iter = gDebugTimers.rbegin();
|
|
||||||
iter != gDebugTimers.rend(); ++iter)
|
|
||||||
{
|
{
|
||||||
S32 idx = iter->first;
|
const U32 y_inc2 = 15;
|
||||||
LLFrameTimer& timer = iter->second;
|
LLFrameTimer& timer = gTextureTimer;
|
||||||
F32 time = timer.getElapsedTimeF32();
|
F32 time = timer.getElapsedTimeF32();
|
||||||
S32 hours = (S32)(time / (60*60));
|
S32 hours = (S32)(time / (60*60));
|
||||||
S32 mins = (S32)((time - hours*(60*60)) / 60);
|
S32 mins = (S32)((time - hours*(60*60)) / 60);
|
||||||
S32 secs = (S32)((time - hours*(60*60) - mins*60));
|
S32 secs = (S32)((time - hours*(60*60) - mins*60));
|
||||||
std::string label = gDebugTimerLabel[idx];
|
addText(xpos, ypos, llformat("Texture: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc2;
|
||||||
if (label.empty()) label = llformat("Debug: %d", idx);
|
|
||||||
addText(xpos, ypos, llformat(" %s: %d:%02d:%02d", label.c_str(), hours,mins,secs)); ypos += y_inc2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
F32 time = gFrameTimeSeconds;
|
F32 time = gFrameTimeSeconds;
|
||||||
S32 hours = (S32)(time / (60*60));
|
S32 hours = (S32)(time / (60*60));
|
||||||
S32 mins = (S32)((time - hours*(60*60)) / 60);
|
S32 mins = (S32)((time - hours*(60*60)) / 60);
|
||||||
S32 secs = (S32)((time - hours*(60*60) - mins*60));
|
S32 secs = (S32)((time - hours*(60*60) - mins*60));
|
||||||
addText(xpos, ypos, llformat("Time: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc;
|
addText(xpos, ypos, llformat("Time: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if LL_WINDOWS
|
#if LL_WINDOWS
|
||||||
static const LLCachedControl<bool> debug_show_memory("DebugShowMemory");
|
static const LLCachedControl<bool> debug_show_memory("DebugShowMemory");
|
||||||
|
|||||||
@@ -567,10 +567,15 @@ SHClientTagMgr::SHClientTagMgr()
|
|||||||
gSavedSettings.getControl("AscentFriendColor")->getSignal()->connect(boost::bind(&LLVOAvatar::invalidateNameTags));
|
gSavedSettings.getControl("AscentFriendColor")->getSignal()->connect(boost::bind(&LLVOAvatar::invalidateNameTags));
|
||||||
gSavedSettings.getControl("AscentMutedColor")->getSignal()->connect(boost::bind(&LLVOAvatar::invalidateNameTags));
|
gSavedSettings.getControl("AscentMutedColor")->getSignal()->connect(boost::bind(&LLVOAvatar::invalidateNameTags));
|
||||||
|
|
||||||
|
//Following group of settings all actually manipulate the tag cache for agent avatar. Even if the tag system is 'disabled', we still allow an
|
||||||
|
//entry to exist for the agent avatar.
|
||||||
gSavedSettings.getControl("AscentUseCustomTag")->getSignal()->connect(boost::bind(&SHClientTagMgr::updateAgentAvatarTag, this));
|
gSavedSettings.getControl("AscentUseCustomTag")->getSignal()->connect(boost::bind(&SHClientTagMgr::updateAgentAvatarTag, this));
|
||||||
gSavedSettings.getControl("AscentCustomTagColor")->getSignal()->connect(boost::bind(&SHClientTagMgr::updateAgentAvatarTag, this));
|
gSavedSettings.getControl("AscentCustomTagColor")->getSignal()->connect(boost::bind(&SHClientTagMgr::updateAgentAvatarTag, this));
|
||||||
gSavedSettings.getControl("AscentCustomTagLabel")->getSignal()->connect(boost::bind(&SHClientTagMgr::updateAgentAvatarTag, this));
|
gSavedSettings.getControl("AscentCustomTagLabel")->getSignal()->connect(boost::bind(&SHClientTagMgr::updateAgentAvatarTag, this));
|
||||||
|
|
||||||
|
//And because there can be an entry for the self avatar, always perform this as well.
|
||||||
|
gSavedSettings.getControl("AscentShowSelfTag")->getSignal()->connect(boost::bind(&LLVOAvatar::invalidateNameTags));
|
||||||
|
|
||||||
if(!getIsEnabled())
|
if(!getIsEnabled())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -578,12 +583,14 @@ SHClientTagMgr::SHClientTagMgr()
|
|||||||
fetchDefinitions();
|
fetchDefinitions();
|
||||||
parseDefinitions();
|
parseDefinitions();
|
||||||
|
|
||||||
//These only matter to the agent avatar. Don't iterate over everything.
|
//Tags for other users only exist if the tag system is enabled. No point in registering this callback if non-agent avatars can't have tags.
|
||||||
gSavedSettings.getControl("AscentUseTag")->getSignal()->connect(boost::bind(&SHClientTagMgr::updateAgentAvatarTag, this));
|
gSavedSettings.getControl("AscentShowOthersTag")->getSignal()->connect(boost::bind(&LLVOAvatar::invalidateNameTags));
|
||||||
|
|
||||||
|
//Update the cached tag for the agent avatar. AscentReportClientUUID dictates what tag the agent avatar sees on their self.
|
||||||
gSavedSettings.getControl("AscentReportClientUUID")->getSignal()->connect(boost::bind(&SHClientTagMgr::updateAgentAvatarTag, this));
|
gSavedSettings.getControl("AscentReportClientUUID")->getSignal()->connect(boost::bind(&SHClientTagMgr::updateAgentAvatarTag, this));
|
||||||
|
|
||||||
//Fire off a AgentSetAppearance update if these change.
|
//Fire off a AgentSetAppearance update if these change. Essentially, forces the new clientid (or lack thereof) to be sent off to the server for others to see.
|
||||||
gSavedSettings.getControl("AscentUseTag")->getSignal()->connect(boost::bind(&LLAgent::sendAgentSetAppearance, &gAgent));
|
gSavedSettings.getControl("AscentBroadcastTag")->getSignal()->connect(boost::bind(&LLAgent::sendAgentSetAppearance, &gAgent));
|
||||||
gSavedSettings.getControl("AscentReportClientUUID")->getSignal()->connect(boost::bind(&LLAgent::sendAgentSetAppearance, &gAgent));
|
gSavedSettings.getControl("AscentReportClientUUID")->getSignal()->connect(boost::bind(&LLAgent::sendAgentSetAppearance, &gAgent));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -682,7 +689,6 @@ const LLSD SHClientTagMgr::generateClientTag(const LLVOAvatar* pAvatar) const
|
|||||||
|
|
||||||
if (pAvatar->isSelf())
|
if (pAvatar->isSelf())
|
||||||
{
|
{
|
||||||
static const LLCachedControl<bool> ascent_use_tag("AscentUseTag",true);
|
|
||||||
static const LLCachedControl<bool> ascent_use_custom_tag("AscentUseCustomTag", false);
|
static const LLCachedControl<bool> ascent_use_custom_tag("AscentUseCustomTag", false);
|
||||||
static const LLCachedControl<LLColor4> ascent_custom_tag_color("AscentCustomTagColor", LLColor4(.5f,1.f,.25f,1.f));
|
static const LLCachedControl<LLColor4> ascent_custom_tag_color("AscentCustomTagColor", LLColor4(.5f,1.f,.25f,1.f));
|
||||||
static const LLCachedControl<std::string> ascent_custom_tag_label("AscentCustomTagLabel","custom");
|
static const LLCachedControl<std::string> ascent_custom_tag_label("AscentCustomTagLabel","custom");
|
||||||
@@ -699,7 +705,7 @@ const LLSD SHClientTagMgr::generateClientTag(const LLVOAvatar* pAvatar) const
|
|||||||
{
|
{
|
||||||
return LLSD();
|
return LLSD();
|
||||||
}
|
}
|
||||||
else if (ascent_use_tag)
|
else
|
||||||
{
|
{
|
||||||
id.set(ascent_report_client_uuid,false);
|
id.set(ascent_report_client_uuid,false);
|
||||||
}
|
}
|
||||||
@@ -796,24 +802,32 @@ void SHClientTagMgr::updateAvatarTag(LLVOAvatar* pAvatar)
|
|||||||
if(new_tag.isUndefined())
|
if(new_tag.isUndefined())
|
||||||
mAvatarTags.erase(id);
|
mAvatarTags.erase(id);
|
||||||
else
|
else
|
||||||
mAvatarTags.insert(std::pair<LLUUID,LLSD>(id, new_tag));
|
mAvatarTags[id]=new_tag;
|
||||||
pAvatar->clearNameTag(); //LLVOAvatar::idleUpdateNameTag will pick up on mNameString being cleared.
|
pAvatar->clearNameTag(); //LLVOAvatar::idleUpdateNameTag will pick up on mNameString being cleared.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const std::string SHClientTagMgr::getClientName(const LLVOAvatar* pAvatar, bool is_friend) const
|
const std::string SHClientTagMgr::getClientName(const LLVOAvatar* pAvatar, bool is_friend) const
|
||||||
{
|
{
|
||||||
static LLCachedControl<bool> ascent_show_friends_tag("AscentShowFriendsTag", false);
|
static LLCachedControl<bool> ascent_show_friends_tag("AscentShowFriendsTag", false);
|
||||||
|
static LLCachedControl<bool> ascent_show_self_tag("AscentShowSelfTag", false);
|
||||||
|
static LLCachedControl<bool> ascent_show_others_tag("AscentShowOthersTag", false);
|
||||||
if(is_friend && ascent_show_friends_tag)
|
if(is_friend && ascent_show_friends_tag)
|
||||||
return "Friend";
|
return "Friend";
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LLSD tag;
|
if((!pAvatar->isSelf() && ascent_show_others_tag) ||
|
||||||
std::map<LLUUID, LLSD>::const_iterator it = mAvatarTags.find(pAvatar->getID());
|
(pAvatar->isSelf() && ascent_show_self_tag))
|
||||||
if(it != mAvatarTags.end())
|
|
||||||
{
|
{
|
||||||
tag = it->second.get("name");
|
LLSD tag;
|
||||||
|
std::map<LLUUID, LLSD>::const_iterator it = mAvatarTags.find(pAvatar->getID());
|
||||||
|
if(it != mAvatarTags.end())
|
||||||
|
{
|
||||||
|
tag = it->second.get("name");
|
||||||
|
}
|
||||||
|
return tag.asString();
|
||||||
}
|
}
|
||||||
return tag.asString();
|
else
|
||||||
|
return std::string();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const LLUUID SHClientTagMgr::getClientID(const LLVOAvatar* pAvatar) const
|
const LLUUID SHClientTagMgr::getClientID(const LLVOAvatar* pAvatar) const
|
||||||
@@ -3222,7 +3236,13 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
|
|||||||
while ((index = line.find("%f")) != std::string::npos)
|
while ((index = line.find("%f")) != std::string::npos)
|
||||||
line.replace(index, 2, firstnameText);
|
line.replace(index, 2, firstnameText);
|
||||||
while ((index = line.find("%l")) != std::string::npos)
|
while ((index = line.find("%l")) != std::string::npos)
|
||||||
line.replace(index, 2, lastnameText);
|
{
|
||||||
|
llinfos << "'" << line.substr(index) << "'" << llendl;
|
||||||
|
if(lastnameText.empty() && line[index+2] == ' ') //Entire displayname string crammed into firstname
|
||||||
|
line.replace(index, 3, ""); //so eat the extra space.
|
||||||
|
else
|
||||||
|
line.replace(index, 2, lastnameText);
|
||||||
|
}
|
||||||
while ((index = line.find("%g")) != std::string::npos)
|
while ((index = line.find("%g")) != std::string::npos)
|
||||||
line.replace(index, 2, groupText);
|
line.replace(index, 2, groupText);
|
||||||
while ((index = line.find("%t")) != std::string::npos)
|
while ((index = line.find("%t")) != std::string::npos)
|
||||||
|
|||||||
@@ -2589,7 +2589,7 @@ bool LLVOAvatarSelf::sendAppearanceMessage(LLMessageSystem *mesgsys) const
|
|||||||
{
|
{
|
||||||
LLTextureEntry* entry = getTE((U8) index);
|
LLTextureEntry* entry = getTE((U8) index);
|
||||||
texture_id[index] = entry->getID();
|
texture_id[index] = entry->getID();
|
||||||
if (SHClientTagMgr::instance().getIsEnabled() && index == 0 && gSavedSettings.getBOOL("AscentUseTag"))
|
if (SHClientTagMgr::instance().getIsEnabled() && index == 0 && gSavedSettings.getBOOL("AscentBroadcastTag"))
|
||||||
entry->setID(LLUUID(gSavedSettings.getString("AscentReportClientUUID")));
|
entry->setID(LLUUID(gSavedSettings.getString("AscentReportClientUUID")));
|
||||||
else
|
else
|
||||||
entry->setID(IMG_DEFAULT_AVATAR);
|
entry->setID(IMG_DEFAULT_AVATAR);
|
||||||
|
|||||||
@@ -926,20 +926,32 @@ void LLVOVolume::sculpt()
|
|||||||
if (discard_level > max_discard)
|
if (discard_level > max_discard)
|
||||||
discard_level = max_discard; // clamp to the best we can do
|
discard_level = max_discard; // clamp to the best we can do
|
||||||
|
|
||||||
S32 current_discard = getVolume()->getSculptLevel();
|
S32 current_discard = getVolume()->getSculptLevel() ;
|
||||||
if(current_discard < -2)
|
if(current_discard < -2)
|
||||||
{
|
{
|
||||||
llwarns << "WARNING!!: Current discard of sculpty at " << current_discard
|
static S32 low_sculpty_discard_warning_count = 100;
|
||||||
<< " is less than -2." << llendl;
|
if (++low_sculpty_discard_warning_count >= 100)
|
||||||
|
{ // Log first time, then every 100 afterwards otherwise this can flood the logs
|
||||||
|
llwarns << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID()
|
||||||
|
<< " at " << current_discard
|
||||||
|
<< " is less than -2." << llendl;
|
||||||
|
low_sculpty_discard_warning_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// corrupted volume... don't update the sculpty
|
// corrupted volume... don't update the sculpty
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (current_discard > MAX_DISCARD_LEVEL)
|
else if (current_discard > MAX_DISCARD_LEVEL)
|
||||||
{
|
{
|
||||||
llwarns << "WARNING!!: Current discard of sculpty at " << current_discard
|
static S32 high_sculpty_discard_warning_count = 100;
|
||||||
<< " is more than than allowed max of " << MAX_DISCARD_LEVEL << llendl;
|
if (++high_sculpty_discard_warning_count >= 100)
|
||||||
|
{ // Log first time, then every 100 afterwards otherwise this can flood the logs
|
||||||
|
llwarns << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID()
|
||||||
|
<< " at " << current_discard
|
||||||
|
<< " is more than than allowed max of " << MAX_DISCARD_LEVEL << llendl;
|
||||||
|
high_sculpty_discard_warning_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// corrupted volume... don't update the sculpty
|
// corrupted volume... don't update the sculpty
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -489,7 +489,10 @@ void LLPipeline::init()
|
|||||||
//gSavedSettings.getControl("RenderDelayVBUpdate")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
|
//gSavedSettings.getControl("RenderDelayVBUpdate")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
|
||||||
gSavedSettings.getControl("UseOcclusion")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
|
gSavedSettings.getControl("UseOcclusion")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
|
||||||
gSavedSettings.getControl("VertexShaderEnable")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
|
gSavedSettings.getControl("VertexShaderEnable")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
|
||||||
|
gSavedSettings.getControl("RenderDeferred")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
|
||||||
gSavedSettings.getControl("RenderFSAASamples")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
|
gSavedSettings.getControl("RenderFSAASamples")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
|
||||||
|
gSavedSettings.getControl("RenderAvatarVP")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
|
||||||
|
gSavedSettings.getControl("WindLightUseAtmosShaders")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
|
||||||
}
|
}
|
||||||
|
|
||||||
LLPipeline::~LLPipeline()
|
LLPipeline::~LLPipeline()
|
||||||
@@ -631,7 +634,16 @@ void LLPipeline::resizeScreenTexture()
|
|||||||
GLuint resX = gViewerWindow->getWorldViewWidthRaw();
|
GLuint resX = gViewerWindow->getWorldViewWidthRaw();
|
||||||
GLuint resY = gViewerWindow->getWorldViewHeightRaw();
|
GLuint resY = gViewerWindow->getWorldViewHeightRaw();
|
||||||
|
|
||||||
allocateScreenBuffer(resX,resY);
|
if (!allocateScreenBuffer(resX,resY))
|
||||||
|
{ //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled
|
||||||
|
//NOTE: if the session closes successfully after this call, deferred rendering will be
|
||||||
|
// disabled on future sessions
|
||||||
|
if (LLPipeline::sRenderDeferred)
|
||||||
|
{
|
||||||
|
gSavedSettings.setBOOL("RenderDeferred", FALSE);
|
||||||
|
LLPipeline::refreshCachedSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -902,6 +914,8 @@ void LLPipeline::refreshCachedSettings()
|
|||||||
&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion")
|
&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion")
|
||||||
&& gSavedSettings.getBOOL("UseOcclusion")
|
&& gSavedSettings.getBOOL("UseOcclusion")
|
||||||
&& gGLManager.mHasOcclusionQuery) ? 2 : 0;
|
&& gGLManager.mHasOcclusionQuery) ? 2 : 0;
|
||||||
|
|
||||||
|
updateRenderDeferred();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLPipeline::releaseGLBuffers()
|
void LLPipeline::releaseGLBuffers()
|
||||||
@@ -5412,7 +5426,6 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
|
|||||||
if (light->isLightSpotlight() // directional (spot-)light
|
if (light->isLightSpotlight() // directional (spot-)light
|
||||||
&& (LLPipeline::sRenderDeferred || RenderSpotLightsInNondeferred)) // these are only rendered as GL spotlights if we're in deferred rendering mode *or* the setting forces them on
|
&& (LLPipeline::sRenderDeferred || RenderSpotLightsInNondeferred)) // these are only rendered as GL spotlights if we're in deferred rendering mode *or* the setting forces them on
|
||||||
{
|
{
|
||||||
LLVector3 spotparams = light->getSpotLightParams();
|
|
||||||
LLQuaternion quat = light->getRenderRotation();
|
LLQuaternion quat = light->getRenderRotation();
|
||||||
LLVector3 at_axis(0,0,-1); // this matches deferred rendering's object light direction
|
LLVector3 at_axis(0,0,-1); // this matches deferred rendering's object light direction
|
||||||
at_axis *= quat;
|
at_axis *= quat;
|
||||||
@@ -5460,7 +5473,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
|
|||||||
|
|
||||||
F32 light_radius = 16.f;
|
F32 light_radius = 16.f;
|
||||||
|
|
||||||
F32 x = 3.f;
|
F32 x = 3.f;
|
||||||
float linatten = x / (light_radius); // % of brightness at radius
|
float linatten = x / (light_radius); // % of brightness at radius
|
||||||
|
|
||||||
mHWLightColors[2] = light_color;
|
mHWLightColors[2] = light_color;
|
||||||
@@ -5624,7 +5637,7 @@ void LLPipeline::enableLightsPreview()
|
|||||||
|
|
||||||
LLVector4 light_pos(dir0, 0.0f);
|
LLVector4 light_pos(dir0, 0.0f);
|
||||||
|
|
||||||
LLLightState* light = gGL.getLight(0);
|
LLLightState* light = gGL.getLight(1);
|
||||||
|
|
||||||
light->enable();
|
light->enable();
|
||||||
light->setPosition(light_pos);
|
light->setPosition(light_pos);
|
||||||
@@ -5636,7 +5649,7 @@ void LLPipeline::enableLightsPreview()
|
|||||||
|
|
||||||
light_pos = LLVector4(dir1, 0.f);
|
light_pos = LLVector4(dir1, 0.f);
|
||||||
|
|
||||||
light = gGL.getLight(1);
|
light = gGL.getLight(2);
|
||||||
light->enable();
|
light->enable();
|
||||||
light->setPosition(light_pos);
|
light->setPosition(light_pos);
|
||||||
light->setDiffuse(diffuse1);
|
light->setDiffuse(diffuse1);
|
||||||
@@ -5646,7 +5659,7 @@ void LLPipeline::enableLightsPreview()
|
|||||||
light->setSpotCutoff(180.f);
|
light->setSpotCutoff(180.f);
|
||||||
|
|
||||||
light_pos = LLVector4(dir2, 0.f);
|
light_pos = LLVector4(dir2, 0.f);
|
||||||
light = gGL.getLight(2);
|
light = gGL.getLight(3);
|
||||||
light->enable();
|
light->enable();
|
||||||
light->setPosition(light_pos);
|
light->setPosition(light_pos);
|
||||||
light->setDiffuse(diffuse2);
|
light->setDiffuse(diffuse2);
|
||||||
|
|||||||
@@ -35,6 +35,9 @@
|
|||||||
<on_click function="Object.DERENDER" />
|
<on_click function="Object.DERENDER" />
|
||||||
<on_enable function="Object.EnableDerender" />
|
<on_enable function="Object.EnableDerender" />
|
||||||
</menu_item_call>
|
</menu_item_call>
|
||||||
|
<menu_item_call enabled="true" label="Reload" mouse_opaque="true" name="Reload Textures">
|
||||||
|
<on_click function="Object.ReloadTextures" />
|
||||||
|
</menu_item_call>
|
||||||
</pie_menu>
|
</pie_menu>
|
||||||
<menu_item_call enabled="true" label="Appearance..." name="Appearance...">
|
<menu_item_call enabled="true" label="Appearance..." name="Appearance...">
|
||||||
<on_click function="ShowFloater" userdata="appearance" />
|
<on_click function="ShowFloater" userdata="appearance" />
|
||||||
|
|||||||
@@ -14,11 +14,11 @@
|
|||||||
</panel>
|
</panel>
|
||||||
<panel border="true" left="1" bottom="-190" height="180" width="500" label="Tags/Colors" name="TagsColors">
|
<panel border="true" left="1" bottom="-190" height="180" width="500" label="Tags/Colors" name="TagsColors">
|
||||||
<!-- Client tag options -->
|
<!-- Client tag options -->
|
||||||
<check_box bottom_delta="-25" control_name="AscentUseTag" follows="top" height="16" initial_value="true" label="Use Client Tag:" left="10" tool_tip="Enabling this will show your client tag on your avatar name locally." name="show_my_tag_check"/>
|
<check_box bottom_delta="-25" control_name="AscentBroadcastTag" follows="top" height="16" initial_value="true" label="Broadcast Client Tag:" left="10" tool_tip="Choose whether others see that you enjoy Singularity." name="show_my_tag_check"/>
|
||||||
<combo_box follows="top" bottom_delta="-24" height="18" left_delta="24" max_chars="32" tool_tip="The client tag (And subsequent color) to broadcast. Overridden locally by Custom Tag/Color." name="tag_spoofing_combobox" width="130">
|
<combo_box follows="top" bottom_delta="-24" height="18" left_delta="24" max_chars="32" tool_tip="The client tag (And subsequent color) to broadcast. Overridden locally by Custom Tag/Color." name="tag_spoofing_combobox" width="130">
|
||||||
<combo_item name="Singularity" value="f25263b7-6167-4f34-a4ef-af65213b2e39">Singularity</combo_item>
|
<combo_item name="Singularity" value="f25263b7-6167-4f34-a4ef-af65213b2e39">Singularity</combo_item>
|
||||||
</combo_box>
|
</combo_box>
|
||||||
<check_box bottom_delta="-23" control_name="AscentShowSelfTag" follows="top" height="16" initial_value="true" label="Display client tag to self" left_delta="-24" tool_tip="Choose whether others see that you enjoy Singularity." name="show_self_tag_check"/>
|
<check_box bottom_delta="-23" control_name="AscentShowSelfTag" follows="top" height="16" initial_value="true" label="Display client tag to self" left_delta="-24" tool_tip="Enabling this will show your client tag on your avatar name locally." name="show_self_tag_check"/>
|
||||||
<check_box bottom_delta="-20" control_name="AscentShowSelfTagColor" follows="top" height="16" initial_value="true" label="Display client tag color to self" tool_tip="Enabling this set your avatar name color to your client tag color or custom set color." name="show_self_tag_color_check"/>
|
<check_box bottom_delta="-20" control_name="AscentShowSelfTagColor" follows="top" height="16" initial_value="true" label="Display client tag color to self" tool_tip="Enabling this set your avatar name color to your client tag color or custom set color." name="show_self_tag_color_check"/>
|
||||||
<check_box bottom_delta="-20" control_name="AscentShowFriendsTag" follows="top" height="16" initial_value="true" label="Display friend client tags as (Friend)" tool_tip="Enabling this changes your friends' client tags to (Friend)." name="show_friend_tag_check"/>
|
<check_box bottom_delta="-20" control_name="AscentShowFriendsTag" follows="top" height="16" initial_value="true" label="Display friend client tags as (Friend)" tool_tip="Enabling this changes your friends' client tags to (Friend)." name="show_friend_tag_check"/>
|
||||||
<!-- End of Left Side -->
|
<!-- End of Left Side -->
|
||||||
|
|||||||
@@ -1908,7 +1908,7 @@ Requests that a nonphysical object be keyframed according to keyframe list.
|
|||||||
</string>
|
</string>
|
||||||
<string name="LSLTipText_llTransferLindenDollars">
|
<string name="LSLTipText_llTransferLindenDollars">
|
||||||
key llTransferLindenDollars(key destination, integer amount)
|
key llTransferLindenDollars(key destination, integer amount)
|
||||||
Transfer amount of linden dollars (L$) from script owner to destination. Returns a key to a corresponding transaction_result event for the success of the transfer.
|
Transfer amount of linden dollars ([CURRENCY]) from script owner to destination. Returns a key to a corresponding transaction_result event for the success of the transfer.
|
||||||
</string>
|
</string>
|
||||||
<string name="LSLTipText_llGetParcelMusicURL">
|
<string name="LSLTipText_llGetParcelMusicURL">
|
||||||
string llGetParcelMusicURL()
|
string llGetParcelMusicURL()
|
||||||
@@ -4005,16 +4005,16 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
|
|||||||
<string name="Home position set.">Home position set.</string>
|
<string name="Home position set.">Home position set.</string>
|
||||||
|
|
||||||
<!-- Financial operations strings -->
|
<!-- Financial operations strings -->
|
||||||
<string name="paid_you_ldollars">[NAME] paid you L$[AMOUNT] [REASON].</string>
|
<string name="paid_you_ldollars">[NAME] paid you [CURRENCY][AMOUNT] [REASON].</string>
|
||||||
<string name="paid_you_ldollars_no_reason">[NAME] paid you L$[AMOUNT].</string>
|
<string name="paid_you_ldollars_no_reason">[NAME] paid you [CURRENCY][AMOUNT].</string>
|
||||||
<string name="you_paid_ldollars">You paid [NAME] L$[AMOUNT] [REASON].</string>
|
<string name="you_paid_ldollars">You paid [NAME] [CURRENCY][AMOUNT] [REASON].</string>
|
||||||
<string name="you_paid_ldollars_no_info">You paid L$[AMOUNT].</string>
|
<string name="you_paid_ldollars_no_info">You paid [CURRENCY][AMOUNT].</string>
|
||||||
<string name="you_paid_ldollars_no_reason">You paid [NAME] L$[AMOUNT].</string>
|
<string name="you_paid_ldollars_no_reason">You paid [NAME] [CURRENCY][AMOUNT].</string>
|
||||||
<string name="you_paid_ldollars_no_name">You paid L$[AMOUNT] [REASON].</string>
|
<string name="you_paid_ldollars_no_name">You paid [CURRENCY][AMOUNT] [REASON].</string>
|
||||||
<string name="you_paid_failure_ldollars">You failed to pay [NAME] L$[AMOUNT] [REASON].</string>
|
<string name="you_paid_failure_ldollars">You failed to pay [NAME] [CURRENCY][AMOUNT] [REASON].</string>
|
||||||
<string name="you_paid_failure_ldollars_no_info">You failed to pay L$[AMOUNT].</string>
|
<string name="you_paid_failure_ldollars_no_info">You failed to pay [CURRENCY][AMOUNT].</string>
|
||||||
<string name="you_paid_failure_ldollars_no_reason">You failed to pay [NAME] L$[AMOUNT].</string>
|
<string name="you_paid_failure_ldollars_no_reason">You failed to pay [NAME] [CURRENCY][AMOUNT].</string>
|
||||||
<string name="you_paid_failure_ldollars_no_name">You failed to pay L$[AMOUNT] [REASON].</string>
|
<string name="you_paid_failure_ldollars_no_name">You failed to pay [CURRENCY][AMOUNT] [REASON].</string>
|
||||||
<string name="for item">for [ITEM]</string>
|
<string name="for item">for [ITEM]</string>
|
||||||
<string name="for a parcel of land">for a parcel of land</string>
|
<string name="for a parcel of land">for a parcel of land</string>
|
||||||
<string name="for a land access pass">for a land access pass</string>
|
<string name="for a land access pass">for a land access pass</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user