Pull and merge from ssh://hg@bitbucket.org/lindenlab/viewer-drtvwr-365.

master
Stinson Linden 2014-06-02 22:32:16 +01:00
commit 8392fde6f6
78 changed files with 1093 additions and 606 deletions

View File

@ -152,19 +152,31 @@ void LLDriverParamInfo::toStream(std::ostream &out)
// LLDriverParam
//-----------------------------------------------------------------------------
LLDriverParam::LLDriverParam(LLAvatarAppearance *appearance, LLWearable* wearable /* = NULL */) :
LLDriverParam::LLDriverParam(LLAvatarAppearance *appearance, LLWearable* wearable /* = NULL */)
: LLViewerVisualParam(),
mDefaultVec(),
mDriven(),
mCurrentDistortionParam( NULL ),
mAvatarAppearance(appearance),
mWearablep(wearable)
{
llassert(mAvatarAppearance);
if (mWearablep)
{
llassert(mAvatarAppearance->isSelf());
}
llassert((mWearablep == NULL) || mAvatarAppearance->isSelf());
mDefaultVec.clear();
}
LLDriverParam::LLDriverParam(const LLDriverParam& pOther)
: LLViewerVisualParam(pOther),
mDefaultVec(pOther.mDefaultVec),
mDriven(pOther.mDriven),
mCurrentDistortionParam(pOther.mCurrentDistortionParam),
mAvatarAppearance(pOther.mAvatarAppearance),
mWearablep(pOther.mWearablep)
{
llassert(mAvatarAppearance);
llassert((mWearablep == NULL) || mAvatarAppearance->isSelf());
}
LLDriverParam::~LLDriverParam()
{
}
@ -186,13 +198,7 @@ BOOL LLDriverParam::setInfo(LLDriverParamInfo *info)
/*virtual*/ LLViewerVisualParam* LLDriverParam::cloneParam(LLWearable* wearable) const
{
llassert(wearable);
LLDriverParam *new_param = new LLDriverParam(mAvatarAppearance, wearable);
// FIXME DRANO this clobbers mWearablep, which means any code
// currently using mWearablep is wrong, or at least untested.
*new_param = *this;
//new_param->mWearablep = wearable;
// new_param->mDriven.clear(); // clear driven list to avoid overwriting avatar driven params from wearables.
return new_param;
return new LLDriverParam(*this);
}
void LLDriverParam::setWeight(F32 weight)

View File

@ -129,6 +129,7 @@ public:
const LLViewerVisualParam* getDrivenParam(S32 index) const;
protected:
LLDriverParam(const LLDriverParam& pOther);
F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight);
void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight);

View File

@ -315,10 +315,27 @@ BOOL LLPolyMorphTargetInfo::parseXml(LLXmlTreeNode* node)
// LLPolyMorphTarget()
//-----------------------------------------------------------------------------
LLPolyMorphTarget::LLPolyMorphTarget(LLPolyMesh *poly_mesh)
: mMorphData(NULL), mMesh(poly_mesh),
mVertMask(NULL),
mLastSex(SEX_FEMALE),
mNumMorphMasksPending(0)
: LLViewerVisualParam(),
mMorphData(NULL),
mMesh(poly_mesh),
mVertMask(NULL),
mLastSex(SEX_FEMALE),
mNumMorphMasksPending(0),
mVolumeMorphs()
{
}
//-----------------------------------------------------------------------------
// LLPolyMorphTarget()
//-----------------------------------------------------------------------------
LLPolyMorphTarget::LLPolyMorphTarget(const LLPolyMorphTarget& pOther)
: LLViewerVisualParam(pOther),
mMorphData(pOther.mMorphData),
mMesh(pOther.mMesh),
mVertMask(pOther.mVertMask == NULL ? NULL : new LLPolyVertexMask(*pOther.mVertMask)),
mLastSex(pOther.mLastSex),
mNumMorphMasksPending(pOther.mNumMorphMasksPending),
mVolumeMorphs(pOther.mVolumeMorphs)
{
}
@ -327,10 +344,8 @@ LLPolyMorphTarget::LLPolyMorphTarget(LLPolyMesh *poly_mesh)
//-----------------------------------------------------------------------------
LLPolyMorphTarget::~LLPolyMorphTarget()
{
if (mVertMask)
{
delete mVertMask;
}
delete mVertMask;
mVertMask = NULL;
}
//-----------------------------------------------------------------------------
@ -385,9 +400,7 @@ BOOL LLPolyMorphTarget::setInfo(LLPolyMorphTargetInfo* info)
/*virtual*/ LLViewerVisualParam* LLPolyMorphTarget::cloneParam(LLWearable* wearable) const
{
LLPolyMorphTarget *new_param = new LLPolyMorphTarget(mMesh);
*new_param = *this;
return new_param;
return new LLPolyMorphTarget(*this);
}
#if 0 // obsolete
@ -722,10 +735,25 @@ void LLPolyMorphTarget::applyMask(U8 *maskTextureData, S32 width, S32 height, S3
// LLPolyVertexMask()
//-----------------------------------------------------------------------------
LLPolyVertexMask::LLPolyVertexMask(LLPolyMorphData* morph_data)
: mWeights(new F32[morph_data->mNumIndices]),
mMorphData(morph_data),
mWeightsGenerated(FALSE)
{
mWeights = new F32[morph_data->mNumIndices];
mMorphData = morph_data;
mWeightsGenerated = FALSE;
llassert(mMorphData != NULL);
llassert(mMorphData->mNumIndices > 0);
}
//-----------------------------------------------------------------------------
// LLPolyVertexMask()
//-----------------------------------------------------------------------------
LLPolyVertexMask::LLPolyVertexMask(const LLPolyVertexMask& pOther)
: mWeights(new F32[pOther.mMorphData->mNumIndices]),
mMorphData(pOther.mMorphData),
mWeightsGenerated(pOther.mWeightsGenerated)
{
llassert(mMorphData != NULL);
llassert(mMorphData->mNumIndices > 0);
memcpy(mWeights, pOther.mWeights, sizeof(F32) * mMorphData->mNumIndices);
}
//-----------------------------------------------------------------------------
@ -733,7 +761,8 @@ LLPolyVertexMask::LLPolyVertexMask(LLPolyMorphData* morph_data)
//-----------------------------------------------------------------------------
LLPolyVertexMask::~LLPolyVertexMask()
{
delete[] mWeights;
delete [] mWeights;
mWeights = NULL;
}
//-----------------------------------------------------------------------------

View File

@ -91,6 +91,7 @@ class LLPolyVertexMask
{
public:
LLPolyVertexMask(LLPolyMorphData* morph_data);
LLPolyVertexMask(const LLPolyVertexMask& pOther);
~LLPolyVertexMask();
void generateMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4a *clothing_weights);
@ -182,6 +183,8 @@ public:
void addPendingMorphMask() { mNumMorphMasksPending++; }
protected:
LLPolyMorphTarget(const LLPolyMorphTarget& pOther);
LLPolyMorphData* mMorphData;
LLPolyMesh* mMesh;
LLPolyVertexMask * mVertMask;

View File

@ -104,9 +104,25 @@ BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node)
// LLPolySkeletalDistortion()
//-----------------------------------------------------------------------------
LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLAvatarAppearance *avatarp)
: LLViewerVisualParam(),
mDefaultVec(),
mJointScales(),
mJointOffsets(),
mAvatar(avatarp)
{
mDefaultVec.splat(0.001f);
}
//-----------------------------------------------------------------------------
// LLPolySkeletalDistortion()
//-----------------------------------------------------------------------------
LLPolySkeletalDistortion::LLPolySkeletalDistortion(const LLPolySkeletalDistortion &pOther)
: LLViewerVisualParam(pOther),
mDefaultVec(pOther.mDefaultVec),
mJointScales(pOther.mJointScales),
mJointOffsets(pOther.mJointOffsets),
mAvatar(pOther.mAvatar)
{
mAvatar = avatarp;
mDefaultVec.splat(0.001f);
}
//-----------------------------------------------------------------------------
@ -171,9 +187,7 @@ BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)
/*virtual*/ LLViewerVisualParam* LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const
{
LLPolySkeletalDistortion *new_param = new LLPolySkeletalDistortion(mAvatar);
*new_param = *this;
return new_param;
return new LLPolySkeletalDistortion(*this);
}
//-----------------------------------------------------------------------------

View File

@ -118,6 +118,8 @@ public:
/*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;};
protected:
LLPolySkeletalDistortion(const LLPolySkeletalDistortion& pOther);
LL_ALIGN_16(LLVector4a mDefaultVec);
typedef std::map<LLJoint*, LLVector3> joint_vec_map_t;
joint_vec_map_t mJointScales;

View File

@ -90,17 +90,31 @@ const std::string& LLTexGlobalColor::getName() const
//-----------------------------------------------------------------------------
// LLTexParamGlobalColor
//-----------------------------------------------------------------------------
LLTexParamGlobalColor::LLTexParamGlobalColor(LLTexGlobalColor* tex_global_color) :
LLTexLayerParamColor(tex_global_color->getAvatarAppearance()),
LLTexParamGlobalColor::LLTexParamGlobalColor(LLTexGlobalColor* tex_global_color)
: LLTexLayerParamColor(tex_global_color->getAvatarAppearance()),
mTexGlobalColor(tex_global_color)
{
}
//-----------------------------------------------------------------------------
// LLTexParamGlobalColor
//-----------------------------------------------------------------------------
LLTexParamGlobalColor::LLTexParamGlobalColor(const LLTexParamGlobalColor& pOther)
: LLTexLayerParamColor(pOther),
mTexGlobalColor(pOther.mTexGlobalColor)
{
}
//-----------------------------------------------------------------------------
// ~LLTexParamGlobalColor
//-----------------------------------------------------------------------------
LLTexParamGlobalColor::~LLTexParamGlobalColor()
{
}
/*virtual*/ LLViewerVisualParam* LLTexParamGlobalColor::cloneParam(LLWearable* wearable) const
{
LLTexParamGlobalColor *new_param = new LLTexParamGlobalColor(mTexGlobalColor);
*new_param = *this;
return new_param;
return new LLTexParamGlobalColor(*this);
}
void LLTexParamGlobalColor::onGlobalColorChanged()

View File

@ -73,8 +73,10 @@ class LLTexParamGlobalColor : public LLTexLayerParamColor
{
public:
LLTexParamGlobalColor(LLTexGlobalColor *tex_color);
virtual ~LLTexParamGlobalColor();
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
protected:
LLTexParamGlobalColor(const LLTexParamGlobalColor& pOther);
/*virtual*/ void onGlobalColorChanged();
private:
LLTexGlobalColor* mTexGlobalColor;

View File

@ -40,7 +40,8 @@
//-----------------------------------------------------------------------------
// LLTexLayerParam
//-----------------------------------------------------------------------------
LLTexLayerParam::LLTexLayerParam(LLTexLayerInterface *layer) :
LLTexLayerParam::LLTexLayerParam(LLTexLayerInterface *layer)
: LLViewerVisualParam(),
mTexLayer(layer),
mAvatarAppearance(NULL)
{
@ -54,12 +55,19 @@ LLTexLayerParam::LLTexLayerParam(LLTexLayerInterface *layer) :
}
}
LLTexLayerParam::LLTexLayerParam(LLAvatarAppearance *appearance) :
LLTexLayerParam::LLTexLayerParam(LLAvatarAppearance *appearance)
: LLViewerVisualParam(),
mTexLayer(NULL),
mAvatarAppearance(appearance)
{
}
LLTexLayerParam::LLTexLayerParam(const LLTexLayerParam& pOther)
: LLViewerVisualParam(pOther),
mTexLayer(pOther.mTexLayer),
mAvatarAppearance(pOther.mAvatarAppearance)
{
}
BOOL LLTexLayerParam::setInfo(LLViewerVisualParamInfo *info, BOOL add_to_appearance)
{
@ -112,9 +120,11 @@ void LLTexLayerParamAlpha::getCacheByteCount(S32* gl_bytes)
}
}
LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLTexLayerInterface* layer) :
LLTexLayerParam(layer),
LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLTexLayerInterface* layer)
: LLTexLayerParam(layer),
mCachedProcessedTexture(NULL),
mStaticImageTGA(),
mStaticImageRaw(),
mNeedsCreateTexture(FALSE),
mStaticImageInvalid(FALSE),
mAvgDistortionVec(1.f, 1.f, 1.f),
@ -123,9 +133,11 @@ LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLTexLayerInterface* layer) :
sInstances.push_front(this);
}
LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLAvatarAppearance* appearance) :
LLTexLayerParam(appearance),
LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLAvatarAppearance* appearance)
: LLTexLayerParam(appearance),
mCachedProcessedTexture(NULL),
mStaticImageTGA(),
mStaticImageRaw(),
mNeedsCreateTexture(FALSE),
mStaticImageInvalid(FALSE),
mAvgDistortionVec(1.f, 1.f, 1.f),
@ -134,6 +146,18 @@ LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLAvatarAppearance* appearance) :
sInstances.push_front(this);
}
LLTexLayerParamAlpha::LLTexLayerParamAlpha(const LLTexLayerParamAlpha& pOther)
: LLTexLayerParam(pOther),
mCachedProcessedTexture(pOther.mCachedProcessedTexture),
mStaticImageTGA(pOther.mStaticImageTGA),
mStaticImageRaw(pOther.mStaticImageRaw),
mNeedsCreateTexture(pOther.mNeedsCreateTexture),
mStaticImageInvalid(pOther.mStaticImageInvalid),
mAvgDistortionVec(pOther.mAvgDistortionVec),
mCachedEffectiveWeight(pOther.mCachedEffectiveWeight)
{
sInstances.push_front(this);
}
LLTexLayerParamAlpha::~LLTexLayerParamAlpha()
{
@ -143,9 +167,7 @@ LLTexLayerParamAlpha::~LLTexLayerParamAlpha()
/*virtual*/ LLViewerVisualParam* LLTexLayerParamAlpha::cloneParam(LLWearable* wearable) const
{
LLTexLayerParamAlpha *new_param = new LLTexLayerParamAlpha(mTexLayer);
*new_param = *this;
return new_param;
return new LLTexLayerParamAlpha(*this);
}
void LLTexLayerParamAlpha::deleteCaches()
@ -399,27 +421,31 @@ BOOL LLTexLayerParamAlphaInfo::parseXml(LLXmlTreeNode* node)
LLTexLayerParamColor::LLTexLayerParamColor(LLTexLayerInterface* layer) :
LLTexLayerParam(layer),
LLTexLayerParamColor::LLTexLayerParamColor(LLTexLayerInterface* layer)
: LLTexLayerParam(layer),
mAvgDistortionVec(1.f, 1.f, 1.f)
{
}
LLTexLayerParamColor::LLTexLayerParamColor(LLAvatarAppearance *appearance) :
LLTexLayerParam(appearance),
LLTexLayerParamColor::LLTexLayerParamColor(LLAvatarAppearance *appearance)
: LLTexLayerParam(appearance),
mAvgDistortionVec(1.f, 1.f, 1.f)
{
}
LLTexLayerParamColor::LLTexLayerParamColor(const LLTexLayerParamColor& pOther)
: LLTexLayerParam(pOther),
mAvgDistortionVec(pOther.mAvgDistortionVec)
{
}
LLTexLayerParamColor::~LLTexLayerParamColor()
{
}
/*virtual*/ LLViewerVisualParam* LLTexLayerParamColor::cloneParam(LLWearable* wearable) const
{
LLTexLayerParamColor *new_param = new LLTexLayerParamColor(mTexLayer);
*new_param = *this;
return new_param;
return new LLTexLayerParamColor(*this);
}
LLColor4 LLTexLayerParamColor::getNetColor() const

View File

@ -52,6 +52,8 @@ public:
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const = 0;
protected:
LLTexLayerParam(const LLTexLayerParam& pOther);
LLTexLayerInterface* mTexLayer;
LLAvatarAppearance* mAvatarAppearance;
};
@ -102,6 +104,8 @@ public:
BOOL getMultiplyBlend() const;
private:
LLTexLayerParamAlpha(const LLTexLayerParamAlpha& pOther);
LLPointer<LLGLTexture> mCachedProcessedTexture;
LLPointer<LLImageTGA> mStaticImageTGA;
LLPointer<LLImageRaw> mStaticImageRaw;
@ -190,6 +194,8 @@ public:
// New functions
LLColor4 getNetColor() const;
protected:
LLTexLayerParamColor(const LLTexLayerParamColor& pOther);
virtual void onGlobalColorChanged() {}
private:
LL_ALIGN_16(LLVector4a mAvgDistortionVec);

