diff options
author | Merov Linden <merov@lindenlab.com> | 2014-06-17 09:50:48 -0700 |
---|---|---|
committer | Merov Linden <merov@lindenlab.com> | 2014-06-17 09:50:48 -0700 |
commit | 9c792f03b4f006f5083c9fc98047bfad6bee8e16 (patch) | |
tree | 5e15865f837e4d7815000b79452f4bdd7245d511 /indra | |
parent | f79b1139fd28b29c51a0c001960ef3f0bb999ec0 (diff) | |
parent | 977476171ddcc057d7c28b6c14ae988b8189ed75 (diff) |
Pull merge from lindenlab/viewer-release
Diffstat (limited to 'indra')
79 files changed, 1088 insertions, 601 deletions
diff --git a/indra/llappearance/lldriverparam.cpp b/indra/llappearance/lldriverparam.cpp index 08084d3fe4..e630c1118b 100755 --- a/indra/llappearance/lldriverparam.cpp +++ b/indra/llappearance/lldriverparam.cpp @@ -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) diff --git a/indra/llappearance/lldriverparam.h b/indra/llappearance/lldriverparam.h index 83301218dd..f71c930e5e 100755 --- a/indra/llappearance/lldriverparam.h +++ b/indra/llappearance/lldriverparam.h @@ -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); diff --git a/indra/llappearance/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp index 5224e3e3e1..e3992a080e 100644 --- a/indra/llappearance/llpolymorph.cpp +++ b/indra/llappearance/llpolymorph.cpp @@ -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) +{ + 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) { - mWeights = new F32[morph_data->mNumIndices]; - mMorphData = morph_data; - mWeightsGenerated = FALSE; + 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; } //----------------------------------------------------------------------------- diff --git a/indra/llappearance/llpolymorph.h b/indra/llappearance/llpolymorph.h index ee380ae7c3..7e712f9e94 100644 --- a/indra/llappearance/llpolymorph.h +++ b/indra/llappearance/llpolymorph.h @@ -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; diff --git a/indra/llappearance/llpolyskeletaldistortion.cpp b/indra/llappearance/llpolyskeletaldistortion.cpp index 4e2aa16762..ea29cbd451 100644 --- a/indra/llappearance/llpolyskeletaldistortion.cpp +++ b/indra/llappearance/llpolyskeletaldistortion.cpp @@ -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); } //----------------------------------------------------------------------------- diff --git a/indra/llappearance/llpolyskeletaldistortion.h b/indra/llappearance/llpolyskeletaldistortion.h index 24c9e9ae48..ea2adb8a87 100644 --- a/indra/llappearance/llpolyskeletaldistortion.h +++ b/indra/llappearance/llpolyskeletaldistortion.h @@ -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; diff --git a/indra/llappearance/lltexglobalcolor.cpp b/indra/llappearance/lltexglobalcolor.cpp index 633da4b851..3df2254b14 100755 --- a/indra/llappearance/lltexglobalcolor.cpp +++ b/indra/llappearance/lltexglobalcolor.cpp @@ -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() diff --git a/indra/llappearance/lltexglobalcolor.h b/indra/llappearance/lltexglobalcolor.h index 1b0c91b5ca..3b426053de 100755 --- a/indra/llappearance/lltexglobalcolor.h +++ b/indra/llappearance/lltexglobalcolor.h @@ -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; diff --git a/indra/llappearance/lltexlayerparams.cpp b/indra/llappearance/lltexlayerparams.cpp index 4da5cf54e8..ff682d6906 100755 --- a/indra/llappearance/lltexlayerparams.cpp +++ b/indra/llappearance/lltexlayerparams.cpp @@ -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 diff --git a/indra/llappearance/lltexlayerparams.h b/indra/llappearance/lltexlayerparams.h index e1a8c28265..0cb2dedbff 100755 --- a/indra/llappearance/lltexlayerparams.h +++ b/indra/llappearance/lltexlayerparams.h @@ -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); diff --git a/indra/llappearance/llviewervisualparam.cpp b/indra/llappearance/llviewervisualparam.cpp index 0d8d1dbeca..af8394b60c 100644 --- a/indra/llappearance/llviewervisualparam.cpp +++ b/indra/llappearance/llviewervisualparam.cpp @@ -123,6 +123,22 @@ BOOL LLViewerVisualParamInfo::parseXml(LLXmlTreeNode *node) // LLViewerVisualParam() //----------------------------------------------------------------------------- LLViewerVisualParam::LLViewerVisualParam() + : LLVisualParam() +{ +} + +//----------------------------------------------------------------------------- +// LLViewerVisualParam() +//----------------------------------------------------------------------------- +LLViewerVisualParam::LLViewerVisualParam(const LLViewerVisualParam& pOther) + : LLVisualParam(pOther) +{ +} + +//----------------------------------------------------------------------------- +// ~LLViewerVisualParam() +//----------------------------------------------------------------------------- +LLViewerVisualParam::~LLViewerVisualParam() { } diff --git a/indra/llappearance/llviewervisualparam.h b/indra/llappearance/llviewervisualparam.h index 2826e6c316..1a710c0ca6 100644 --- a/indra/llappearance/llviewervisualparam.h +++ b/indra/llappearance/llviewervisualparam.h @@ -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 diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp index bacbc09aee..4bce3f99ed 100755 --- a/indra/llappearance/llwearable.cpp +++ b/indra/llappearance/llwearable.cpp @@ -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(); } diff --git a/indra/llappearance/llwearable.h b/indra/llappearance/llwearable.h index 3e8bd2ca5d..406fc7e883 100755 --- a/indra/llappearance/llwearable.h +++ b/indra/llappearance/llwearable.h @@ -46,6 +46,7 @@ class LLWearable // Constructors and destructors //-------------------------------------------------------------------- public: + LLWearable(); virtual ~LLWearable(); //-------------------------------------------------------------------- diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp index 50ccfd75fb..e02b139608 100755 --- a/indra/llcharacter/llmotioncontroller.cpp +++ b/indra/llcharacter/llmotioncontroller.cpp @@ -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(); } //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/llvisualparam.cpp b/indra/llcharacter/llvisualparam.cpp index 17c003d07e..2235496ac5 100755 --- a/indra/llcharacter/llvisualparam.cpp +++ b/indra/llcharacter/llvisualparam.cpp @@ -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; } /* @@ -285,6 +301,14 @@ void LLVisualParam::setNextParam( LLVisualParam *next ) } //----------------------------------------------------------------------------- +// clearNextParam() +//----------------------------------------------------------------------------- +void LLVisualParam::clearNextParam() +{ + mNext = NULL; +} + +//----------------------------------------------------------------------------- // animate() //----------------------------------------------------------------------------- void LLVisualParam::animate( F32 delta) diff --git a/indra/llcharacter/llvisualparam.h b/indra/llcharacter/llvisualparam.h index 6c3bf2901a..c6b97d7e8b 100755 --- a/indra/llcharacter/llvisualparam.h +++ b/indra/llcharacter/llvisualparam.h @@ -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 diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index a7963174ad..22cd861c72 100755 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -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; } - - void Settings::reset() + + SettingsConfig::~SettingsConfig() { - Globals::get().invalidateCallSites(); - - Settings*& p = getPtr(); - delete p; - p = new Settings(); + mRecorders.clear(); + } + + Settings::Settings() + : LLSingleton<Settings>(), + mSettingsConfig(new SettingsConfig()) + { + } + + SettingsConfigPtr Settings::getSettingsConfig() + { + return mSettingsConfig; } - Settings* Settings::saveAndReset() + void Settings::reset() { - Globals::get().invalidateCallSites(); - - Settings*& p = getPtr(); - Settings* originalSettings = p; - p = new Settings(); - return originalSettings; + Globals::getInstance()->invalidateCallSites(); + mSettingsConfig = new SettingsConfig(); } - void Settings::restore(Settings* originalSettings) + SettingsStoragePtr Settings::saveAndReset() { - Globals::get().invalidateCallSites(); - - Settings*& p = getPtr(); - delete p; - p = originalSettings; + SettingsStoragePtr oldSettingsConfig(mSettingsConfig.get()); + reset(); + return oldSettingsConfig; } - Settings*& Settings::getPtr() + void Settings::restore(SettingsStoragePtr pSettingsStorage) { - 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(); + } } diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index bc80e64423..63040e1772 100755 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -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(); }; } diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h index aab695094c..56ac52e5de 100755 --- a/indra/llcommon/llerrorcontrol.h +++ b/indra/llcommon/llerrorcontrol.h @@ -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*! - */ - LL_COMMON_API void addRecorder(Recorder*); - /** - * @NOTE: removeRecorder() reclaims ownership of the Recorder*: its - * lifespan becomes the caller's problem. + * @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 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(); diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h index 2532566319..7aa87fcd0e 100755 --- a/indra/llcommon/llinitparam.h +++ b/indra/llcommon/llinitparam.h @@ -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 diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp index b28c5ba4b3..a5aaff10c5 100755 --- a/indra/llcommon/tests/llerror_test.cpp +++ b/indra/llcommon/tests/llerror_test.cpp @@ -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); } } diff --git a/indra/llcommon/tests/wrapllerrs.h b/indra/llcommon/tests/wrapllerrs.h index 3137bd8fea..785197ba11 100755 --- a/indra/llcommon/tests/wrapllerrs.h +++ b/indra/llcommon/tests/wrapllerrs.h @@ -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); } diff --git a/indra/llmessage/llares.cpp b/indra/llmessage/llares.cpp index 81e28121fd..9f90ae1544 100755 --- a/indra/llmessage/llares.cpp +++ b/indra/llmessage/llares.cpp @@ -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(), diff --git a/indra/llmessage/llares.h b/indra/llmessage/llares.h index 800781ee88..0b5d49e322 100755 --- a/indra/llmessage/llares.h +++ b/indra/llmessage/llares.h @@ -578,5 +578,6 @@ extern LLAres *gAres; * thread safe. */ extern LLAres *ll_init_ares(); +extern void ll_cleanup_ares(); #endif // LL_LLARES_H diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index a80d5a570e..73df47b933 100755 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -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 ; diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index bd6b0b3fd4..385d9fffa8 100755 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -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 diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index 801cf83fae..a8c3b86192 100755 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -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; } diff --git a/indra/llplugin/llplugincookiestore.cpp b/indra/llplugin/llplugincookiestore.cpp index f64b264222..a5d717389d 100755 --- a/indra/llplugin/llplugincookiestore.cpp +++ b/indra/llplugin/llplugincookiestore.cpp @@ -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) diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index ea0d2b81f1..b5a2588e1e 100755 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -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); diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index ddf38c6745..ebed454271 100755 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -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,6 +1883,37 @@ void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h) } //---------------------------------------------------------------------------- +U32 LLImageGL::createPickMask(S32 pWidth, S32 pHeight) +{ + 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 + mPickMask = new U8[size]; + claimMem(size); + mPickMaskWidth = pick_width - 1; + mPickMaskHeight = pick_height - 1; + + 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) @@ -1893,10 +1921,7 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in) return ; } - disclaimMem((mPickMaskWidth * mPickMaskHeight + 7) / 8); - delete [] mPickMask; - mPickMask = NULL; - mPickMaskWidth = mPickMaskHeight = 0; + freePickMask(); if (mFormatType != GL_UNSIGNED_BYTE || mFormatPrimary != GL_RGBA) @@ -1905,17 +1930,11 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in) return; } - U32 pick_width = width/2 + 1; - U32 pick_height = height/2 + 1; - - U32 size = pick_width * pick_height; - size = (size + 7) / 8; // pixelcount-to-bits - mPickMask = new U8[size]; - claimMem(size); - mPickMaskWidth = pick_width - 1; - mPickMaskHeight = pick_height - 1; - - memset(mPickMask, 0, sizeof(U8) * size); +#ifdef SHOW_ASSERT + const U32 pickSize = createPickMask(width, height); +#else // SHOW_ASSERT + createPickMask(width, height); +#endif // SHOW_ASSERT U32 pick_bit = 0; @@ -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; } diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 6ca814af6f..21982eab1d 100755 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -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; diff --git a/indra/llui/llbadgeowner.cpp b/indra/llui/llbadgeowner.cpp index 1860a05edd..55e64bb940 100755 --- a/indra/llui/llbadgeowner.cpp +++ b/indra/llui/llbadgeowner.cpp @@ -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); - } -} - -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(); + mHasBadgeHolderParent = false; - 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) diff --git a/indra/llui/llbadgeowner.h b/indra/llui/llbadgeowner.h index 8d03e30645..53c2de95c8 100755 --- a/indra/llui/llbadgeowner.h +++ b/indra/llui/llbadgeowner.h @@ -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; }; diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 093d91d44d..ce8383857c 100755 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -384,7 +384,7 @@ BOOL LLButton::postBuild() { autoResize(); - addBadgeToParentPanel(); + addBadgeToParentHolder(); return LLUICtrl::postBuild(); } diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index 2fb57d55e7..692f3965f1 100755 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -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) { diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index d410a2de33..b09c927782 100755 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -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, diff --git a/indra/llui/llmenubutton.cpp b/indra/llui/llmenubutton.cpp index 0609cd8b42..303afcda15 100755 --- a/indra/llui/llmenubutton.cpp +++ b/indra/llui/llmenubutton.cpp @@ -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) { diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 7383a8c307..604dc92789 100755 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -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; diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index feafaab199..ae9b169691 100755 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -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 diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 3708071e11..5f72ee3ac6 100755 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -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) diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index ebc6183b8b..6f858cdeb3 100755 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -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) diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 62edbadb07..8906a6e736 100755 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -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()) diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index d1f66b6cfe..ecbfdaf84c 100755 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -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 diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index c797b6acc5..b4ebed0849 100755 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -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()); diff --git a/indra/llui/lltextutil.cpp b/indra/llui/lltextutil.cpp index 4df2c3363f..fff04b34f2 100755 --- a/indra/llui/lltextutil.cpp +++ b/indra/llui/lltextutil.cpp @@ -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) diff --git a/indra/llui/lltextutil.h b/indra/llui/lltextutil.h index bf7dbb58ce..798f14d086 100755 --- a/indra/llui/lltextutil.h +++ b/indra/llui/lltextutil.h @@ -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 { diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp index f9bdd87087..abc2b6e9ca 100755 --- a/indra/llui/lltoolbar.cpp +++ b/indra/llui/lltoolbar.cpp @@ -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) diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index 523ee5d78c..bccc646821 100755 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -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; diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h index da16171a97..6270df1bbb 100755 --- a/indra/llui/llurlregistry.h +++ b/indra/llui/llurlregistry.h @@ -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 diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 0637572f67..19961d5759 100755 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -657,7 +657,7 @@ LLWindowWin32::~LLWindowWin32() delete [] mSupportedResolutions; mSupportedResolutions = NULL; - delete mWindowClassName; + delete [] mWindowClassName; mWindowClassName = NULL; } diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index c77a7de85c..f06fb9e915 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -3.7.9 +3.7.10 diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index f98ec69732..f52e6625c1 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -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; diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 06f081e920..57fb84bbf1 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -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(); } diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h index fb37df1a2f..59d1ddaa3d 100644 --- a/indra/newview/llappviewerwin32.h +++ b/indra/newview/llappviewerwin32.h @@ -61,7 +61,8 @@ protected: private: void disableWinErrorReporting(); - std::string mCmdLine; + std::string mCmdLine; + bool mIsConsoleAllocated; }; #endif // LL_LLAPPVIEWERWIN32_H diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 05c4181714..84b9ac756a 100755 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -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) - { - // *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)); - } - } - - if (!sInfoCtrl) + const bool isVisible = !mAvatarID.isNull() && !mFrom.empty() && CHAT_SOURCE_SYSTEM != mSourceType; + if (isVisible) { - llassert(sInfoCtrl != NULL); - return; + 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 ) ; } - - 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), diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h index bb6d4fb59c..44736a0489 100755 --- a/indra/newview/llchathistory.h +++ b/indra/newview/llchathistory.h @@ -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; diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index fd4f17b694..cfc62c07b6 100755 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -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 { diff --git a/indra/newview/llchatitemscontainerctrl.h b/indra/newview/llchatitemscontainerctrl.h index 54b6499d52..f66670ec8c 100755 --- a/indra/newview/llchatitemscontainerctrl.h +++ b/indra/newview/llchatitemscontainerctrl.h @@ -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; diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index b1dce42dfd..c0823182c0 100755 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -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, diff --git a/indra/newview/lllistcontextmenu.cpp b/indra/newview/lllistcontextmenu.cpp index a624c9fb87..6bda8b1d0d 100755 --- a/indra/newview/lllistcontextmenu.cpp +++ b/indra/newview/lllistcontextmenu.cpp @@ -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()); } diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index f406bb9f06..0178512cb5 100755 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -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); +} diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 5978a7a344..b07eb356ae 100755 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -168,6 +168,8 @@ public: LLUUID getTextureID() {return mMediaTextureID;} + void updateContextMenuParent(LLView* pNewParent); + protected: void convertInputCoords(S32& x, S32& y); diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp index 2f65bedc2b..f7c2f629ec 100755 --- a/indra/newview/llpanelmarketplaceinboxinventory.cpp +++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp @@ -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); diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 8ccbb03fcc..496168229d 100755 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -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()); diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index 8fddd9523f..652d2be6f6 100755 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -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()); diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index 6a840f3f40..8708fb87ee 100755 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -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; } diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index a7b99a0f6b..08a4d00d0f 100755 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -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) diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp index a27105e22d..39adfb3431 100755 --- a/indra/newview/lltoastimpanel.cpp +++ b/indra/newview/lltoastimpanel.cpp @@ -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(); diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index 51935dc03b..907baf0661 100755 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -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); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 7aa0af5d93..ed26842035 100755 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -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; + } } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 9d2a4a50e1..dafe2cafec 100755 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -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()) diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 42147fdd29..923aa522ad 100755 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -43,6 +43,7 @@ public: // singleton pattern implementation static LLViewerShaderMgr * instance(); + static void releaseInstance(); void initAttribsAndUniforms(void); void setShaders(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index b2b5c9d903..d052906bee 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -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; + } } diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 1f497bc107..42a7c2e576 100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -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) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index c9f03a3b7d..945d3711f0 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -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) { diff --git a/indra/newview/llwindebug.cpp b/indra/newview/llwindebug.cpp index 551d0be8d7..eff70ca0b2 100755 --- a/indra/newview/llwindebug.cpp +++ b/indra/newview/llwindebug.cpp @@ -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. diff --git a/indra/newview/llwindebug.h b/indra/newview/llwindebug.h index 6f274c6f16..a3cbf6dc03 100755 --- a/indra/newview/llwindebug.h +++ b/indra/newview/llwindebug.h @@ -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); }; diff --git a/indra/test/test.cpp b/indra/test/test.cpp index 10f71a2843..e42374d56b 100755 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -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: |