View File

@ -123,6 +123,22 @@ BOOL LLViewerVisualParamInfo::parseXml(LLXmlTreeNode *node)
// LLViewerVisualParam()
//-----------------------------------------------------------------------------
LLViewerVisualParam::LLViewerVisualParam()
: LLVisualParam()
{
}
//-----------------------------------------------------------------------------
// LLViewerVisualParam()
//-----------------------------------------------------------------------------
LLViewerVisualParam::LLViewerVisualParam(const LLViewerVisualParam& pOther)
: LLVisualParam(pOther)
{
}
//-----------------------------------------------------------------------------
// ~LLViewerVisualParam()
//-----------------------------------------------------------------------------
LLViewerVisualParam::~LLViewerVisualParam()
{
}

View File

@ -70,7 +70,7 @@ class LLViewerVisualParam : public LLVisualParam
{
public:
LLViewerVisualParam();
/*virtual*/ ~LLViewerVisualParam(){};
virtual ~LLViewerVisualParam();
// Special: These functions are overridden by child classes
LLViewerVisualParamInfo *getInfo() const { return (LLViewerVisualParamInfo*)mInfo; };
@ -105,6 +105,8 @@ public:
BOOL getCrossWearable() const { return getInfo()->mCrossWearable; }
protected:
LLViewerVisualParam(const LLViewerVisualParam& pOther);
} LL_ALIGN_POSTFIX(16);
#endif // LL_LLViewerVisualParam_H

View File

@ -43,9 +43,32 @@ S32 LLWearable::sCurrentDefinitionVersion = 1;
// Private local functions
static std::string terse_F32_to_string(F32 f);
LLWearable::LLWearable()
: mDefinitionVersion(-1),
mName(),
mDescription(),
mPermissions(),
mSaleInfo(),
mType(LLWearableType::WT_NONE),
mSavedVisualParamMap(),
mVisualParamIndexMap(),
mTEMap(),
mSavedTEMap()
{
}
// virtual
LLWearable::~LLWearable()
{
for (visual_param_index_map_t::iterator vpIter = mVisualParamIndexMap.begin(); vpIter != mVisualParamIndexMap.end(); ++vpIter)
{
LLVisualParam* vp = vpIter->second;
vp->clearNextParam();
delete vp;
vpIter->second = NULL;
}
destroyTextures();
}
const std::string& LLWearable::getTypeLabel() const
@ -620,17 +643,10 @@ void LLWearable::syncImages(te_map_t &src, te_map_t &dst)
void LLWearable::destroyTextures()
{
for( te_map_t::iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter )
{
LLLocalTextureObject *lto = iter->second;
delete lto;
}
std::for_each(mTEMap.begin(), mTEMap.end(), DeletePairedPointer());
mTEMap.clear();
for( te_map_t::iterator iter = mSavedTEMap.begin(); iter != mSavedTEMap.end(); ++iter )
{
LLLocalTextureObject *lto = iter->second;
delete lto;
}
std::for_each(mSavedTEMap.begin(), mSavedTEMap.end(), DeletePairedPointer());
mSavedTEMap.clear();
}

View File

@ -46,6 +46,7 @@ class LLWearable
// Constructors and destructors
//--------------------------------------------------------------------
public:
LLWearable();
virtual ~LLWearable();
//--------------------------------------------------------------------

View File

@ -172,6 +172,13 @@ void LLMotionController::deleteAllMotions()
for_each(mAllMotions.begin(), mAllMotions.end(), DeletePairedPointer());
mAllMotions.clear();
// stinson 05/12/20014 : Ownership of the LLMotion pointers is transferred from
// mAllMotions to mDeprecatedMotions in method
// LLMotionController::deprecateMotionInstance(). Thus, we should also clean
// up the mDeprecatedMotions list as well.
for_each(mDeprecatedMotions.begin(), mDeprecatedMotions.end(), DeletePointer());
mDeprecatedMotions.clear();
}
//-----------------------------------------------------------------------------

View File

@ -159,26 +159,42 @@ void LLVisualParamInfo::toStream(std::ostream &out)
//-----------------------------------------------------------------------------
// LLVisualParam()
//-----------------------------------------------------------------------------
LLVisualParam::LLVisualParam()
:
mCurWeight( 0.f ),
LLVisualParam::LLVisualParam()
: mCurWeight( 0.f ),
mLastWeight( 0.f ),
mNext( NULL ),
mTargetWeight( 0.f ),
mIsAnimating( FALSE ),
mIsDummy(FALSE),
mID( -1 ),
mInfo( 0 ),
mIsDummy(FALSE),
mParamLocation(LOC_UNKNOWN)
{
}
//-----------------------------------------------------------------------------
// LLVisualParam()
//-----------------------------------------------------------------------------
LLVisualParam::LLVisualParam(const LLVisualParam& pOther)
: mCurWeight(pOther.mCurWeight),
mLastWeight(pOther.mLastWeight),
mNext(pOther.mNext),
mTargetWeight(pOther.mTargetWeight),
mIsAnimating(pOther.mIsAnimating),
mIsDummy(pOther.mIsDummy),
mID(pOther.mID),
mInfo(pOther.mInfo),
mParamLocation(pOther.mParamLocation)
{
}
//-----------------------------------------------------------------------------
// ~LLVisualParam()
//-----------------------------------------------------------------------------
LLVisualParam::~LLVisualParam()
{
delete mNext;
mNext = NULL;
}
/*
@ -284,6 +300,14 @@ void LLVisualParam::setNextParam( LLVisualParam *next )
mNext = next;
}
//-----------------------------------------------------------------------------
// clearNextParam()
//-----------------------------------------------------------------------------
void LLVisualParam::clearNextParam()
{
mNext = NULL;
}
//-----------------------------------------------------------------------------
// animate()
//-----------------------------------------------------------------------------

View File

@ -155,6 +155,7 @@ public:
LLVisualParam* getNextParam() { return mNext; }
void setNextParam( LLVisualParam *next );
void clearNextParam();
virtual void setAnimating(BOOL is_animating) { mIsAnimating = is_animating && !mIsDummy; }
BOOL getAnimating() const { return mIsAnimating; }
@ -165,6 +166,8 @@ public:
EParamLocation getParamLocation() const { return mParamLocation; }
protected:
LLVisualParam(const LLVisualParam& pOther);
F32 mCurWeight; // current weight
F32 mLastWeight; // last weight
LLVisualParam* mNext; // next param in a shared chain

View File

@ -47,6 +47,7 @@
#include "lllivefile.h"
#include "llsd.h"
#include "llsdserialize.h"
#include "llsingleton.h"
#include "llstl.h"
#include "lltimer.h"
@ -356,30 +357,31 @@ namespace
typedef std::map<std::string, LLError::ELevel> LevelMap;
typedef std::vector<LLError::Recorder*> Recorders;
typedef std::vector<LLError::RecorderPtr> Recorders;
typedef std::vector<LLError::CallSite*> CallSiteVector;
class Globals
class Globals : public LLSingleton<Globals>
{
public:
Globals();
std::ostringstream messageStream;
bool messageStreamInUse;
void addCallSite(LLError::CallSite&);
void invalidateCallSites();
static Globals& get();
// return the one instance of the globals
private:
CallSiteVector callSites;
Globals()
: messageStreamInUse(false)
{ }
};
Globals::Globals()
: messageStream(),
messageStreamInUse(false),
callSites()
{
}
void Globals::addCallSite(LLError::CallSite& site)
{
callSites.push_back(&site);
@ -396,25 +398,17 @@ namespace
callSites.clear();
}
Globals& Globals::get()
{
/* This pattern, of returning a reference to a static function
variable, is to ensure that this global is constructed before
it is used, no matter what the global initialization sequence
is.
See C++ FAQ Lite, sections 10.12 through 10.14
*/
static Globals* globals = new Globals;
return *globals;
}
}
namespace LLError
{
class Settings
class SettingsConfig : public LLRefCount
{
friend class Settings;
public:
virtual ~SettingsConfig();
bool mPrintLocation;
LLError::ELevel mDefaultLevel;
@ -429,81 +423,86 @@ namespace LLError
LLError::TimeFunction mTimeFunction;
Recorders mRecorders;
Recorder* mFileRecorder;
Recorder* mFixedBufferRecorder;
RecorderPtr mFileRecorder;
RecorderPtr mFixedBufferRecorder;
std::string mFileRecorderFileName;
int mShouldLogCallCounter;
static Settings& get();
private:
SettingsConfig();
};
typedef LLPointer<SettingsConfig> SettingsConfigPtr;
class Settings : public LLSingleton<Settings>
{
public:
Settings();
SettingsConfigPtr getSettingsConfig();
static void reset();
static Settings* saveAndReset();
static void restore(Settings*);
void reset();
SettingsStoragePtr saveAndReset();
void restore(SettingsStoragePtr pSettingsStorage);
private:
Settings()
: mPrintLocation(false),
mDefaultLevel(LLError::LEVEL_DEBUG),
mCrashFunction(),
mTimeFunction(NULL),
mFileRecorder(NULL),
mFixedBufferRecorder(NULL),
mShouldLogCallCounter(0)
{ }
~Settings()
{
for_each(mRecorders.begin(), mRecorders.end(), DeletePointer());
mRecorders.clear();
}
static Settings*& getPtr();
SettingsConfigPtr mSettingsConfig;
};
Settings& Settings::get()
SettingsConfig::SettingsConfig()
: LLRefCount(),
mPrintLocation(false),
mDefaultLevel(LLError::LEVEL_DEBUG),
mFunctionLevelMap(),
mClassLevelMap(),
mFileLevelMap(),
mTagLevelMap(),
mUniqueLogMessages(),
mCrashFunction(NULL),
mTimeFunction(NULL),
mRecorders(),
mFileRecorder(),
mFixedBufferRecorder(),
mFileRecorderFileName(),
mShouldLogCallCounter(0)
{
Settings* p = getPtr();
if (!p)
{
reset();
p = getPtr();
}
return *p;
}
SettingsConfig::~SettingsConfig()
{
mRecorders.clear();
}
Settings::Settings()
: LLSingleton<Settings>(),
mSettingsConfig(new SettingsConfig())
{
}
SettingsConfigPtr Settings::getSettingsConfig()
{
return mSettingsConfig;
}
void Settings::reset()
{
Globals::get().invalidateCallSites();
Settings*& p = getPtr();
delete p;
p = new Settings();
Globals::getInstance()->invalidateCallSites();
mSettingsConfig = new SettingsConfig();
}
Settings* Settings::saveAndReset()
SettingsStoragePtr Settings::saveAndReset()
{
Globals::get().invalidateCallSites();
Settings*& p = getPtr();
Settings* originalSettings = p;
p = new Settings();
return originalSettings;
SettingsStoragePtr oldSettingsConfig(mSettingsConfig.get());
reset();
return oldSettingsConfig;
}
void Settings::restore(Settings* originalSettings)
void Settings::restore(SettingsStoragePtr pSettingsStorage)
{
Globals::get().invalidateCallSites();
Settings*& p = getPtr();
delete p;
p = originalSettings;
}
Settings*& Settings::getPtr()
{
static Settings* currentSettings = NULL;
return currentSettings;
Globals::getInstance()->invalidateCallSites();
SettingsConfigPtr newSettingsConfig(dynamic_cast<SettingsConfig *>(pSettingsStorage.get()));
mSettingsConfig = newSettingsConfig;
}
}
@ -604,7 +603,7 @@ namespace
void commonInit(const std::string& dir, bool log_to_stderr = true)
{
LLError::Settings::reset();
LLError::Settings::getInstance()->reset();
LLError::setDefaultLevel(LLError::LEVEL_INFO);
LLError::setFatalFunction(LLError::crashAndLoop);
@ -613,11 +612,13 @@ namespace
// log_to_stderr is only false in the unit and integration tests to keep builds quieter
if (log_to_stderr && shouldLogToStderr())
{
LLError::addRecorder(new RecordToStderr(stderrLogWantsTime()));
LLError::RecorderPtr recordToStdErr(new RecordToStderr(stderrLogWantsTime()));
LLError::addRecorder(recordToStdErr);
}
#if LL_WINDOWS
LLError::addRecorder(new RecordToWinDebug);
LLError::RecorderPtr recordToWinDebug(new RecordToWinDebug());
LLError::addRecorder(recordToWinDebug);
#endif
LogControlFile& e = LogControlFile::fromDirectory(dir);
@ -645,7 +646,8 @@ namespace LLError
}
commonInit(dir);
#if !LL_WINDOWS
addRecorder(new RecordToSyslog(identity));
LLError::RecorderPtr recordToSyslog(new RecordToSyslog(identity));
addRecorder(recordToSyslog);
#endif
}
@ -656,72 +658,67 @@ namespace LLError
void setPrintLocation(bool print)
{
Settings& s = Settings::get();
s.mPrintLocation = print;
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
s->mPrintLocation = print;
}
void setFatalFunction(const FatalFunction& f)
{
Settings& s = Settings::get();
s.mCrashFunction = f;
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
s->mCrashFunction = f;
}
FatalFunction getFatalFunction()
{
Settings& s = Settings::get();
return s.mCrashFunction;
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
return s->mCrashFunction;
}
void setTimeFunction(TimeFunction f)
{
Settings& s = Settings::get();
s.mTimeFunction = f;
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
s->mTimeFunction = f;
}
void setDefaultLevel(ELevel level)
{
Globals& g = Globals::get();
Settings& s = Settings::get();
g.invalidateCallSites();
s.mDefaultLevel = level;
Globals::getInstance()->invalidateCallSites();
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
s->mDefaultLevel = level;
}
ELevel getDefaultLevel()
{
Settings& s = Settings::get();
return s.mDefaultLevel;
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
return s->mDefaultLevel;
}
void setFunctionLevel(const std::string& function_name, ELevel level)
{
Globals& g = Globals::get();
Settings& s = Settings::get();
g.invalidateCallSites();
s.mFunctionLevelMap[function_name] = level;
Globals::getInstance()->invalidateCallSites();
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
s->mFunctionLevelMap[function_name] = level;
}
void setClassLevel(const std::string& class_name, ELevel level)
{
Globals& g = Globals::get();
Settings& s = Settings::get();
g.invalidateCallSites();
s.mClassLevelMap[class_name] = level;
Globals::getInstance()->invalidateCallSites();
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
s->mClassLevelMap[class_name] = level;
}
void setFileLevel(const std::string& file_name, ELevel level)
{
Globals& g = Globals::get();
Settings& s = Settings::get();
g.invalidateCallSites();
s.mFileLevelMap[file_name] = level;
Globals::getInstance()->invalidateCallSites();
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
s->mFileLevelMap[file_name] = level;
}
void setTagLevel(const std::string& tag_name, ELevel level)
{
Globals& g = Globals::get();
Settings& s = Settings::get();
g.invalidateCallSites();
s.mTagLevelMap[tag_name] = level;
Globals::getInstance()->invalidateCallSites();
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
s->mTagLevelMap[tag_name] = level;
}
LLError::ELevel decodeLevel(std::string name)
@ -765,15 +762,14 @@ namespace LLError
{
void configure(const LLSD& config)
{
Globals& g = Globals::get();
Settings& s = Settings::get();
Globals::getInstance()->invalidateCallSites();
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
g.invalidateCallSites();
s.mFunctionLevelMap.clear();
s.mClassLevelMap.clear();
s.mFileLevelMap.clear();
s.mTagLevelMap.clear();
s.mUniqueLogMessages.clear();
s->mFunctionLevelMap.clear();
s->mClassLevelMap.clear();
s->mFileLevelMap.clear();
s->mTagLevelMap.clear();
s->mUniqueLogMessages.clear();
setPrintLocation(config["print-location"]);
setDefaultLevel(decodeLevel(config["default-level"]));
@ -786,10 +782,10 @@ namespace LLError
ELevel level = decodeLevel(entry["level"]);
setLevels(s.mFunctionLevelMap, entry["functions"], level);
setLevels(s.mClassLevelMap, entry["classes"], level);
setLevels(s.mFileLevelMap, entry["files"], level);
setLevels(s.mTagLevelMap, entry["tags"], level);
setLevels(s->mFunctionLevelMap, entry["functions"], level);
setLevels(s->mClassLevelMap, entry["classes"], level);
setLevels(s->mFileLevelMap, entry["files"], level);
setLevels(s->mTagLevelMap, entry["tags"], level);
}
}
}
@ -803,10 +799,12 @@ namespace LLError
mWantsLevel(true),
mWantsLocation(false),
mWantsFunctionName(true)
{}
{
}
Recorder::~Recorder()
{ }
{
}
bool Recorder::wantsTime()
{
@ -837,25 +835,25 @@ namespace LLError
return mWantsFunctionName;
}
void addRecorder(Recorder* recorder)
void addRecorder(RecorderPtr recorder)
{
if (recorder == NULL)
if (!recorder)
{
return;
}
Settings& s = Settings::get();
s.mRecorders.push_back(recorder);
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
s->mRecorders.push_back(recorder);
}
void removeRecorder(Recorder* recorder)
void removeRecorder(RecorderPtr recorder)
{
if (recorder == NULL)
if (!recorder)
{
return;
}
Settings& s = Settings::get();
s.mRecorders.erase(std::remove(s.mRecorders.begin(), s.mRecorders.end(), recorder),
s.mRecorders.end());
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
s->mRecorders.erase(std::remove(s->mRecorders.begin(), s->mRecorders.end(), recorder),
s->mRecorders.end());
}
}
@ -863,51 +861,47 @@ namespace LLError
{
void logToFile(const std::string& file_name)
{
LLError::Settings& s = LLError::Settings::get();
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
removeRecorder(s.mFileRecorder);
delete s.mFileRecorder;
s.mFileRecorder = NULL;
s.mFileRecorderFileName.clear();
removeRecorder(s->mFileRecorder);
s->mFileRecorder.reset();
s->mFileRecorderFileName.clear();
if (file_name.empty())
{
return;
}
RecordToFile* f = new RecordToFile(file_name);
if (!f->okay())
RecorderPtr recordToFile(new RecordToFile(file_name));
if (boost::dynamic_pointer_cast<RecordToFile>(recordToFile)->okay())
{
delete f;
return;
s->mFileRecorderFileName = file_name;
s->mFileRecorder = recordToFile;
addRecorder(recordToFile);
}
s.mFileRecorderFileName = file_name;
s.mFileRecorder = f;
addRecorder(f);
}
void logToFixedBuffer(LLLineBuffer* fixedBuffer)
{
LLError::Settings& s = LLError::Settings::get();
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
removeRecorder(s.mFixedBufferRecorder);
delete s.mFixedBufferRecorder;
s.mFixedBufferRecorder = NULL;
removeRecorder(s->mFixedBufferRecorder);
s->mFixedBufferRecorder.reset();
if (!fixedBuffer)
{
return;
}
s.mFixedBufferRecorder = new RecordToFixedBuffer(fixedBuffer);
addRecorder(s.mFixedBufferRecorder);
RecorderPtr recordToFixedBuffer(new RecordToFixedBuffer(fixedBuffer));
s->mFixedBufferRecorder = recordToFixedBuffer;
addRecorder(recordToFixedBuffer);
}
std::string logFileName()
{
LLError::Settings& s = LLError::Settings::get();
return s.mFileRecorderFileName;
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
return s->mFileRecorderFileName;
}
}
@ -916,24 +910,24 @@ namespace
void writeToRecorders(const LLError::CallSite& site, const std::string& message, bool show_location = true, bool show_time = true, bool show_tags = true, bool show_level = true, bool show_function = true)
{
LLError::ELevel level = site.mLevel;
LLError::Settings& s = LLError::Settings::get();
LLError::SettingsConfigPtr s = LLError::Settings::getInstance()->getSettingsConfig();
for (Recorders::const_iterator i = s.mRecorders.begin();
i != s.mRecorders.end();
for (Recorders::const_iterator i = s->mRecorders.begin();
i != s->mRecorders.end();
++i)
{
LLError::Recorder* r = *i;
LLError::RecorderPtr r = *i;
std::ostringstream message_stream;
if (show_location && (r->wantsLocation() || level == LLError::LEVEL_ERROR || s.mPrintLocation))
if (show_location && (r->wantsLocation() || level == LLError::LEVEL_ERROR || s->mPrintLocation))
{
message_stream << site.mLocationString << " ";
}
if (show_time && r->wantsTime() && s.mTimeFunction != NULL)
if (show_time && r->wantsTime() && s->mTimeFunction != NULL)
{
message_stream << s.mTimeFunction() << " ";
message_stream << s->mTimeFunction() << " ";
}
if (show_level && r->wantsLevel())
@ -1060,10 +1054,9 @@ namespace LLError
return false;
}
Globals& g = Globals::get();
Settings& s = Settings::get();
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
s.mShouldLogCallCounter++;
s->mShouldLogCallCounter++;
const std::string& class_name = className(site.mClassInfo);
std::string function_name = functionName(site.mFunction);
@ -1077,21 +1070,21 @@ namespace LLError
function_name = class_name + "::" + function_name;
}
ELevel compareLevel = s.mDefaultLevel;
ELevel compareLevel = s->mDefaultLevel;
// The most specific match found will be used as the log level,
// since the computation short circuits.
// So, in increasing order of importance:
// Default < Tags < File < Class < Function
checkLevelMap(s.mFunctionLevelMap, function_name, compareLevel)
|| checkLevelMap(s.mClassLevelMap, class_name, compareLevel)
|| checkLevelMap(s.mFileLevelMap, abbreviateFile(site.mFile), compareLevel)
checkLevelMap(s->mFunctionLevelMap, function_name, compareLevel)
|| checkLevelMap(s->mClassLevelMap, class_name, compareLevel)
|| checkLevelMap(s->mFileLevelMap, abbreviateFile(site.mFile), compareLevel)
|| (site.mTagCount > 0
? checkLevelMap(s.mTagLevelMap, site.mTags, site.mTagCount, compareLevel)
? checkLevelMap(s->mTagLevelMap, site.mTags, site.mTagCount, compareLevel)
: false);
site.mCached = true;
g.addCallSite(site);
Globals::getInstance()->addCallSite(site);
return site.mShouldLog = site.mLevel >= compareLevel;
}
@ -1101,12 +1094,12 @@ namespace LLError
LogLock lock;
if (lock.ok())
{
Globals& g = Globals::get();
Globals* g = Globals::getInstance();
if (!g.messageStreamInUse)
if (!g->messageStreamInUse)
{
g.messageStreamInUse = true;
return &g.messageStream;
g->messageStreamInUse = true;
return &g->messageStream;
}
}
@ -1131,13 +1124,12 @@ namespace LLError
message[127] = '\0' ;
}
Globals& g = Globals::get();
if (out == &g.messageStream)
Globals* g = Globals::getInstance();
if (out == &g->messageStream)
{
g.messageStream.clear();
g.messageStream.str("");
g.messageStreamInUse = false;
g->messageStream.clear();
g->messageStream.str("");
g->messageStreamInUse = false;
}
else
{
@ -1154,15 +1146,15 @@ namespace LLError
return;
}
Globals& g = Globals::get();
Settings& s = Settings::get();
Globals* g = Globals::getInstance();
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
std::string message = out->str();
if (out == &g.messageStream)
if (out == &g->messageStream)
{
g.messageStream.clear();
g.messageStream.str("");
g.messageStreamInUse = false;
g->messageStream.clear();
g->messageStream.str("");
g->messageStreamInUse = false;
}
else
{
@ -1178,8 +1170,8 @@ namespace LLError
if (site.mPrintOnce)
{
std::map<std::string, unsigned int>::iterator messageIter = s.mUniqueLogMessages.find(message);
if (messageIter != s.mUniqueLogMessages.end())
std::map<std::string, unsigned int>::iterator messageIter = s->mUniqueLogMessages.find(message);
if (messageIter != s->mUniqueLogMessages.end())
{
messageIter->second++;
unsigned int num_messages = messageIter->second;
@ -1195,7 +1187,7 @@ namespace LLError
else
{
message_stream << "ONCE: ";
s.mUniqueLogMessages[message] = 1;
s->mUniqueLogMessages[message] = 1;
}
}
@ -1203,23 +1195,23 @@ namespace LLError
writeToRecorders(site, message_stream.str());
if (site.mLevel == LEVEL_ERROR && s.mCrashFunction)
if (site.mLevel == LEVEL_ERROR && s->mCrashFunction)
{
s.mCrashFunction(message_stream.str());
s->mCrashFunction(message_stream.str());
}
}
}
namespace LLError
{
Settings* saveAndResetSettings()
SettingsStoragePtr saveAndResetSettings()
{
return Settings::saveAndReset();
return Settings::getInstance()->saveAndReset();
}
void restoreSettings(Settings* s)
void restoreSettings(SettingsStoragePtr pSettingsStorage)
{
return Settings::restore(s);
return Settings::getInstance()->restore(pSettingsStorage);
}
std::string removePrefix(std::string& s, const std::string& p)
@ -1265,8 +1257,8 @@ namespace LLError
int shouldLogCallCount()
{
Settings& s = Settings::get();
return s.mShouldLogCallCounter;
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
return s->mShouldLogCallCounter;
}
#if LL_WINDOWS
@ -1375,15 +1367,9 @@ namespace LLError
#endif
//static
void LLCallStacks::push(const char* function, const int line)
void LLCallStacks::allocateStackBuffer()
{
CallStacksLogLock lock;
if (!lock.ok())
{
return;
}
if(!sBuffer)
if(sBuffer == NULL)
{
sBuffer = new char*[512] ;
sBuffer[0] = new char[512 * 128] ;
@ -1393,6 +1379,31 @@ namespace LLError
}
sIndex = 0 ;
}
}
void LLCallStacks::freeStackBuffer()
{
if(sBuffer != NULL)
{
delete [] sBuffer[0] ;
delete [] sBuffer ;
sBuffer = NULL ;
}
}
//static
void LLCallStacks::push(const char* function, const int line)
{
CallStacksLogLock lock;
if (!lock.ok())
{
return;
}
if(sBuffer == NULL)
{
allocateStackBuffer();
}
if(sIndex > 511)
{
@ -1424,15 +1435,9 @@ namespace LLError
return;
}
if(!sBuffer)
if(sBuffer == NULL)
{
sBuffer = new char*[512] ;
sBuffer[0] = new char[512 * 128] ;
for(S32 i = 1 ; i < 512 ; i++)
{
sBuffer[i] = sBuffer[i-1] + 128 ;
}
sIndex = 0 ;
allocateStackBuffer();
}
if(sIndex > 511)
@ -1463,11 +1468,9 @@ namespace LLError
LL_INFOS() << " *************** END OF LL CALL STACKS *************** " << LL_ENDL;
}
if(sBuffer)
if(sBuffer != NULL)
{
delete[] sBuffer[0] ;
delete[] sBuffer ;
sBuffer = NULL ;
freeStackBuffer();
}
}
@ -1477,5 +1480,10 @@ namespace LLError
sIndex = 0 ;
}
//static
void LLCallStacks::cleanup()
{
freeStackBuffer();
}
}

View File

@ -261,6 +261,9 @@ namespace LLError
private:
static char** sBuffer ;
static S32 sIndex ;
static void allocateStackBuffer();
static void freeStackBuffer();
public:
static void push(const char* function, const int line) ;
@ -268,6 +271,7 @@ namespace LLError
static void print() ;
static void clear() ;
static void end(std::ostringstream* _out) ;
static void cleanup();
};
}

View File

@ -29,7 +29,10 @@
#define LL_LLERRORCONTROL_H
#include "llerror.h"
#include "llpointer.h"
#include "llrefcount.h"
#include "boost/function.hpp"
#include "boost/shared_ptr.hpp"
#include <string>
class LLSD;
@ -156,16 +159,14 @@ namespace LLError
mWantsFunctionName;
};
typedef boost::shared_ptr<Recorder> RecorderPtr;
/**
* @NOTE: addRecorder() conveys ownership to the underlying Settings
* object -- when destroyed, it will @em delete the passed Recorder*!
* @NOTE: addRecorder() and removeRecorder() uses the boost::shared_ptr to allow for shared ownership
* while still ensuring that the allocated memory is eventually freed
*/
LL_COMMON_API void addRecorder(Recorder*);
/**
* @NOTE: removeRecorder() reclaims ownership of the Recorder*: its
* lifespan becomes the caller's problem.
*/
LL_COMMON_API void removeRecorder(Recorder*);
LL_COMMON_API void addRecorder(RecorderPtr);
LL_COMMON_API void removeRecorder(RecorderPtr);
// each error message is passed to each recorder via recordMessage()
LL_COMMON_API void logToFile(const std::string& filename);
@ -182,9 +183,9 @@ namespace LLError
Utilities for use by the unit tests of LLError itself.
*/
class Settings;
LL_COMMON_API Settings* saveAndResetSettings();
LL_COMMON_API void restoreSettings(Settings *);
typedef LLPointer<LLRefCount> SettingsStoragePtr;
LL_COMMON_API SettingsStoragePtr saveAndResetSettings();
LL_COMMON_API void restoreSettings(SettingsStoragePtr pSettingsStorage);
LL_COMMON_API std::string abbreviateFile(const std::string& filePath);
LL_COMMON_API int shouldLogCallCount();

View File

@ -31,6 +31,7 @@
#include <vector>
#include <list>
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_enum.hpp>
#include <boost/unordered_map.hpp>
@ -629,7 +630,7 @@ namespace LLInitParam
UserData* mUserData;
};
typedef ParamDescriptor* ParamDescriptorPtr;
typedef boost::shared_ptr<ParamDescriptor> ParamDescriptorPtr;
// each derived Block class keeps a static data structure maintaining offsets to various params
class LL_COMMON_API BlockDescriptor

View File

@ -56,9 +56,9 @@ namespace tut
{
public:
TestRecorder() { mWantsTime = false; }
~TestRecorder() { LLError::removeRecorder(this); }
virtual ~TestRecorder() { }
void recordMessage(LLError::ELevel level,
virtual void recordMessage(LLError::ELevel level,
const std::string& message)
{
mMessages.push_back(message);
@ -85,15 +85,11 @@ namespace tut
struct ErrorTestData
{
// addRecorder() expects to be able to later delete the passed
// Recorder*. Even though removeRecorder() reclaims ownership, passing
// a pointer to a data member rather than a heap Recorder subclass
// instance would just be Wrong.
TestRecorder* mRecorder;
LLError::Settings* mPriorErrorSettings;
LLError::RecorderPtr mRecorder;
LLError::SettingsStoragePtr mPriorErrorSettings;
ErrorTestData():
mRecorder(new TestRecorder)
mRecorder(new TestRecorder())
{
fatalWasCalled = false;
@ -106,13 +102,32 @@ namespace tut
~ErrorTestData()
{
LLError::removeRecorder(mRecorder);
delete mRecorder;
LLError::restoreSettings(mPriorErrorSettings);
}
int countMessages()
{
return boost::dynamic_pointer_cast<TestRecorder>(mRecorder)->countMessages();
}
void clearMessages()
{
boost::dynamic_pointer_cast<TestRecorder>(mRecorder)->clearMessages();
}
void setWantsTime(bool t)
{
boost::dynamic_pointer_cast<TestRecorder>(mRecorder)->setWantsTime(t);
}
std::string message(int n)
{
return boost::dynamic_pointer_cast<TestRecorder>(mRecorder)->message(n);
}
void ensure_message_count(int expectedCount)
{
ensure_equals("message count", mRecorder->countMessages(), expectedCount);
ensure_equals("message count", countMessages(), expectedCount);
}
void ensure_message_contains(int n, const std::string& expectedText)
@ -120,7 +135,7 @@ namespace tut
std::ostringstream test_name;
test_name << "testing message " << n;
ensure_contains(test_name.str(), mRecorder->message(n), expectedText);
ensure_contains(test_name.str(), message(n), expectedText);
}
void ensure_message_does_not_contain(int n, const std::string& expectedText)
@ -128,7 +143,7 @@ namespace tut
std::ostringstream test_name;
test_name << "testing message " << n;
ensure_does_not_contain(test_name.str(), mRecorder->message(n), expectedText);
ensure_does_not_contain(test_name.str(), message(n), expectedText);
}
};
@ -385,15 +400,15 @@ namespace
}
typedef std::string (*LogFromFunction)(bool);
void testLogName(tut::TestRecorder* recorder, LogFromFunction f,
void testLogName(LLError::RecorderPtr recorder, LogFromFunction f,
const std::string& class_name = "")
{
recorder->clearMessages();
boost::dynamic_pointer_cast<tut::TestRecorder>(recorder)->clearMessages();
std::string name = f(false);
f(true);
std::string messageWithoutName = recorder->message(0);
std::string messageWithName = recorder->message(1);
std::string messageWithoutName = boost::dynamic_pointer_cast<tut::TestRecorder>(recorder)->message(0);
std::string messageWithName = boost::dynamic_pointer_cast<tut::TestRecorder>(recorder)->message(1);
ensure_has(name + " logged without name",
messageWithoutName, name);
@ -528,12 +543,12 @@ namespace tut
{
LLError::setTimeFunction(roswell);
mRecorder->setWantsTime(false);
setWantsTime(false);
ufoSighting();
ensure_message_contains(0, "ufo");
ensure_message_does_not_contain(0, roswell());
mRecorder->setWantsTime(true);
setWantsTime(true);
ufoSighting();
ensure_message_contains(1, "ufo");
ensure_message_contains(1, roswell());
@ -545,13 +560,13 @@ namespace tut
{
LLError::setPrintLocation(true);
LLError::setTimeFunction(roswell);
mRecorder->setWantsTime(true);
setWantsTime(true);
std::string location,
function;
writeReturningLocationAndFunction(location, function);
ensure_equals("order is location time type function message",
mRecorder->message(0),
message(0),
location + roswell() + " INFO: " + function + ": apple");
}
@ -559,19 +574,19 @@ namespace tut
// multiple recorders
void ErrorTestObject::test<11>()
{
TestRecorder* altRecorder(new TestRecorder);
LLError::RecorderPtr altRecorder(new TestRecorder());
LLError::addRecorder(altRecorder);
LL_INFOS() << "boo" << LL_ENDL;
ensure_message_contains(0, "boo");
ensure_equals("alt recorder count", altRecorder->countMessages(), 1);
ensure_contains("alt recorder message 0", altRecorder->message(0), "boo");
ensure_equals("alt recorder count", boost::dynamic_pointer_cast<TestRecorder>(altRecorder)->countMessages(), 1);
ensure_contains("alt recorder message 0", boost::dynamic_pointer_cast<TestRecorder>(altRecorder)->message(0), "boo");
LLError::setTimeFunction(roswell);
TestRecorder* anotherRecorder(new TestRecorder);
anotherRecorder->setWantsTime(true);
LLError::RecorderPtr anotherRecorder(new TestRecorder());
boost::dynamic_pointer_cast<TestRecorder>(anotherRecorder)->setWantsTime(true);
LLError::addRecorder(anotherRecorder);
LL_INFOS() << "baz" << LL_ENDL;
@ -579,10 +594,13 @@ namespace tut
std::string when = roswell();
ensure_message_does_not_contain(1, when);
ensure_equals("alt recorder count", altRecorder->countMessages(), 2);
ensure_does_not_contain("alt recorder message 1", altRecorder->message(1), when);
ensure_equals("another recorder count", anotherRecorder->countMessages(), 1);
ensure_contains("another recorder message 0", anotherRecorder->message(0), when);
ensure_equals("alt recorder count", boost::dynamic_pointer_cast<TestRecorder>(altRecorder)->countMessages(), 2);
ensure_does_not_contain("alt recorder message 1", boost::dynamic_pointer_cast<TestRecorder>(altRecorder)->message(1), when);
ensure_equals("another recorder count", boost::dynamic_pointer_cast<TestRecorder>(anotherRecorder)->countMessages(), 1);
ensure_contains("another recorder message 0", boost::dynamic_pointer_cast<TestRecorder>(anotherRecorder)->message(0), when);
LLError::removeRecorder(altRecorder);
LLError::removeRecorder(anotherRecorder);
}
}

View File

@ -38,6 +38,7 @@
#include "stringize.h"
#include <boost/bind.hpp>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <list>
#include <string>
#include <stdexcept>
@ -81,72 +82,29 @@ struct WrapLLErrs
}
std::string error;
LLError::Settings* mPriorErrorSettings;
LLError::SettingsStoragePtr mPriorErrorSettings;
LLError::FatalFunction mPriorFatal;
};
/**
* LLError::addRecorder() accepts ownership of the passed Recorder* -- it
* expects to be able to delete it later. CaptureLog isa Recorder whose
* pointer we want to be able to pass without any ownership implications.
* For such cases, instantiate a new RecorderProxy(yourRecorder) and pass
* that. Your heap RecorderProxy might later be deleted, but not yourRecorder.
*/
class RecorderProxy: public LLError::Recorder
{
public:
RecorderProxy(LLError::Recorder* recorder):
mRecorder(recorder)
{}
virtual void recordMessage(LLError::ELevel level, const std::string& message)
{
mRecorder->recordMessage(level, message);
}
virtual bool wantsTime()
{
return mRecorder->wantsTime();
}
private:
LLError::Recorder* mRecorder;
};
/**
* Capture log messages. This is adapted (simplified) from the one in
* llerror_test.cpp.
*/
class CaptureLog : public LLError::Recorder, public boost::noncopyable
class CaptureLogRecorder : public LLError::Recorder, public boost::noncopyable
{
public:
CaptureLog(LLError::ELevel level=LLError::LEVEL_DEBUG):
// Mostly what we're trying to accomplish by saving and resetting
// LLError::Settings is to bypass the default RecordToStderr and
// RecordToWinDebug Recorders. As these are visible only inside
// llerror.cpp, we can't just call LLError::removeRecorder() with
// each. For certain tests we need to produce, capture and examine
// DEBUG log messages -- but we don't want to spam the user's console
// with that output. If it turns out that saveAndResetSettings() has
// some bad effect, give up and just let the DEBUG level log messages
// display.
mOldSettings(LLError::saveAndResetSettings()),
mProxy(new RecorderProxy(this))
CaptureLogRecorder()
: LLError::Recorder(),
boost::noncopyable(),
mMessages()
{
LLError::setFatalFunction(wouldHaveCrashed);
LLError::setDefaultLevel(level);
LLError::addRecorder(mProxy);
}
~CaptureLog()
virtual ~CaptureLogRecorder()
{
LLError::removeRecorder(mProxy);
delete mProxy;
LLError::restoreSettings(mOldSettings);
}
void recordMessage(LLError::ELevel level,
const std::string& message)
virtual void recordMessage(LLError::ELevel level, const std::string& message)
{
mMessages.push_back(message);
}
@ -154,7 +112,7 @@ public:
/// Don't assume the message we want is necessarily the LAST log message
/// emitted by the underlying code; search backwards through all messages
/// for the sought string.
std::string messageWith(const std::string& search, bool required=true)
std::string messageWith(const std::string& search, bool required)
{
for (MessageList::const_reverse_iterator rmi(mMessages.rbegin()), rmend(mMessages.rend());
rmi != rmend; ++rmi)
@ -187,14 +145,63 @@ public:
return out;
}
private:
typedef std::list<std::string> MessageList;
MessageList mMessages;
LLError::Settings* mOldSettings;
LLError::Recorder* mProxy;
};
/**
* Capture log messages. This is adapted (simplified) from the one in
* llerror_test.cpp.
*/
class CaptureLog : public boost::noncopyable
{
public:
CaptureLog(LLError::ELevel level=LLError::LEVEL_DEBUG)
// Mostly what we're trying to accomplish by saving and resetting
// LLError::Settings is to bypass the default RecordToStderr and
// RecordToWinDebug Recorders. As these are visible only inside
// llerror.cpp, we can't just call LLError::removeRecorder() with
// each. For certain tests we need to produce, capture and examine
// DEBUG log messages -- but we don't want to spam the user's console
// with that output. If it turns out that saveAndResetSettings() has
// some bad effect, give up and just let the DEBUG level log messages
// display.
: boost::noncopyable(),
mOldSettings(LLError::saveAndResetSettings()),
mRecorder(new CaptureLogRecorder())
{
LLError::setFatalFunction(wouldHaveCrashed);
LLError::setDefaultLevel(level);
LLError::addRecorder(mRecorder);
}
~CaptureLog()
{
LLError::removeRecorder(mRecorder);
LLError::restoreSettings(mOldSettings);
}
/// Don't assume the message we want is necessarily the LAST log message
/// emitted by the underlying code; search backwards through all messages
/// for the sought string.
std::string messageWith(const std::string& search, bool required=true)
{
return boost::dynamic_pointer_cast<CaptureLogRecorder>(mRecorder)->messageWith(search, required);
}
std::ostream& streamto(std::ostream& out) const
{
return boost::dynamic_pointer_cast<CaptureLogRecorder>(mRecorder)->streamto(out);
}
private:
LLError::SettingsStoragePtr mOldSettings;
LLError::RecorderPtr mRecorder;
};
inline
std::ostream& operator<<(std::ostream& out, const CaptureLog& log)
std::ostream& operator<<(std::ostream& out, const CaptureLogRecorder& log)
{
return log.streamto(out);
}

View File

@ -610,6 +610,15 @@ LLAres *ll_init_ares()
return gAres;
}
void ll_cleanup_ares()
{
if (gAres != NULL)
{
delete gAres;
gAres = NULL;
}
}
LLDnsRecord::LLDnsRecord(LLResType type, const std::string &name,
unsigned ttl)
: LLRefCount(),

View File

@ -578,5 +578,6 @@ extern LLAres *gAres;
* thread safe.
*/
extern LLAres *ll_init_ares();
extern void ll_cleanup_ares();
#endif // LL_LLARES_H

View File

@ -349,6 +349,36 @@ void LLCurl::Easy::releaseEasyHandle(CURL* handle)
}
}
//static
void LLCurl::Easy::deleteAllActiveHandles()
{
LLMutexLock lock(sHandleMutexp) ;
LL_CHECK_MEMORY
for (std::set<CURL*>::iterator activeHandle = sActiveHandles.begin(); activeHandle != sActiveHandles.end(); ++activeHandle)
{
CURL* curlHandle = *activeHandle;
LLCurl::deleteEasyHandle(curlHandle);
LL_CHECK_MEMORY
}
sFreeHandles.clear();
}
//static
void LLCurl::Easy::deleteAllFreeHandles()
{
LLMutexLock lock(sHandleMutexp) ;
LL_CHECK_MEMORY
for (std::set<CURL*>::iterator freeHandle = sFreeHandles.begin(); freeHandle != sFreeHandles.end(); ++freeHandle)
{
CURL* curlHandle = *freeHandle;
LLCurl::deleteEasyHandle(curlHandle);
LL_CHECK_MEMORY
}
sFreeHandles.clear();
}
LLCurl::Easy::Easy()
: mHeaders(NULL),
mCurlEasyHandle(NULL)
@ -1857,17 +1887,14 @@ void LLCurl::cleanupClass()
#endif
LL_CHECK_MEMORY
for (std::set<CURL*>::iterator iter = Easy::sFreeHandles.begin(); iter != Easy::sFreeHandles.end(); ++iter)
{
CURL* curl = *iter;
LLCurl::deleteEasyHandle(curl);
}
Easy::deleteAllFreeHandles();
LL_CHECK_MEMORY
Easy::deleteAllActiveHandles();
LL_CHECK_MEMORY
Easy::sFreeHandles.clear();
// Free the template easy handle
curl_easy_cleanup(sCurlTemplateStandardHandle);
sCurlTemplateStandardHandle = NULL;
LL_CHECK_MEMORY
delete Easy::sHandleMutexp ;

View File

@ -304,6 +304,9 @@ private:
static std::set<CURL*> sFreeHandles;
static std::set<CURL*> sActiveHandles;
static LLMutex* sHandleMutexp ;
static void deleteAllActiveHandles();
static void deleteAllFreeHandles();
};
class LLCurl::Multi

View File

@ -127,7 +127,7 @@ namespace
{
public:
RawInjector(const U8* data, S32 size) : mData(data), mSize(size) {}
virtual ~RawInjector() {delete mData;}
virtual ~RawInjector() {delete [] mData;}
const std::string& contentType() { return HTTP_CONTENT_OCTET_STREAM; }

View File

@ -27,6 +27,7 @@
*/
#include "linden_common.h"
#include "llstl.h"
#include "indra_constants.h"
#include "llplugincookiestore.h"
@ -654,12 +655,8 @@ void LLPluginCookieStore::setOneCookie(const std::string &s, std::string::size_t
void LLPluginCookieStore::clearCookies()
{
while(!mCookies.empty())
{
cookie_map_t::iterator iter = mCookies.begin();
delete iter->second;
mCookies.erase(iter);
}
std::for_each(mCookies.begin(), mCookies.end(), DeletePairedPointer());
mCookies.clear();
}
void LLPluginCookieStore::removeCookie(const std::string &key)

View File

@ -131,6 +131,8 @@ LLPluginProcessParent::~LLPluginProcessParent()
{
// destroy the shared memory region
iter->second->destroy();
delete iter->second;
iter->second = NULL;
// and remove it from our map
mSharedMemoryRegions.erase(iter);
@ -960,6 +962,8 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)
{
// destroy the shared memory region
iter->second->destroy();
delete iter->second;
iter->second = NULL;
// and remove it from our map
mSharedMemoryRegions.erase(iter);

View File

@ -390,9 +390,7 @@ LLImageGL::~LLImageGL()
{
LLImageGL::cleanup();
sImageList.erase(this);
disclaimMem((mPickMaskWidth * mPickMaskHeight + 7) / 8);
delete [] mPickMask;
mPickMask = NULL;
freePickMask();
sCount--;
}
@ -461,6 +459,8 @@ void LLImageGL::cleanup()
{
destroyGLTexture();
}
freePickMask();
mSaveData = NULL; // deletes data
}
@ -504,10 +504,7 @@ void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_leve
}
// pickmask validity depends on old image size, delete it
disclaimMem((mPickMaskWidth * mPickMaskHeight + 7) / 8);
delete [] mPickMask;
mPickMask = NULL;
mPickMaskWidth = mPickMaskHeight = 0;
freePickMask();
mWidth = width;
mHeight = height;
@ -1886,27 +1883,10 @@ void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)
}
//----------------------------------------------------------------------------
void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
U32 LLImageGL::createPickMask(S32 pWidth, S32 pHeight)
{
if(!mNeedsAlphaAndPickMask)
{
return ;
}
disclaimMem((mPickMaskWidth * mPickMaskHeight + 7) / 8);
delete [] mPickMask;
mPickMask = NULL;
mPickMaskWidth = mPickMaskHeight = 0;
if (mFormatType != GL_UNSIGNED_BYTE ||
mFormatPrimary != GL_RGBA)
{
//cannot generate a pick mask for this texture
return;
}
U32 pick_width = width/2 + 1;
U32 pick_height = height/2 + 1;
U32 pick_width = pWidth/2 + 1;
U32 pick_height = pHeight/2 + 1;
U32 size = pick_width * pick_height;
size = (size + 7) / 8; // pixelcount-to-bits
@ -1917,6 +1897,45 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
memset(mPickMask, 0, sizeof(U8) * size);
return size;
}
//----------------------------------------------------------------------------
void LLImageGL::freePickMask()
{
// pickmask validity depends on old image size, delete it
if (mPickMask != NULL)
{
disclaimMem((mPickMaskWidth * mPickMaskHeight + 7) / 8);
delete [] mPickMask;
}
mPickMask = NULL;
mPickMaskWidth = mPickMaskHeight = 0;
}
//----------------------------------------------------------------------------
void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
{
if(!mNeedsAlphaAndPickMask)
{
return ;
}
freePickMask();
if (mFormatType != GL_UNSIGNED_BYTE ||
mFormatPrimary != GL_RGBA)
{
//cannot generate a pick mask for this texture
return;
}
#ifdef SHOW_ASSERT
const U32 pickSize = createPickMask(width, height);
#else // SHOW_ASSERT
createPickMask(width, height);
#endif // SHOW_ASSERT
U32 pick_bit = 0;
for (S32 y = 0; y < height; y += 2)
@ -1929,7 +1948,7 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
{
U32 pick_idx = pick_bit/8;
U32 pick_offset = pick_bit%8;
llassert(pick_idx < size);
llassert(pick_idx < pickSize);
mPickMask[pick_idx] |= 1 << pick_offset;
}

View File

@ -186,6 +186,9 @@ public:
mutable F32 mLastBindTime; // last time this was bound, by discard level
private:
U32 createPickMask(S32 pWidth, S32 pHeight);
void freePickMask();
LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL
U8* mPickMask; //downsampled bitmap approximation of alpha channel. NULL if no alpha channel
U16 mPickMaskWidth;

View File

@ -35,8 +35,9 @@
//
LLBadgeOwner::LLBadgeOwner(LLHandle< LLView > viewHandle)
: mBadge(NULL)
, mBadgeOwnerView(viewHandle)
: mHasBadgeHolderParent(false),
mBadge(NULL),
mBadgeOwnerView(viewHandle)
{
}
@ -45,31 +46,12 @@ void LLBadgeOwner::initBadgeParams(const LLBadge::Params& p)
if (!p.equals(LLUICtrlFactory::getDefaultParams<LLBadge>()))
{
mBadge = createBadge(p);
}
}
mHasBadgeHolderParent = false;
void LLBadgeOwner::setBadgeLabel(const LLStringExplicit& label)
{
if (mBadge == NULL)
{
mBadge = createBadge(LLUICtrlFactory::getDefaultParams<LLBadge>());
addBadgeToParentPanel();
}
if (mBadge)
{
mBadge->setLabel(label);
//
// Push the badge to the front so it renders on top
//
LLView * parent = mBadge->getParent();
if (parent)
LLView * owner_view = mBadgeOwnerView.get();
if (owner_view)
{
parent->sendChildToFront(mBadge);
mBadge->addToView(owner_view);
}
}
}
@ -82,10 +64,8 @@ void LLBadgeOwner::setBadgeVisibility(bool visible)
}
}
bool LLBadgeOwner::addBadgeToParentPanel()
void LLBadgeOwner::addBadgeToParentHolder()
{
bool badge_added = false;
LLView * owner_view = mBadgeOwnerView.get();
if (mBadge && owner_view)
@ -110,16 +90,9 @@ bool LLBadgeOwner::addBadgeToParentPanel()
if (badge_holder)
{
badge_added = badge_holder->addBadge(mBadge);
}
else
{
// Badge parent is fallback badge owner if no valid holder exists in the hierarchy
badge_added = mBadge->addToView(owner_view);
mHasBadgeHolderParent = badge_holder->addBadge(mBadge);
}
}
return badge_added;
}
LLBadge* LLBadgeOwner::createBadge(const LLBadge::Params& p)

View File

@ -41,11 +41,9 @@ public:
LLBadgeOwner(LLHandle< LLView > viewHandle);
void initBadgeParams(const LLBadge::Params& p);
bool addBadgeToParentPanel();
void addBadgeToParentHolder();
bool badgeHasParent() const { return (mBadge && mBadge->getParent()); }
void setBadgeLabel(const LLStringExplicit& label);
bool hasBadgeHolderParent() const { return mHasBadgeHolderParent; };
void setBadgeVisibility(bool visible);
private:
@ -53,7 +51,7 @@ private:
LLBadge* createBadge(const LLBadge::Params& p);
private:
bool mHasBadgeHolderParent;
LLBadge* mBadge;
LLHandle< LLView > mBadgeOwnerView;
};

View File

@ -384,7 +384,7 @@ BOOL LLButton::postBuild()
{
autoResize();
addBadgeToParentPanel();
addBadgeToParentHolder();
return LLUICtrl::postBuild();
}

View File

@ -227,10 +227,11 @@ LLFolderView::LLFolderView(const Params& p)
mStatusTextBox = LLUICtrlFactory::create<LLTextBox> (text_p);
mStatusTextBox->setFollowsLeft();
mStatusTextBox->setFollowsTop();
//addChild(mStatusTextBox);
addChild(mStatusTextBox);
// make the popup menu available
llassert(LLMenuGL::sMenuContainer != NULL);
LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(p.options_menu, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
if (!menu)
{

View File

@ -192,6 +192,7 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
setPrevalidateInput(p.prevalidate_input_callback());
setPrevalidate(p.prevalidate_callback());
llassert(LLMenuGL::sMenuContainer != NULL);
LLContextMenu* menu = LLUICtrlFactory::instance().createFromFile<LLContextMenu>
("menu_text_editor.xml",
LLMenuGL::sMenuContainer,

View File

@ -93,6 +93,7 @@ void LLMenuButton::setMenu(const std::string& menu_filename, EMenuPosition posit
return;
}
llassert(LLMenuGL::sMenuContainer != NULL);
LLToggleableMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(menu_filename, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
if (!menu)
{

View File

@ -63,6 +63,7 @@
// static
LLMenuHolderGL *LLMenuGL::sMenuContainer = NULL;
view_listener_t::listener_map_t view_listener_t::sListeners;
S32 MENU_BAR_HEIGHT = 0;
S32 MENU_BAR_WIDTH = 0;

View File

@ -895,7 +895,8 @@ class view_listener_t : public boost::signals2::trackable
{
public:
virtual bool handleEvent(const LLSD& userdata) = 0;
virtual ~view_listener_t() {}
view_listener_t() { sListeners.insert(this); }
virtual ~view_listener_t() { sListeners.erase(this); }
static void addEnable(view_listener_t* listener, const std::string& name)
{
@ -913,6 +914,20 @@ public:
addEnable(listener, name);
addCommit(listener, name);
}
static void cleanup()
{
listener_vector_t listeners(sListeners.begin(), sListeners.end());
sListeners.clear();
std::for_each(listeners.begin(), listeners.end(), DeletePointer());
listeners.clear();
}
private:
typedef std::set<view_listener_t*> listener_map_t;
typedef std::vector<view_listener_t*> listener_vector_t;
static listener_map_t sListeners;
};
#endif // LL_LLMENUGL_H

View File

@ -1815,6 +1815,7 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
// create the context menu from the XUI file and display it
std::string menu_name = is_group ? "menu_url_group.xml" : "menu_url_agent.xml";
delete mPopupMenu;
llassert(LLMenuGL::sMenuContainer != NULL);
mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
menu_name, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
if (mPopupMenu)

View File

@ -1140,6 +1140,17 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)
addChild( btn, 0 );
}
}
else
{
if (textbox)
{
LLUICtrl::addChild(textbox, 0);
}
if (btn)
{
LLUICtrl::addChild(btn, 0);
}
}
if (child)
{
@ -1636,16 +1647,26 @@ void LLTabContainer::setTabImage(LLPanel* child, LLIconCtrl* icon)
{
LLTabTuple* tuple = getTabByPanel(child);
LLCustomButtonIconCtrl* button;
bool hasButton = false;
if(tuple)
{
button = dynamic_cast<LLCustomButtonIconCtrl*>(tuple->mButton);
if(button)
{
hasButton = true;
button->setIcon(icon);
reshapeTuple(tuple);
}
}
if (!hasButton && (icon != NULL))
{
// It was assumed that the tab's button would take ownership of the icon pointer.
// But since the tab did not have a button, kill the icon to prevent the memory
// leak.
icon->die();
}
}
void LLTabContainer::reshapeTuple(LLTabTuple* tuple)

View File

@ -1955,6 +1955,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
// create and return the context menu from the XUI file
delete mPopupMenu;
llassert(LLMenuGL::sMenuContainer != NULL);
mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(xui_file, LLMenuGL::sMenuContainer,
LLMenuHolderGL::child_registry_t::instance());
if (mIsFriendSignal)
@ -2037,7 +2038,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
LLUrlMatch match;
std::string text = new_text;
while ( LLUrlRegistry::instance().findUrl(text, match,
boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3)) )
boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3),isContentTrusted()))
{
start = match.getStart();
end = match.getEnd()+1;
@ -2074,7 +2075,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
}
}
LLTextUtil::processUrlMatch(&match,this);
LLTextUtil::processUrlMatch(&match,this,isContentTrusted());
// move on to the rest of the text after the Url
if (end < (S32)text.length())

View File

@ -367,7 +367,9 @@ public:
bool getWordWrap() { return mWordWrap; }
bool getUseEllipses() { return mUseEllipses; }
bool truncate(); // returns true of truncation occurred
bool isContentTrusted() {return mTrustedContent;}
void setContentTrusted(bool trusted_content) { mTrustedContent = trusted_content; }
// TODO: move into LLTextSegment?
void createUrlContextMenu(S32 x, S32 y, const std::string &url); // create a popup context menu for the given Url

View File

@ -2031,6 +2031,7 @@ void LLTextEditor::showContextMenu(S32 x, S32 y)
{
if (!mContextMenu)
{
llassert(LLMenuGL::sMenuContainer != NULL);
mContextMenu = LLUICtrlFactory::instance().createFromFile<LLContextMenu>("menu_text_editor.xml",
LLMenuGL::sMenuContainer,
LLMenuHolderGL::child_registry_t::instance());

View File

@ -72,7 +72,7 @@ const std::string& LLTextUtil::formatPhoneNumber(const std::string& phone_str)
return formatted_phone_str;
}
bool LLTextUtil::processUrlMatch(LLUrlMatch* match,LLTextBase* text_base)
bool LLTextUtil::processUrlMatch(LLUrlMatch* match,LLTextBase* text_base, bool is_content_trusted)
{
if (match == 0 || text_base == 0)
return false;
@ -85,7 +85,7 @@ bool LLTextUtil::processUrlMatch(LLUrlMatch* match,LLTextBase* text_base)
}
// output an optional icon before the Url
if (!match->getIcon().empty() )
if (is_content_trusted && !match->getIcon().empty() )
{
LLUIImagePtr image = LLUI::getUIImage(match->getIcon());
if (image)

View File

@ -64,7 +64,7 @@ namespace LLTextUtil
*/
const std::string& formatPhoneNumber(const std::string& phone_str);
bool processUrlMatch(LLUrlMatch* match,LLTextBase* text_base);
bool processUrlMatch(LLUrlMatch* match,LLTextBase* text_base, bool is_content_trusted);
class TextHelpers
{

View File

@ -148,6 +148,7 @@ void LLToolBar::createContextMenu()
enable_reg.add("Toolbars.CheckSetting", boost::bind(&LLToolBar::isSettingChecked, this, _2));
// Create the context menu
llassert(LLMenuGL::sMenuContainer != NULL);
LLContextMenu* menu = LLUICtrlFactory::instance().createFromFile<LLContextMenu>("menu_toolbars.xml", LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
if (menu)

View File

@ -41,7 +41,8 @@ LLUrlRegistry::LLUrlRegistry()
// Urls are matched in the order that they were registered
registerUrl(new LLUrlEntryNoLink());
registerUrl(new LLUrlEntryIcon());
mUrlEntryIcon = new LLUrlEntryIcon();
registerUrl(mUrlEntryIcon);
registerUrl(new LLUrlEntrySLURL());
registerUrl(new LLUrlEntryHTTP());
registerUrl(new LLUrlEntryHTTPLabel());
@ -145,7 +146,7 @@ static bool stringHasUrl(const std::string &text)
text.find("<icon") != std::string::npos);
}
bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb)
bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb, bool is_content_trusted)
{
// avoid costly regexes if there is clearly no URL in the text
if (! stringHasUrl(text))
@ -160,6 +161,12 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
std::vector<LLUrlEntryBase *>::iterator it;
for (it = mUrlEntry.begin(); it != mUrlEntry.end(); ++it)
{
//Skip for url entry icon if content is not trusted
if(!is_content_trusted && (mUrlEntryIcon == *it))
{
continue;
}
LLUrlEntryBase *url_entry = *it;
U32 start = 0, end = 0;

View File

@ -73,7 +73,8 @@ public:
/// get the next Url in an input string, starting at a given character offset
/// your callback is invoked if the matched Url's label changes in the future
bool findUrl(const std::string &text, LLUrlMatch &match,
const LLUrlLabelCallback &cb = &LLUrlRegistryNullCallback);
const LLUrlLabelCallback &cb = &LLUrlRegistryNullCallback,
bool is_content_trusted = false);
/// a slightly less efficient version of findUrl for wide strings
bool findUrl(const LLWString &text, LLUrlMatch &match,
@ -92,6 +93,7 @@ private:
friend class LLSingleton<LLUrlRegistry>;
std::vector<LLUrlEntryBase *> mUrlEntry;
LLUrlEntryBase* mUrlEntryIcon;
};
#endif

View File

@ -657,7 +657,7 @@ LLWindowWin32::~LLWindowWin32()
delete [] mSupportedResolutions;
mSupportedResolutions = NULL;
delete mWindowClassName;
delete [] mWindowClassName;
mWindowClassName = NULL;
}

View File

@ -2019,6 +2019,9 @@ bool LLAppViewer::cleanup()
// Non-LLCurl libcurl library
mAppCoreHttp.cleanup();
// NOTE The following call is not thread safe.
ll_cleanup_ares();
LLFilePickerThread::cleanupClass();
//MUST happen AFTER LLCurl::cleanupClass
@ -2114,6 +2117,8 @@ bool LLAppViewer::cleanup()
ll_close_fail_log();
LLError::LLCallStacks::cleanup();
removeMarkerFiles();
LL_INFOS() << "Goodbye!" << LL_ENDL;

View File

@ -438,7 +438,7 @@ void LLAppViewerWin32::disableWinErrorReporting()
const S32 MAX_CONSOLE_LINES = 500;
void create_console()
static bool create_console()
{
int h_con_handle;
long l_std_handle;
@ -447,7 +447,7 @@ void create_console()
FILE *fp;
// allocate a console for this app
AllocConsole();
const bool isConsoleAllocated = AllocConsole();
// set the screen buffer to be big enough to let us scroll text
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
@ -495,10 +495,13 @@ void create_console()
*stderr = *fp;
setvbuf( stderr, NULL, _IONBF, 0 );
}
return isConsoleAllocated;
}
LLAppViewerWin32::LLAppViewerWin32(const char* cmd_line) :
mCmdLine(cmd_line)
mCmdLine(cmd_line),
mIsConsoleAllocated(false)
{
}
@ -542,6 +545,16 @@ bool LLAppViewerWin32::cleanup()
gDXHardware.cleanup();
#ifndef LL_RELEASE_FOR_DOWNLOAD
LLWinDebug::instance().cleanup();
#endif
if (mIsConsoleAllocated)
{
FreeConsole();
mIsConsoleAllocated = false;
}
return result;
}
@ -553,7 +566,7 @@ void LLAppViewerWin32::initLoggingAndGetLastDuration()
void LLAppViewerWin32::initConsole()
{
// pop up debug console
create_console();
mIsConsoleAllocated = create_console();
return LLAppViewer::initConsole();
}

View File

@ -61,7 +61,8 @@ protected:
private:
void disableWinErrorReporting();
std::string mCmdLine;
std::string mCmdLine;
bool mIsConsoleAllocated;
};
#endif // LL_LLAPPVIEWERWIN32_H

View File

@ -107,6 +107,7 @@ class LLChatHistoryHeader: public LLPanel
public:
LLChatHistoryHeader()
: LLPanel(),
mInfoCtrl(NULL),
mPopupMenuHandleAvatar(),
mPopupMenuHandleObject(),
mAvatarID(),
@ -129,9 +130,6 @@ public:
~LLChatHistoryHeader()
{
// Detach the info button so that it doesn't get destroyed (EXT-8463).
hideInfoCtrl();
if (mAvatarNameCacheConnection.connected())
{
mAvatarNameCacheConnection.disconnect();
@ -292,6 +290,11 @@ public:
mUserNameTextBox = getChild<LLTextBox>("user_name");
mTimeBoxTextBox = getChild<LLTextBox>("time_box");
mInfoCtrl = LLUICtrlFactory::getInstance()->createFromFile<LLUICtrl>("inspector_info_ctrl.xml", this, LLPanel::child_registry_t::instance());
llassert(mInfoCtrl != NULL);
mInfoCtrl->setCommitCallback(boost::bind(&LLChatHistoryHeader::onClickInfoCtrl, mInfoCtrl));
mInfoCtrl->setVisible(FALSE);
return LLPanel::postBuild();
}
@ -589,39 +592,19 @@ protected:
void showInfoCtrl()
{
if (mAvatarID.isNull() || mFrom.empty() || CHAT_SOURCE_SYSTEM == mSourceType) return;
if (!sInfoCtrl)
const bool isVisible = !mAvatarID.isNull() && !mFrom.empty() && CHAT_SOURCE_SYSTEM != mSourceType;
if (isVisible)
{
// *TODO: Delete the button at exit.
sInfoCtrl = LLUICtrlFactory::createFromFile<LLUICtrl>("inspector_info_ctrl.xml", NULL, LLPanel::child_registry_t::instance());
if (sInfoCtrl)
{
sInfoCtrl->setCommitCallback(boost::bind(&LLChatHistoryHeader::onClickInfoCtrl, sInfoCtrl));
}
const LLRect sticky_rect = mUserNameTextBox->getRect();
S32 icon_x = llmin(sticky_rect.mLeft + mUserNameTextBox->getTextBoundingRect().getWidth() + 7, sticky_rect.mRight - 3);
mInfoCtrl->setOrigin(icon_x, sticky_rect.getCenterY() - mInfoCtrl->getRect().getHeight() / 2 ) ;
}
if (!sInfoCtrl)
{
llassert(sInfoCtrl != NULL);
return;
}
LLTextBox* name = getChild<LLTextBox>("user_name");
LLRect sticky_rect = name->getRect();
S32 icon_x = llmin(sticky_rect.mLeft + name->getTextBoundingRect().getWidth() + 7, sticky_rect.mRight - 3);
sInfoCtrl->setOrigin(icon_x, sticky_rect.getCenterY() - sInfoCtrl->getRect().getHeight() / 2 ) ;
addChild(sInfoCtrl);
mInfoCtrl->setVisible(isVisible);
}
void hideInfoCtrl()
{
if (!sInfoCtrl) return;
if (sInfoCtrl->getParent() == this)
{
removeChild(sInfoCtrl);
}
mInfoCtrl->setVisible(FALSE);
}
private:
@ -692,7 +675,7 @@ protected:
LLHandle<LLView> mPopupMenuHandleAvatar;
LLHandle<LLView> mPopupMenuHandleObject;
static LLUICtrl* sInfoCtrl;
LLUICtrl* mInfoCtrl;
LLUUID mAvatarID;
LLSD mObjectData;
@ -709,8 +692,6 @@ private:
boost::signals2::connection mAvatarNameCacheConnection;
};
LLUICtrl* LLChatHistoryHeader::sInfoCtrl = NULL;
LLChatHistory::LLChatHistory(const LLChatHistory::Params& p)
: LLUICtrl(p),
mMessageHeaderFilename(p.message_header),

View File

@ -93,14 +93,15 @@ class LLChatHistory : public LLUICtrl
* @return pointer to LLView separator object.
*/
LLView* getSeparator();
void onClickMoreText();
private:
/**
* Builds a message header.
* @return pointer to LLView header object.
*/
LLView* getHeader(const LLChat& chat,const LLStyle::Params& style_params, const LLSD& args);
void onClickMoreText();
public:
~LLChatHistory();
LLSD getValue() const;

View File

@ -29,7 +29,6 @@
#include "llchatitemscontainerctrl.h"
#include "lltextbox.h"
#include "llchatmsgbox.h"
#include "llavatariconctrl.h"
#include "llcommandhandler.h"
#include "llfloaterreg.h"
@ -130,7 +129,6 @@ void LLFloaterIMNearbyChatToastPanel::addMessage(LLSD& notification)
{
std::string messageText = notification["message"].asString(); // UTF-8 line of text
LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);
std::string color_name = notification["text_color"].asString();
@ -171,7 +169,7 @@ void LLFloaterIMNearbyChatToastPanel::addMessage(LLSD& notification)
{
style_params.font.style = "ITALIC";
}
msg_text->appendText(messageText, TRUE, style_params);
mMsgText->appendText(messageText, TRUE, style_params);
}
snapToMessageHeight();
@ -204,9 +202,10 @@ void LLFloaterIMNearbyChatToastPanel::init(LLSD& notification)
case 2: messageFont = LLFontGL::getFontSansSerifBig(); break;
}
LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);
mMsgText = getChild<LLChatMsgBox>("msg_text", false);
mMsgText->setContentTrusted(false);
msg_text->setText(std::string(""));
mMsgText->setText(std::string(""));
if ( notification["chat_style"].asInteger() != CHAT_STYLE_IRC )
{
@ -232,12 +231,12 @@ void LLFloaterIMNearbyChatToastPanel::init(LLSD& notification)
style_params_name.link_href = notification["sender_slurl"].asString();
style_params_name.is_link = true;
msg_text->appendText(str_sender, FALSE, style_params_name);
mMsgText->appendText(str_sender, FALSE, style_params_name);
}
else
{
msg_text->appendText(str_sender, false);
mMsgText->appendText(str_sender, false);
}
}
@ -264,7 +263,7 @@ void LLFloaterIMNearbyChatToastPanel::init(LLSD& notification)
{
style_params.font.style = "ITALIC";
}
msg_text->appendText(messageText, FALSE, style_params);
mMsgText->appendText(messageText, FALSE, style_params);
}
@ -275,8 +274,7 @@ void LLFloaterIMNearbyChatToastPanel::init(LLSD& notification)
void LLFloaterIMNearbyChatToastPanel::snapToMessageHeight ()
{
LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false);
S32 new_height = llmax (text_box->getTextPixelHeight() + 2*text_box->getVPad() + 2*msg_height_pad, 25);
S32 new_height = llmax (mMsgText->getTextPixelHeight() + 2*mMsgText->getVPad() + 2*msg_height_pad, 25);
LLRect panel_rect = getRect();
@ -312,14 +310,13 @@ BOOL LLFloaterIMNearbyChatToastPanel::handleMouseUp (S32 x, S32 y, MASK mask)
return LLPanel::handleMouseUp(x,y,mask);
*/
LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false);
S32 local_x = x - text_box->getRect().mLeft;
S32 local_y = y - text_box->getRect().mBottom;
S32 local_x = x - mMsgText->getRect().mLeft;
S32 local_y = y - mMsgText->getRect().mBottom;
//if text_box process mouse up (ussually this is click on url) - we didn't show nearby_chat.
if (text_box->pointInView(local_x, local_y) )
if (mMsgText->pointInView(local_x, local_y) )
{
if (text_box->handleMouseUp(local_x,local_y,mask) == TRUE)
if (mMsgText->handleMouseUp(local_x,local_y,mask) == TRUE)
return TRUE;
else
{

View File

@ -28,6 +28,7 @@
#define LL_LLCHATITEMSCONTAINERCTRL_H_
#include "llchat.h"
#include "llchatmsgbox.h"
#include "llpanel.h"
#include "llscrollbar.h"
#include "llviewerchat.h"
@ -85,6 +86,7 @@ private:
LLUUID mFromID; // agent id or object id
std::string mFromName;
EChatSourceType mSourceType;
LLChatMsgBox* mMsgText;

View File

@ -204,6 +204,7 @@ void LLNotificationChiclet::createMenu()
enable_registrar.add("NotificationWellChicletMenu.EnableItem",
boost::bind(&LLNotificationChiclet::enableMenuItem, this, _2));
llassert(LLMenuGL::sMenuContainer != NULL);
mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>
("menu_notification_well_button.xml",
LLMenuGL::sMenuContainer,

View File

@ -110,6 +110,7 @@ void LLListContextMenu::handleMultiple(functor_t functor, const uuid_vec_t& ids)
// static
LLContextMenu* LLListContextMenu::createFromFile(const std::string& filename)
{
llassert(LLMenuGL::sMenuContainer != NULL);
return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
filename, LLContextMenu::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
}

View File

@ -391,8 +391,12 @@ BOOL LLMediaCtrl::postBuild ()
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registar;
registar.add("Open.WebInspector", boost::bind(&LLMediaCtrl::onOpenWebInspector, this));
// stinson 05/05/2014 : use this as the parent of the context menu if the static menu
// container has yet to be created
LLPanel* menuParent = (LLMenuGL::sMenuContainer != NULL) ? dynamic_cast<LLPanel*>(LLMenuGL::sMenuContainer) : dynamic_cast<LLPanel*>(this);
llassert(menuParent != NULL);
mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
"menu_media_ctrl.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
"menu_media_ctrl.xml", menuParent, LLViewerMenuHolderGL::child_registry_t::instance());
setVisibleCallback(boost::bind(&LLMediaCtrl::onVisibilityChanged, this, _2));
return TRUE;
@ -1118,3 +1122,8 @@ void LLMediaCtrl::setTrustedContent(bool trusted)
mMediaSource->setTrustedBrowser(trusted);
}
}
void LLMediaCtrl::updateContextMenuParent(LLView* pNewParent)
{
mContextMenu->updateParent(pNewParent);
}

View File

@ -168,6 +168,8 @@ public:
LLUUID getTextureID() {return mMediaTextureID;}
void updateContextMenuParent(LLView* pNewParent);
protected:
void convertInputCoords(S32& x, S32& y);

View File

@ -129,11 +129,11 @@ void LLInboxFolderViewFolder::addItem(LLFolderViewItem* item)
// virtual
void LLInboxFolderViewFolder::draw()
{
if (!badgeHasParent())
if (!hasBadgeHolderParent())
{
addBadgeToParentPanel();
addBadgeToParentHolder();
}
setBadgeVisibility(mFresh);
LLFolderViewFolder::draw();
@ -214,9 +214,9 @@ BOOL LLInboxFolderViewItem::handleDoubleClick(S32 x, S32 y, MASK mask)
// virtual
void LLInboxFolderViewItem::draw()
{
if (!badgeHasParent())
if (!hasBadgeHolderParent())
{
addBadgeToParentPanel();
addBadgeToParentHolder();
}
setBadgeVisibility(mFresh);

View File

@ -159,6 +159,7 @@ public:
registrar.add("Wearable.Create", boost::bind(onCreate, _2));
llassert(LLMenuGL::sMenuContainer != NULL);
LLToggleableMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(
"menu_cof_gear.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
llassert(menu);
@ -228,6 +229,7 @@ public:
enable_registrar.add("AddWearable.Gear.Check", boost::bind(onCheck, flat_list_handle, inventory_panel_handle, _2));
enable_registrar.add("AddWearable.Gear.Visible", boost::bind(onVisible, inventory_panel_handle, _2));
llassert(LLMenuGL::sMenuContainer != NULL);
LLToggleableMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(
"menu_add_wearable_gear.xml",
LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());

View File

@ -341,6 +341,7 @@ LLContextMenu* LLTeleportHistoryPanel::ContextMenu::createMenu()
registrar.add("TeleportHistory.CopyToClipboard",boost::bind(&LLTeleportHistoryPanel::ContextMenu::onCopyToClipboard, this));
// create the context menu from the XUI
llassert(LLMenuGL::sMenuContainer != NULL);
return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
"menu_teleport_history_item.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
}
@ -935,6 +936,7 @@ void LLTeleportHistoryPanel::onAccordionTabRightClick(LLView *view, S32 x, S32 y
registrar.add("TeleportHistory.TabClose", boost::bind(&LLTeleportHistoryPanel::onAccordionTabClose, this, tab));
// create the context menu from the XUI
llassert(LLMenuGL::sMenuContainer != NULL);
mAccordionTabMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
"menu_teleport_history_tab.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());

View File

@ -273,6 +273,14 @@ void LLScreenChannel::addToast(const LLToast::Params& p)
// only cancel notification if it isn't being used in IM session
LLNotifications::instance().cancel(notification);
}
// It was assumed that the toast would take ownership of the panel pointer.
// But since we have decided not to display the toast, kill the panel to
// prevent the memory leak.
if (p.panel != NULL)
{
p.panel()->die();
}
return;
}

View File

@ -640,12 +640,26 @@ class LLVolumeGeometryManager: public LLGeometryManager
DISTANCE_SORT
} eSortType;
virtual ~LLVolumeGeometryManager() { }
LLVolumeGeometryManager();
virtual ~LLVolumeGeometryManager();
virtual void rebuildGeom(LLSpatialGroup* group);
virtual void rebuildMesh(LLSpatialGroup* group);
virtual void getGeometry(LLSpatialGroup* group);
void genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE, BOOL no_materials = FALSE);
void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type);
private:
void allocateFaces(U32 pMaxFaceCount);
void freeFaces();
static int32_t sInstanceCount;
static LLFace** sFullbrightFaces;
static LLFace** sBumpFaces;
static LLFace** sSimpleFaces;
static LLFace** sNormFaces;
static LLFace** sSpecFaces;
static LLFace** sNormSpecFaces;
static LLFace** sAlphaFaces;
};
//spatial partition that uses volume geometry manager (implemented in LLVOVolume.cpp)

View File

@ -54,6 +54,7 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif
mAvatarName = getChild<LLTextBox>("user_name");
mTime = getChild<LLTextBox>("time_box");
mMessage = getChild<LLTextBox>("message");
mMessage->setContentTrusted(false);
LLStyle::Params style_params;
LLFontGL* fontp = LLViewerChat::getChatFont();

View File

@ -270,8 +270,12 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
// customize panel's attributes
// is it intended for displaying a tip?
mIsTip = mNotification->getType() == "notifytip";
std::string notif_name = mNotification->getName();
// is it a script dialog?
mIsScriptDialog = (mNotification->getName() == "ScriptDialog" || mNotification->getName() == "ScriptDialogGroup");
mIsScriptDialog = (notif_name == "ScriptDialog" || notif_name == "ScriptDialogGroup");
bool is_content_trusted = (notif_name != "LoadWebPage");
// is it a caution?
//
// caution flag can be set explicitly by specifying it in the notification payload, or it can be set implicitly if the
@ -314,6 +318,7 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
mTextBox->setMaxTextLength(MAX_LENGTH);
mTextBox->setVisible(TRUE);
mTextBox->setPlainText(!show_images);
mTextBox->setContentTrusted(is_content_trusted);
mTextBox->setValue(mNotification->getMessage());
mTextBox->setIsFriendCallback(LLAvatarActions::isFriend);

View File

@ -1593,6 +1593,17 @@ void LLViewerMedia::cleanupClass()
{
gIdleCallbacks.deleteFunction(LLViewerMedia::updateMedia, NULL);
sTeleportFinishConnection.disconnect();
if (sSpareBrowserMediaSource != NULL)
{
delete sSpareBrowserMediaSource;
sSpareBrowserMediaSource = NULL;
}
if (sCookieStore != NULL)
{
delete sCookieStore;
sCookieStore = NULL;
}
}
//////////////////////////////////////////////////////////////////////////////////////////

View File

@ -355,6 +355,16 @@ LLViewerShaderMgr * LLViewerShaderMgr::instance()
return static_cast<LLViewerShaderMgr*>(sInstance);
}
// static
void LLViewerShaderMgr::releaseInstance()
{
if (sInstance != NULL)
{
delete sInstance;
sInstance = NULL;
}
}
void LLViewerShaderMgr::initAttribsAndUniforms(void)
{
if (mReservedAttribs.empty())

View File

@ -43,6 +43,7 @@ public:
// singleton pattern implementation
static LLViewerShaderMgr * instance();
static void releaseInstance();
void initAttribsAndUniforms(void);
void setShaders();

View File

@ -261,7 +261,7 @@ std::string LLViewerWindow::sMovieBaseName;
LLTrace::SampleStatHandle<> LLViewerWindow::sMouseVelocityStat("Mouse Velocity");
class RecordToChatConsole : public LLError::Recorder, public LLSingleton<RecordToChatConsole>
class RecordToChatConsoleRecorder : public LLError::Recorder
{
public:
virtual void recordMessage(LLError::ELevel level,
@ -285,6 +285,22 @@ public:
}
};
class RecordToChatConsole : public LLSingleton<RecordToChatConsole>
{
public:
RecordToChatConsole()
: LLSingleton<RecordToChatConsole>(),
mRecorder(new RecordToChatConsoleRecorder())
{
}
void startRecorder() { LLError::addRecorder(mRecorder); }
void stopRecorder() { LLError::removeRecorder(mRecorder); }
private:
LLError::RecorderPtr mRecorder;
};
////////////////////////////////////////////////////////////////////////////
//
// LLDebugText
@ -1886,11 +1902,11 @@ void LLViewerWindow::initBase()
// optionally forward warnings to chat console/chat floater
// for qa runs and dev builds
#if !LL_RELEASE_FOR_DOWNLOAD
LLError::addRecorder(RecordToChatConsole::getInstance());
RecordToChatConsole::getInstance()->startRecorder();
#else
if(gSavedSettings.getBOOL("QAMode"))
{
LLError::addRecorder(RecordToChatConsole::getInstance());
RecordToChatConsole::getInstance()->startRecorder();
}
#endif
@ -1907,9 +1923,7 @@ void LLViewerWindow::initBase()
setProgressCancelButtonVisible(FALSE);
gMenuHolder = getRootView()->getChild<LLViewerMenuHolderGL>("Menu Holder");
LLMenuGL::sMenuContainer = gMenuHolder;
}
void LLViewerWindow::initWorldUI()
@ -2039,8 +2053,7 @@ void LLViewerWindow::initWorldUI()
void LLViewerWindow::shutdownViews()
{
// clean up warning logger
LLError::removeRecorder(RecordToChatConsole::getInstance());
RecordToChatConsole::getInstance()->stopRecorder();
LL_INFOS() << "Warning logger is cleaned." << LL_ENDL ;
delete mDebugText;
@ -2075,6 +2088,9 @@ void LLViewerWindow::shutdownViews()
// access to gMenuHolder
cleanup_menus();
LL_INFOS() << "menus destroyed." << LL_ENDL ;
view_listener_t::cleanup();
LL_INFOS() << "view listeners destroyed." << LL_ENDL ;
// Delete all child views.
delete mRootView;
@ -2150,6 +2166,12 @@ LLViewerWindow::~LLViewerWindow()
delete mDebugText;
mDebugText = NULL;
if (LLViewerShaderMgr::sInitialized)
{
LLViewerShaderMgr::releaseInstance();
LLViewerShaderMgr::sInitialized = FALSE;
}
}

View File

@ -1917,7 +1917,10 @@ BOOL LLVOAvatarSelf::getIsCloud() const
/*static*/
void LLVOAvatarSelf::debugOnTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata)
{
gAgentAvatarp->debugTimingLocalTexLoaded(success, src_vi, src, aux_src, discard_level, final, userdata);
if (gAgentAvatarp.notNull())
{
gAgentAvatarp->debugTimingLocalTexLoaded(success, src_vi, src, aux_src, discard_level, final, userdata);
}
}
void LLVOAvatarSelf::debugTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata)

View File

@ -4059,7 +4059,8 @@ U32 LLVOVolume::getPartitionType() const
}
LLVolumePartition::LLVolumePartition(LLViewerRegion* regionp)
: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB, regionp)
: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB, regionp),
LLVolumeGeometryManager()
{
mLODPeriod = 32;
mDepthMask = FALSE;
@ -4070,7 +4071,8 @@ LLVolumePartition::LLVolumePartition(LLViewerRegion* regionp)
}
LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep, LLViewerRegion* regionp)
: LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK, regionp)
: LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK, regionp),
LLVolumeGeometryManager()
{
mDepthMask = FALSE;
mLODPeriod = 32;
@ -4107,6 +4109,70 @@ bool can_batch_texture(LLFace* facep)
return true;
}
const static U32 MAX_FACE_COUNT = 4096U;
int32_t LLVolumeGeometryManager::sInstanceCount = 0;
LLFace** LLVolumeGeometryManager::sFullbrightFaces = NULL;
LLFace** LLVolumeGeometryManager::sBumpFaces = NULL;
LLFace** LLVolumeGeometryManager::sSimpleFaces = NULL;
LLFace** LLVolumeGeometryManager::sNormFaces = NULL;
LLFace** LLVolumeGeometryManager::sSpecFaces = NULL;
LLFace** LLVolumeGeometryManager::sNormSpecFaces = NULL;
LLFace** LLVolumeGeometryManager::sAlphaFaces = NULL;
LLVolumeGeometryManager::LLVolumeGeometryManager()
: LLGeometryManager()
{
llassert(sInstanceCount >= 0);
if (sInstanceCount == 0)
{
allocateFaces(MAX_FACE_COUNT);
}
++sInstanceCount;
}
LLVolumeGeometryManager::~LLVolumeGeometryManager()
{
llassert(sInstanceCount > 0);
--sInstanceCount;
if (sInstanceCount <= 0)
{
freeFaces();
sInstanceCount = 0;
}
}
void LLVolumeGeometryManager::allocateFaces(U32 pMaxFaceCount)
{
sFullbrightFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*)));
sBumpFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*)));
sSimpleFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*)));
sNormFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*)));
sSpecFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*)));
sNormSpecFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*)));
sAlphaFaces = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount*sizeof(LLFace*)));
}
void LLVolumeGeometryManager::freeFaces()
{
ll_aligned_free<64>(sFullbrightFaces);
ll_aligned_free<64>(sBumpFaces);
ll_aligned_free<64>(sSimpleFaces);
ll_aligned_free<64>(sNormFaces);
ll_aligned_free<64>(sSpecFaces);
ll_aligned_free<64>(sNormSpecFaces);
ll_aligned_free<64>(sAlphaFaces);
sFullbrightFaces = NULL;
sBumpFaces = NULL;
sSimpleFaces = NULL;
sNormFaces = NULL;
sSpecFaces = NULL;
sNormSpecFaces = NULL;
sAlphaFaces = NULL;
}
static LLTrace::BlockTimerStatHandle FTM_REGISTER_FACE("Register Face");
void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type)
@ -4429,16 +4495,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
mFaceList.clear();
const U32 MAX_FACE_COUNT = 4096;
static LLFace** fullbright_faces = (LLFace**) ll_aligned_malloc<64>(MAX_FACE_COUNT*sizeof(LLFace*));
static LLFace** bump_faces = (LLFace**) ll_aligned_malloc<64>(MAX_FACE_COUNT*sizeof(LLFace*));
static LLFace** simple_faces = (LLFace**) ll_aligned_malloc<64>(MAX_FACE_COUNT*sizeof(LLFace*));
static LLFace** norm_faces = (LLFace**) ll_aligned_malloc<64>(MAX_FACE_COUNT*sizeof(LLFace*));
static LLFace** spec_faces = (LLFace**) ll_aligned_malloc<64>(MAX_FACE_COUNT*sizeof(LLFace*));
static LLFace** normspec_faces = (LLFace**) ll_aligned_malloc<64>(MAX_FACE_COUNT*sizeof(LLFace*));
static LLFace** alpha_faces = (LLFace**) ll_aligned_malloc<64>(MAX_FACE_COUNT*sizeof(LLFace*));
U32 fullbright_count = 0;
U32 bump_count = 0;
U32 simple_count = 0;
@ -4816,7 +4872,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{ //can be treated as alpha mask
if (simple_count < MAX_FACE_COUNT)
{
simple_faces[simple_count++] = facep;
sSimpleFaces[simple_count++] = facep;
}
}
else
@ -4827,7 +4883,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
if (alpha_count < MAX_FACE_COUNT)
{
alpha_faces[alpha_count++] = facep;
sAlphaFaces[alpha_count++] = facep;
}
}
}
@ -4850,14 +4906,14 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{ //has normal and specular maps (needs texcoord1, texcoord2, and tangent)
if (normspec_count < MAX_FACE_COUNT)
{
normspec_faces[normspec_count++] = facep;
sNormSpecFaces[normspec_count++] = facep;
}
}
else
{ //has normal map (needs texcoord1 and tangent)
if (norm_count < MAX_FACE_COUNT)
{
norm_faces[norm_count++] = facep;
sNormFaces[norm_count++] = facep;
}
}
}
@ -4865,14 +4921,14 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{ //has specular map but no normal map, needs texcoord2
if (spec_count < MAX_FACE_COUNT)
{
spec_faces[spec_count++] = facep;
sSpecFaces[spec_count++] = facep;
}
}
else
{ //has neither specular map nor normal map, only needs texcoord0
if (simple_count < MAX_FACE_COUNT)
{
simple_faces[simple_count++] = facep;
sSimpleFaces[simple_count++] = facep;
}
}
}
@ -4880,14 +4936,14 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{ //needs normal + tangent
if (bump_count < MAX_FACE_COUNT)
{
bump_faces[bump_count++] = facep;
sBumpFaces[bump_count++] = facep;
}
}
else if (te->getShiny() || !te->getFullbright())
{ //needs normal
if (simple_count < MAX_FACE_COUNT)
{
simple_faces[simple_count++] = facep;
sSimpleFaces[simple_count++] = facep;
}
}
else
@ -4895,7 +4951,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
facep->setState(LLFace::FULLBRIGHT);
if (fullbright_count < MAX_FACE_COUNT)
{
fullbright_faces[fullbright_count++] = facep;
sFullbrightFaces[fullbright_count++] = facep;
}
}
}
@ -4905,7 +4961,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{ //needs normal + tangent
if (bump_count < MAX_FACE_COUNT)
{
bump_faces[bump_count++] = facep;
sBumpFaces[bump_count++] = facep;
}
}
else if ((te->getShiny() && LLPipeline::sRenderBump) ||
@ -4913,7 +4969,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{ //needs normal
if (simple_count < MAX_FACE_COUNT)
{
simple_faces[simple_count++] = facep;
sSimpleFaces[simple_count++] = facep;
}
}
else
@ -4921,7 +4977,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
facep->setState(LLFace::FULLBRIGHT);
if (fullbright_count < MAX_FACE_COUNT)
{
fullbright_faces[fullbright_count++] = facep;
sFullbrightFaces[fullbright_count++] = facep;
}
}
}
@ -4993,13 +5049,13 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX;
}
genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, simple_count, FALSE, batch_textures, FALSE);
genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, fullbright_count, FALSE, batch_textures);
genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, alpha_count, TRUE, batch_textures);
genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, bump_count, FALSE, FALSE);
genDrawInfo(group, norm_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, norm_faces, norm_count, FALSE, FALSE);
genDrawInfo(group, spec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, spec_faces, spec_count, FALSE, FALSE);
genDrawInfo(group, normspec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, normspec_faces, normspec_count, FALSE, FALSE);
genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sSimpleFaces, simple_count, FALSE, batch_textures, FALSE);
genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sFullbrightFaces, fullbright_count, FALSE, batch_textures);
genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sAlphaFaces, alpha_count, TRUE, batch_textures);
genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sBumpFaces, bump_count, FALSE, FALSE);
genDrawInfo(group, norm_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sNormFaces, norm_count, FALSE, FALSE);
genDrawInfo(group, spec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sSpecFaces, spec_count, FALSE, FALSE);
genDrawInfo(group, normspec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sNormSpecFaces, normspec_count, FALSE, FALSE);
if (!LLPipeline::sDelayVBUpdate)
{

View File

@ -45,7 +45,7 @@ public:
~LLMemoryReserve();
void reserve();
void release();
protected:
private:
unsigned char *mReserve;
static const size_t MEMORY_RESERVATION_SIZE;
};
@ -53,7 +53,7 @@ protected:
LLMemoryReserve::LLMemoryReserve() :
mReserve(NULL)
{
};
}
LLMemoryReserve::~LLMemoryReserve()
{
@ -66,14 +66,19 @@ const size_t LLMemoryReserve::MEMORY_RESERVATION_SIZE = 5 * 1024 * 1024;
void LLMemoryReserve::reserve()
{
if(NULL == mReserve)
{
mReserve = new unsigned char[MEMORY_RESERVATION_SIZE];
};
}
}
void LLMemoryReserve::release()
{
delete [] mReserve;
if (NULL != mReserve)
{
delete [] mReserve;
}
mReserve = NULL;
};
}
static LLMemoryReserve gEmergencyMemoryReserve;
@ -130,6 +135,11 @@ void LLWinDebug::init()
}
}
void LLWinDebug::cleanup ()
{
gEmergencyMemoryReserve.release();
}
void LLWinDebug::writeDumpToFile(MINIDUMP_TYPE type, MINIDUMP_EXCEPTION_INFORMATION *ExInfop, const std::string& filename)
{
// Temporary fix to switch out the code that writes the DMP file.

View File

@ -37,6 +37,7 @@ class LLWinDebug:
public:
static void init();
static void generateMinidump(struct _EXCEPTION_POINTERS *pExceptionInfo = NULL);
static void cleanup();
private:
static void writeDumpToFile(MINIDUMP_TYPE type, MINIDUMP_EXCEPTION_INFORMATION *ExInfop, const std::string& filename);
};

View File

@ -95,25 +95,20 @@ public:
virtual void replay(std::ostream&) {}
};
class LLReplayLogReal: public LLReplayLog, public LLError::Recorder, public boost::noncopyable
class RecordToTempFile : public LLError::Recorder, public boost::noncopyable
{
public:
LLReplayLogReal(LLError::ELevel level, apr_pool_t* pool):
mOldSettings(LLError::saveAndResetSettings()),
mProxy(new RecorderProxy(this)),
mTempFile("log", "", pool), // create file
mFile(mTempFile.getName().c_str()) // open it
RecordToTempFile(apr_pool_t* pPool)
: LLError::Recorder(),
boost::noncopyable(),
mTempFile("log", "", pPool),
mFile(mTempFile.getName().c_str())
{
LLError::setFatalFunction(wouldHaveCrashed);
LLError::setDefaultLevel(level);
LLError::addRecorder(mProxy);
}
virtual ~LLReplayLogReal()
virtual ~RecordToTempFile()
{
LLError::removeRecorder(mProxy);
delete mProxy;
LLError::restoreSettings(mOldSettings);
mFile.close();
}
virtual void recordMessage(LLError::ELevel level, const std::string& message)
@ -121,13 +116,13 @@ public:
mFile << message << std::endl;
}
virtual void reset()
void reset()
{
mFile.close();
mFile.open(mTempFile.getName().c_str());
}
virtual void replay(std::ostream& out)
void replay(std::ostream& out)
{
mFile.close();
std::ifstream inf(mTempFile.getName().c_str());
@ -139,12 +134,45 @@ public:
}
private:
LLError::Settings* mOldSettings;
LLError::Recorder* mProxy;
NamedTempFile mTempFile;
std::ofstream mFile;
};
class LLReplayLogReal: public LLReplayLog, public boost::noncopyable
{
public:
LLReplayLogReal(LLError::ELevel level, apr_pool_t* pool)
: LLReplayLog(),
boost::noncopyable(),
mOldSettings(LLError::saveAndResetSettings()),
mRecorder(new RecordToTempFile(pool))
{
LLError::setFatalFunction(wouldHaveCrashed);
LLError::setDefaultLevel(level);
LLError::addRecorder(mRecorder);
}
virtual ~LLReplayLogReal()
{
LLError::removeRecorder(mRecorder);
LLError::restoreSettings(mOldSettings);
}
virtual void reset()
{
boost::dynamic_pointer_cast<RecordToTempFile>(mRecorder)->reset();
}
virtual void replay(std::ostream& out)
{
boost::dynamic_pointer_cast<RecordToTempFile>(mRecorder)->replay(out);
}
private:
LLError::SettingsStoragePtr mOldSettings;
LLError::RecorderPtr mRecorder;
};
class LLTestCallback : public tut::callback
{
public: