From ef490e308ccce8e6df85144784a0f4580f5ac6a1 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Sat, 5 Feb 2011 15:58:07 +0100 Subject: Introduces a LLThreadLocalData class that can be accessed through the static LLThread::tldata(). Currently this object contains two (public) thread-local objects: a LLAPRRootPool and a LLVolatileAPRPool. The first is the general memory pool used by this thread (and this thread alone), while the second is intended for short lived memory allocations (needed for APR). The advantages of not mixing those two is that the latter is used most frequently, and as a result of it's nature can be destroyed and reconstructed on a "regular" basis. This patch adds LLAPRPool (completely replacing the old one), which is a wrapper around apr_pool_t* and has complete thread-safity checking. Whenever an apr call requires memory for some resource, a memory pool in the form of an LLAPRPool object can be created with the same life-time as this resource; assuring clean up of the memory no sooner, but also not much later than the life-time of the resource that needs the memory. Many, many function calls and constructors had the pool parameter simply removed (it is no longer the concern of the developer, if you don't write code that actually does an libapr call then you are no longer bothered with memory pools at all). However, I kept the notion of short-lived and long-lived allocations alive (see my remark in the jira here: https://jira.secondlife.com/browse/STORM-864?focusedCommentId=235356&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-235356 which requires that the LLAPRFile API needs to allow the user to specify how long they think a file will stay open. By choosing 'short_lived' as default for the constructor that immediately opens a file, the number of instances where this needs to be specified is drastically reduced however (obviously, any automatic LLAPRFile is short lived). *** Addressed Boroondas remarks in https://codereview.secondlife.com/r/99/ regarding (doxygen) comments. This patch effectively only changes comments. Includes some 'merge' stuff that ended up in llvocache.cpp (while starting as a bug fix, now only resulting in a cleanup). *** Added comment 'The use of apr_pool_t is OK here'. Added this comment on every line where apr_pool_t is correctly being used. This should make it easier to spot (future) errors where someone started to use apr_pool_t; you can just grep all sources for 'apr_pool_t' and immediately see where it's being used while LLAPRPool should have been used. Note that merging this patch is very easy: If there are no other uses of apr_pool_t in the code (one grep) and it compiles, then it will work. *** Second Merge (needed to remove 'delete mCreationMutex' from LLImageDecodeThread::~LLImageDecodeThread). *** Added back #include . Apparently that is needed on libapr version 1.2.8., the version used by Linden Lab, for calls to apr_queue_*. This is a bug in libapr (we also include , that is fixed in (at least) 1.3.7. Note that 1.2.8 is VERY old. Even 1.3.x is old. *** License fixes (GPL -> LGPL). And typo in comments. Addresses merov's comments on the review board. *** Added Merov's compile fixes for windows. --- indra/llmath/llvolumemgr.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolumemgr.cpp b/indra/llmath/llvolumemgr.cpp index 88c195936c..734440d312 100644 --- a/indra/llmath/llvolumemgr.cpp +++ b/indra/llmath/llvolumemgr.cpp @@ -49,7 +49,7 @@ LLVolumeMgr::LLVolumeMgr() { // the LLMutex magic interferes with easy unit testing, // so you now must manually call useMutex() to use it - //mDataMutex = new LLMutex(gAPRPoolp); + //mDataMutex = new LLMutex; } LLVolumeMgr::~LLVolumeMgr() @@ -216,7 +216,7 @@ void LLVolumeMgr::useMutex() { if (!mDataMutex) { - mDataMutex = new LLMutex(gAPRPoolp); + mDataMutex = new LLMutex; } } -- cgit v1.3 From 9f2987d995e8a2273f723a387dd587c3dc988056 Mon Sep 17 00:00:00 2001 From: "Nyx (Neal Orman)" Date: Wed, 23 Mar 2011 16:01:12 -0400 Subject: second pass at render complexity debug display. --- indra/llmath/lloctree.h | 2 +- indra/newview/app_settings/settings.xml | 73 ++++++++++++++++++++++++- indra/newview/llchathistory.cpp | 2 +- indra/newview/llspatialpartition.cpp | 96 +++++++++++++++++++++++++++++---- indra/newview/llviewermenu.cpp | 2 +- 5 files changed, 161 insertions(+), 14 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index fdfc24f8b7..179ad7ecfd 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -294,7 +294,7 @@ public: //is it here? if (isInside(data->getPositionGroup())) { - if ((getElementCount() < LL_OCTREE_MAX_CAPACITY && contains(data->getBinRadius()) || + if (((getElementCount() < LL_OCTREE_MAX_CAPACITY && contains(data->getBinRadius())) || (data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= LL_OCTREE_MAX_CAPACITY))) { //it belongs here #if LL_OCTREE_PARANOIA_CHECK diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 176211773f..bf2d8eda7f 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -7105,7 +7105,78 @@ RenderAvatarComplexityLimit Comment - Max visual complexity of avatars in a scens + Max visual complexity of avatars in a scene + Persist + 1 + Type + S32 + Value + -1 + + RenderComplexityColorMin + + Comment + Max visual complexity of avatars in a scene + Persist + 1 + Type + Color4 + Value + + 0.0 + 0.0 + 1.0 + 0.5 + + + RenderComplexityColorMid + + Comment + Max visual complexity of avatars in a scene + Persist + 1 + Type + Color4 + Value + + 0.0 + 1.0 + 0.0 + 0.5 + + + RenderComplexityColorMax + + Comment + Max visual complexity of avatars in a scene + Persist + 1 + Type + Color4 + Value + + 1.0 + 0.0 + 0.0 + 0.5 + + + RenderComplexityThreshold + + Comment + Only color objects higher than render threshold + Persist + 1 + Type + S32 + Value + -1 + + RenderComplexityStaticMax + + Comment + Sets a static max value for scaling of RenderComplexity + display (-1 for dynamic scaling) Persist 1 Type diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index d4ec377e03..658eb6eccf 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -255,7 +255,7 @@ public: mSourceType = chat.mSourceType; //*TODO overly defensive thing, source type should be maintained out there - if((chat.mFromID.isNull() && chat.mFromName.empty()) || chat.mFromName == SYSTEM_FROM && chat.mFromID.isNull()) + if((chat.mFromID.isNull() && chat.mFromName.empty()) || (chat.mFromName == SYSTEM_FROM && chat.mFromID.isNull())) { mSourceType = CHAT_SOURCE_SYSTEM; } diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index b604908474..092e48e459 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -2807,24 +2807,99 @@ void renderComplexityDisplay(LLDrawable* drawablep) return; } + if (!voVol->isRoot()) + { + return; + } + LLVOVolume::texture_cost_t textures; - F32 cost = (F32) voVol->getRenderCost(textures) / (F32) LLVOVolume::getRenderComplexityMax(); + F32 cost = (F32) voVol->getRenderCost(textures); + + // add any child volumes + LLViewerObject::const_child_list_t children = voVol->getChildren(); + for (LLViewerObject::const_child_list_t::const_iterator iter = children.begin(); iter != children.end(); ++iter) + { + const LLViewerObject *child = *iter; + const LLVOVolume *child_volume = dynamic_cast(child); + if (child_volume) + { + cost += child_volume->getRenderCost(textures); + } + } + + // add texture cost + for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter) + { + // add the cost of each individual texture in the linkset + cost += iter->second; + } + + F32 cost_max = (F32) LLVOVolume::getRenderComplexityMax(); + + + + // allow user to set a static color scale + if (gSavedSettings.getS32("RenderComplexityStaticMax") > 0) + { + cost_max = gSavedSettings.getS32("RenderComplexityStaticMax"); + } + + F32 cost_ratio = cost / cost_max; + + // cap cost ratio at 1.0f in case cost_max is at a low threshold + cost_ratio = cost_ratio > 1.0f ? 1.0f : cost_ratio; LLGLEnable blend(GL_BLEND); - F32 red = cost; - F32 green = 1.0f - cost; + LLColor4 color; + const LLColor4 color_min = gSavedSettings.getColor4("RenderComplexityColorMin"); + const LLColor4 color_mid = gSavedSettings.getColor4("RenderComplexityColorMid"); + const LLColor4 color_max = gSavedSettings.getColor4("RenderComplexityColorMax"); + + if (cost_ratio < 0.5f) + { + color = color_min * (1 - cost_ratio * 2) + color_mid * (cost_ratio * 2); + } + else + { + color = color_mid * (1 - (cost_ratio - 0.5) * 2) + color_max * ((cost_ratio - 0.5) * 2); + } - glColor4f(red,green,0,0.5f); + LLSD color_val = color.getValue(); - S32 num_faces = drawablep->getNumFaces(); - if (num_faces) + // don't highlight objects below the threshold + if (cost > gSavedSettings.getS32("RenderComplexityThreshold")) { - for (S32 i = 0; i < num_faces; ++i) + glColor4f(color[0],color[1],color[2],0.5f); + + + S32 num_faces = drawablep->getNumFaces(); + if (num_faces) { - pushVerts(drawablep->getFace(i), LLVertexBuffer::MAP_VERTEX); + for (S32 i = 0; i < num_faces; ++i) + { + pushVerts(drawablep->getFace(i), LLVertexBuffer::MAP_VERTEX); + } } - } + LLViewerObject::const_child_list_t children = voVol->getChildren(); + for (LLViewerObject::const_child_list_t::const_iterator iter = children.begin(); iter != children.end(); ++iter) + { + const LLViewerObject *child = *iter; + if (child) + { + num_faces = child->getNumFaces(); + if (num_faces) + { + for (S32 i = 0; i < num_faces; ++i) + { + pushVerts(child->mDrawable->getFace(i), LLVertexBuffer::MAP_VERTEX); + } + } + } + } + } + + voVol->setDebugText(llformat("%4.0f", cost)); } void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE) @@ -4170,7 +4245,8 @@ void LLSpatialPartition::renderDebug() LLPipeline::RENDER_DEBUG_AVATAR_VOLUME | LLPipeline::RENDER_DEBUG_AGENT_TARGET | //LLPipeline::RENDER_DEBUG_BUILD_QUEUE | - LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) + LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA | + LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY)) { return; } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 30be2fb8e0..f3e58ce73d 100755 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -993,7 +993,7 @@ U32 info_display_from_string(std::string info_display) { return LLPipeline::RENDER_DEBUG_AGENT_TARGET; } - else if ("" == info_display) + else if ("rendercomplexity" == info_display) { return LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY; } -- cgit v1.3 From 85b316e5df41444eafe77964f1a4758ccfd40784 Mon Sep 17 00:00:00 2001 From: "Nyx (Neal Orman)" Date: Mon, 6 Jun 2011 11:42:04 -0400 Subject: BUILDFIX fixing crash on performance analysis when there is no variation when fasttimers are amazingly consistent, we remove all data as outliers instead of removing nothing. Probably something else going on here, but this should fix the crash so we can analyze better. --- indra/llmath/llmath.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'indra/llmath') diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h index eea7c977fb..9297bcbac2 100644 --- a/indra/llmath/llmath.h +++ b/indra/llmath/llmath.h @@ -510,6 +510,13 @@ inline void ll_remove_outliers(std::vector& data, F32 k) VEC_TYPE Q1 = data[data.size()/4]; VEC_TYPE Q3 = data[data.size()-data.size()/4-1]; + if ((F32)(Q3-Q1) < 1.f) + { + // not enough variation to detect outliers + return; + } + + VEC_TYPE min = (VEC_TYPE) ((F32) Q1-k * (F32) (Q3-Q1)); VEC_TYPE max = (VEC_TYPE) ((F32) Q3+k * (F32) (Q3-Q1)); -- cgit v1.3 From 15235061e8a8f64dd94640d27eadfce23ccb76f6 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 18 Jun 2011 01:02:03 -0500 Subject: SH-828 Fix for using uninitialized data when normals or texture coordinates are absent from collada file (can now upload meshes without normals or texture coordinates). --- indra/llmath/llvolume.cpp | 141 ++++++++++--- indra/llprimitive/llmodel.cpp | 355 +++++++++++++++----------------- indra/newview/llfloatermodelpreview.cpp | 56 +++-- 3 files changed, 318 insertions(+), 234 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 8c81f27784..7c7c4306da 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2379,11 +2379,16 @@ bool LLVolumeFace::VertexData::operator==(const LLVolumeFace::VertexData& rhs)co bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs, F32 angle_cutoff) const { bool retval = false; - if (rhs.mData[POSITION].equals3(mData[POSITION]) && rhs.mTexCoord == mTexCoord) + + const F32 epsilon = 0.00001f; + + if (rhs.mData[POSITION].equals3(mData[POSITION], epsilon) && + abs(rhs.mTexCoord[0]-mTexCoord[0]) < epsilon && + abs(rhs.mTexCoord[1]-mTexCoord[1]) < epsilon) { if (angle_cutoff > 1.f) { - retval = (mData[NORMAL].equals3(rhs.mData[NORMAL])); + retval = (mData[NORMAL].equals3(rhs.mData[NORMAL], epsilon)); } else { @@ -2499,38 +2504,52 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) } { - U16* n = (U16*) &(norm[0]); - for (U32 j = 0; j < num_verts; ++j) + if (!norm.empty()) + { + U16* n = (U16*) &(norm[0]); + for (U32 j = 0; j < num_verts; ++j) + { + norm_out->set((F32) n[0], (F32) n[1], (F32) n[2]); + norm_out->div(65535.f); + norm_out->mul(2.f); + norm_out->sub(1.f); + norm_out++; + n += 3; + } + } + else { - norm_out->set((F32) n[0], (F32) n[1], (F32) n[2]); - norm_out->div(65535.f); - norm_out->mul(2.f); - norm_out->sub(1.f); - norm_out++; - n += 3; + memset(norm_out, 0, sizeof(LLVector4a)*num_verts); } } { - U16* t = (U16*) &(tc[0]); - for (U32 j = 0; j < num_verts; j+=2) + if (!tc.empty()) { - if (j < num_verts-1) - { - tc_out->set((F32) t[0], (F32) t[1], (F32) t[2], (F32) t[3]); - } - else + U16* t = (U16*) &(tc[0]); + for (U32 j = 0; j < num_verts; j+=2) { - tc_out->set((F32) t[0], (F32) t[1], 0.f, 0.f); - } + if (j < num_verts-1) + { + tc_out->set((F32) t[0], (F32) t[1], (F32) t[2], (F32) t[3]); + } + else + { + tc_out->set((F32) t[0], (F32) t[1], 0.f, 0.f); + } - t += 4; + t += 4; - tc_out->div(65535.f); - tc_out->mul(tc_range); - tc_out->add(min_tc4); + tc_out->div(65535.f); + tc_out->mul(tc_range); + tc_out->add(min_tc4); - tc_out++; + tc_out++; + } + } + else + { + memset(tc_out, 0, sizeof(LLVector2)*num_verts); } } @@ -2656,6 +2675,25 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) min.setMin(min, face.mPositions[i]); max.setMax(max, face.mPositions[i]); } + + if (face.mTexCoords) + { + LLVector2& min_tc = face.mTexCoordExtents[0]; + LLVector2& max_tc = face.mTexCoordExtents[1]; + + min_tc = face.mTexCoords[0]; + max_tc = face.mTexCoords[0]; + + for (U32 j = 1; j < face.mNumVertices; ++j) + { + update_min_max(min_tc, max_tc, face.mTexCoords[j]); + } + } + else + { + face.mTexCoordExtents[0].set(0,0); + face.mTexCoordExtents[1].set(1,1); + } } } } @@ -5696,8 +5734,23 @@ BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) void LLVolumeFace::getVertexData(U16 index, LLVolumeFace::VertexData& cv) { cv.setPosition(mPositions[index]); - cv.setNormal(mNormals[index]); - cv.mTexCoord = mTexCoords[index]; + if (mNormals) + { + cv.setNormal(mNormals[index]); + } + else + { + cv.getNormal().clear(); + } + + if (mTexCoords) + { + cv.mTexCoord = mTexCoords[index]; + } + else + { + cv.mTexCoord.clear(); + } } bool LLVolumeFace::VertexMapData::operator==(const LLVolumeFace::VertexData& rhs) const @@ -5727,7 +5780,10 @@ void LLVolumeFace::optimize(F32 angle_cutoff) LLVolumeFace new_face; //map of points to vector of vertices at that point - VertexMapData::PointMap point_map; + std::map > point_map; + + LLVector4a range; + range.setSub(mExtents[1],mExtents[0]); //remove redundant vertices for (U32 i = 0; i < mNumIndices; ++i) @@ -5738,7 +5794,19 @@ void LLVolumeFace::optimize(F32 angle_cutoff) getVertexData(index, cv); BOOL found = FALSE; - VertexMapData::PointMap::iterator point_iter = point_map.find(LLVector3(cv.getPosition().getF32ptr())); + + LLVector4a pos; + pos.setSub(mPositions[index], mExtents[0]); + pos.div(range); + + U64 pos64 = 0; + + pos64 = (U16) (pos[0]*65535); + pos64 = pos64 | (((U64) (pos[1]*65535)) << 16); + pos64 = pos64 | (((U64) (pos[2]*65535)) << 32); + + std::map >::iterator point_iter = point_map.find(pos64); + if (point_iter != point_map.end()) { //duplicate point might exist for (U32 j = 0; j < point_iter->second.size(); ++j) @@ -5770,11 +5838,26 @@ void LLVolumeFace::optimize(F32 angle_cutoff) } else { - point_map[LLVector3(d.getPosition().getF32ptr())].push_back(d); + point_map[pos64].push_back(d); } } } + llassert(new_face.mNumIndices == mNumIndices); + llassert(new_face.mNumVertices <= mNumVertices); + + if (angle_cutoff > 1.f && !mNormals) + { + ll_aligned_free_16(new_face.mNormals); + new_face.mNormals = NULL; + } + + if (!mTexCoords) + { + ll_aligned_free_16(new_face.mTexCoords); + new_face.mTexCoords = NULL; + } + swapData(new_face); } diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index e0cfa07614..7c9dba9597 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -27,6 +27,7 @@ #include "linden_common.h" #include "llmodel.h" +#include "llmemory.h" #include "llconvexdecomposition.h" #include "llsdserialize.h" #include "llvector4a.h" @@ -71,88 +72,10 @@ LLModel::~LLModel() } } -void load_face_from_dom_inputs(LLVolumeFace& face, const domInputLocalOffset_Array& inputs, U32 min_idx, U32 max_idx) -{ - for (U32 j = 0; j < inputs.getCount(); ++j) - { - if (strcmp(COMMON_PROFILE_INPUT_VERTEX, inputs[j]->getSemantic()) == 0) - { //found vertex array - const domURIFragmentType& uri = inputs[j]->getSource(); - daeElementRef elem = uri.getElement(); - domVertices* vertices = (domVertices*) elem.cast(); - - domInputLocal_Array& v_inp = vertices->getInput_array(); - if (inputs[j]->getOffset() != 0) - { - llerrs << "Vertex array offset MUST be zero." << llendl; - } - - for (U32 k = 0; k < v_inp.getCount(); ++k) - { - if (strcmp(COMMON_PROFILE_INPUT_POSITION, v_inp[k]->getSemantic()) == 0) - { - const domURIFragmentType& uri = v_inp[k]->getSource(); - - daeElementRef elem = uri.getElement(); - domSource* src = (domSource*) elem.cast(); - - if (src->getTechnique_common()->getAccessor()->getStride() != 3) - { - llerrs << "Vertex array stride MUST be three." << llendl; - } - - domListOfFloats& v = src->getFloat_array()->getValue(); - - LLVector4a min; - min.set(v[min_idx], v[min_idx+1], v[min_idx+2]); - LLVector4a max = min; - - for (U32 j = min_idx; j <= max_idx; ++j) - { //copy vertex array - face.mPositions[j-min_idx].set(v[j*3+0], v[j*3+1], v[j*3+2]); - update_min_max(min, max, face.mPositions[j-min_idx]); - } - - face.mExtents[0] = min; - face.mExtents[1] = max; - } - } - } - - if (strcmp(COMMON_PROFILE_INPUT_NORMAL, inputs[j]->getSemantic()) == 0) - { - //found normal array for this triangle list - const domURIFragmentType& uri = inputs[j]->getSource(); - daeElementRef elem = uri.getElement(); - domSource* src = (domSource*) elem.cast(); - domListOfFloats& n = src->getFloat_array()->getValue(); - - for (U32 j = min_idx; j <= max_idx; ++j) - { - LLVector4a* norm = (LLVector4a*) face.mNormals + (j-min_idx); - norm->set(n[j*3+0], n[j*3+1], n[j*3+2]); - norm->normalize3(); - } - } - else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, inputs[j]->getSemantic()) == 0) - { //found texCoords - const domURIFragmentType& uri = inputs[j]->getSource(); - daeElementRef elem = uri.getElement(); - domSource* src = (domSource*) elem.cast(); - domListOfFloats& u = src->getFloat_array()->getValue(); - - for (U32 j = min_idx; j <= max_idx; ++j) - { - face.mTexCoords[j-min_idx].setVec(u[j*2+0], u[j*2+1]); - } - } - } -} bool get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S32& tc_offset, S32& norm_offset, S32 &idx_stride, domSource* &pos_source, domSource* &tc_source, domSource* &norm_source) { - idx_stride = 0; for (U32 j = 0; j < inputs.getCount(); ++j) @@ -271,14 +194,13 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector& fa cv.mTexCoord.setVec(tc[idx[i+tc_offset]*2+0], tc[idx[i+tc_offset]*2+1]); } - + if (norm_source) { cv.setNormal(LLVector4a(n[idx[i+norm_offset]*3+0], n[idx[i+norm_offset]*3+1], n[idx[i+norm_offset]*3+2])); } - BOOL found = FALSE; @@ -329,10 +251,22 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector& fa { face_list.push_back(face); face_list.rbegin()->fillFromLegacyData(verts, indices); + LLVolumeFace& new_face = *face_list.rbegin(); + if (!norm_source) + { + ll_aligned_free_16(new_face.mNormals); + new_face.mNormals = NULL; + } + + if (!tc_source) + { + ll_aligned_free_16(face.mTexCoords); + new_face.mTexCoords = NULL; + } + face = LLVolumeFace(); point_map.clear(); } - } if (!verts.empty()) @@ -348,6 +282,18 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector& fa face_list.push_back(face); face_list.rbegin()->fillFromLegacyData(verts, indices); + LLVolumeFace& new_face = *face_list.rbegin(); + if (!norm_source) + { + ll_aligned_free_16(new_face.mNormals); + new_face.mNormals = NULL; + } + + if (!tc_source) + { + ll_aligned_free_16(face.mTexCoords); + new_face.mTexCoords = NULL; + } } return LLModel::NO_ERRORS ; @@ -433,14 +379,14 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector& fac cv.mTexCoord.setVec(tc[idx[cur_idx+tc_offset]*2+0], tc[idx[cur_idx+tc_offset]*2+1]); } - + if (norm_source) { cv.getNormal().set(n[idx[cur_idx+norm_offset]*3+0], n[idx[cur_idx+norm_offset]*3+1], n[idx[cur_idx+norm_offset]*3+2]); } - + cur_idx += idx_stride; BOOL found = FALSE; @@ -524,6 +470,19 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector& fac { face_list.push_back(face); face_list.rbegin()->fillFromLegacyData(verts, indices); + LLVolumeFace& new_face = *face_list.rbegin(); + if (!norm_source) + { + ll_aligned_free_16(new_face.mNormals); + new_face.mNormals = NULL; + } + + if (!tc_source) + { + ll_aligned_free_16(face.mTexCoords); + new_face.mTexCoords = NULL; + } + face = LLVolumeFace(); verts.clear(); indices.clear(); @@ -540,10 +499,23 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector& fac { material = std::string(poly->getMaterial()); } - + materials.push_back(material); face_list.push_back(face); face_list.rbegin()->fillFromLegacyData(verts, indices); + + LLVolumeFace& new_face = *face_list.rbegin(); + if (!norm_source) + { + ll_aligned_free_16(new_face.mNormals); + new_face.mNormals = NULL; + } + + if (!tc_source) + { + ll_aligned_free_16(face.mTexCoords); + new_face.mTexCoords = NULL; + } } return LLModel::NO_ERRORS ; @@ -557,7 +529,6 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector& fac const domInputLocalOffset_Array& inputs = poly->getInput_array(); - S32 v_offset = -1; S32 n_offset = -1; S32 t_offset = -1; @@ -662,15 +633,14 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector& fac n->get(n_idx+1), n->get(n_idx+2)); } - + if (t) { U32 t_idx = idx[j*stride+t_offset]*2; vert.mTexCoord.setVec(t->get(t_idx), t->get(t_idx+1)); } - - + verts.push_back(vert); } } @@ -733,6 +703,19 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector& fac materials.push_back(material); face_list.push_back(face); face_list.rbegin()->fillFromLegacyData(new_verts, indices); + + LLVolumeFace& new_face = *face_list.rbegin(); + if (!n) + { + ll_aligned_free_16(new_face.mNormals); + new_face.mNormals = NULL; + } + + if (!t) + { + ll_aligned_free_16(face.mTexCoords); + new_face.mTexCoords = NULL; + } } return LLModel::NO_ERRORS ; @@ -817,9 +800,9 @@ BOOL LLModel::createVolumeFacesFromDomMesh(domMesh* mesh) if (getNumVolumeFaces() > 0) { - optimizeVolumeFaces(); normalizeVolumeFaces(); - + optimizeVolumeFaces(); + if (getNumVolumeFaces() > 0) { return TRUE; @@ -853,81 +836,10 @@ void LLModel::offsetMesh( const LLVector3& pivotPoint ) void LLModel::optimizeVolumeFaces() { -#if 0 //VECTORIZE ? - for (std::vector::iterator iter = mVolumeFaces.begin(); iter != mVolumeFaces.end(); ) - { - std::vector::iterator cur_iter = iter++; - LLVolumeFace& face = *cur_iter; - - for (S32 i = 0; i < (S32) face.mNumIndices; i += 3) - { //remove zero area triangles - U16 i0 = face.mIndices[i+0]; - U16 i1 = face.mIndices[i+1]; - U16 i2 = face.mIndices[i+2]; - - if (i0 == i1 || - i1 == i2 || - i0 == i2) - { //duplicate index in triangle, remove triangle - face.mIndices.erase(face.mIndices.begin()+i, face.mIndices.begin()+i+3); - i -= 3; - } - else - { - LLVolumeFace::VertexData& v0 = face.mVertices[i0]; - LLVolumeFace::VertexData& v1 = face.mVertices[i1]; - LLVolumeFace::VertexData& v2 = face.mVertices[i2]; - - if (v0.mPosition == v1.mPosition || - v1.mPosition == v2.mPosition || - v2.mPosition == v0.mPosition) - { //zero area triangle, delete - face.mIndices.erase(face.mIndices.begin()+i, face.mIndices.begin()+i+3); - i-=3; - } - } - } - - //remove unreference vertices - std::vector ref; - ref.resize(face.mNumVertices); - - for (U32 i = 0; i < ref.size(); ++i) - { - ref[i] = false; - } - - for (U32 i = 0; i < face.mNumIndices; ++i) - { - ref[face.mIndices[i]] = true; - } - - U32 unref_count = 0; - for (U32 i = 0; i < ref.size(); ++i) - { - if (!ref[i]) - { - //vertex is unreferenced - face.mVertices.erase(face.mVertices.begin()+(i-unref_count)); - U16 idx = (U16) (i-unref_count); - - for (U32 j = 0; j < face.mNumIndices; ++j) - { //decrement every index array value greater than idx - if (face.mIndices[j] > idx) - { - --face.mIndices[j]; - } - } - ++unref_count; - } - } - - if (face.mVertices.empty() || face.mIndices.empty()) - { //face is empty, remove it - iter = mVolumeFaces.erase(cur_iter); - } + for (U32 i = 0; i < getNumVolumeFaces(); ++i) + { + mVolumeFaces[i].optimize(); } -#endif } // Shrink the model to fit @@ -962,6 +874,25 @@ void LLModel::normalizeVolumeFaces() update_min_max(min, max, face.mExtents[0]); update_min_max(min, max, face.mExtents[1]); + + if (face.mTexCoords) + { + LLVector2& min_tc = face.mTexCoordExtents[0]; + LLVector2& max_tc = face.mTexCoordExtents[1]; + + min_tc = face.mTexCoords[0]; + max_tc = face.mTexCoords[0]; + + for (U32 j = 1; j < face.mNumVertices; ++j) + { + update_min_max(min_tc, max_tc, face.mTexCoords[j]); + } + } + else + { + face.mTexCoordExtents[0].set(0,0); + face.mTexCoordExtents[1].set(1,1); + } } // Now that we have the extents of the model @@ -1029,8 +960,11 @@ void LLModel::normalizeVolumeFaces() { pos[j].add(trans); pos[j].mul(scale); - norm[j].mul(inv_scale); - norm[j].normalize3(); + if (norm && !norm[j].equals3(LLVector4a::getZero())) + { + norm[j].mul(inv_scale); + norm[j].normalize3(); + } } } @@ -1073,8 +1007,26 @@ void LLModel::setVolumeFaceData( face.resizeIndices(num_indices); LLVector4a::memcpyNonAliased16((F32*) face.mPositions, (F32*) pos.get(), num_verts*4*sizeof(F32)); - LLVector4a::memcpyNonAliased16((F32*) face.mNormals, (F32*) norm.get(), num_verts*4*sizeof(F32)); - LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), num_verts*2*sizeof(F32)); + if (norm.get()) + { + LLVector4a::memcpyNonAliased16((F32*) face.mNormals, (F32*) norm.get(), num_verts*4*sizeof(F32)); + } + else + { + ll_aligned_free_16(face.mNormals); + face.mNormals = NULL; + } + + if (tc.get()) + { + LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), num_verts*2*sizeof(F32)); + } + else + { + ll_aligned_free_16(face.mTexCoords); + face.mTexCoords = NULL; + } + U32 size = (num_indices*2+0xF)&~0xF; LLVector4a::memcpyNonAliased16((F32*) face.mIndices, (F32*) ind.get(), size); } @@ -1477,9 +1429,8 @@ LLSD LLModel::writeModel( { //for each vert F32* pos = face.mPositions[j].getF32ptr(); - F32* norm = face.mNormals[j].getF32ptr(); - - //position + normal + + //position for (U32 k = 0; k < 3; ++k) { //for each component //convert to 16-bit normalized across domain @@ -1489,29 +1440,41 @@ LLSD LLModel::writeModel( //write to binary buffer verts[vert_idx++] = buff[0]; verts[vert_idx++] = buff[1]; - - //convert to 16-bit normalized - val = (U16) ((norm[k]+1.f)*0.5f*65535); + } - //write to binary buffer - normals[norm_idx++] = buff[0]; - normals[norm_idx++] = buff[1]; + if (face.mNormals) + { //normals + F32* norm = face.mNormals[j].getF32ptr(); + + for (U32 k = 0; k < 3; ++k) + { //for each component + //convert to 16-bit normalized + U16 val = (U16) ((norm[k]+1.f)*0.5f*65535); + U8* buff = (U8*) &val; + + //write to binary buffer + normals[norm_idx++] = buff[0]; + normals[norm_idx++] = buff[1]; + } } + F32* src_tc = (F32*) face.mTexCoords[j].mV; //texcoord - for (U32 k = 0; k < 2; ++k) - { //for each component - //convert to 16-bit normalized - U16 val = (U16) ((src_tc[k]-min_tc.mV[k])/tc_range.mV[k]*65535); - - U8* buff = (U8*) &val; - //write to binary buffer - tc[tc_idx++] = buff[0]; - tc[tc_idx++] = buff[1]; + if (face.mTexCoords) + { + for (U32 k = 0; k < 2; ++k) + { //for each component + //convert to 16-bit normalized + U16 val = (U16) ((src_tc[k]-min_tc.mV[k])/tc_range.mV[k]*65535); + + U8* buff = (U8*) &val; + //write to binary buffer + tc[tc_idx++] = buff[0]; + tc[tc_idx++] = buff[1]; + } } - } U32 idx_idx = 0; @@ -1525,12 +1488,20 @@ LLSD LLModel::writeModel( //write out face data mdl[model_names[idx]][i]["PositionDomain"]["Min"] = min_pos.getValue(); mdl[model_names[idx]][i]["PositionDomain"]["Max"] = max_pos.getValue(); - mdl[model_names[idx]][i]["TexCoord0Domain"]["Min"] = min_tc.getValue(); - mdl[model_names[idx]][i]["TexCoord0Domain"]["Max"] = max_tc.getValue(); - mdl[model_names[idx]][i]["Position"] = verts; - mdl[model_names[idx]][i]["Normal"] = normals; - mdl[model_names[idx]][i]["TexCoord0"] = tc; + + if (face.mNormals) + { + mdl[model_names[idx]][i]["Normal"] = normals; + } + + if (face.mTexCoords) + { + mdl[model_names[idx]][i]["TexCoord0Domain"]["Min"] = min_tc.getValue(); + mdl[model_names[idx]][i]["TexCoord0Domain"]["Max"] = max_tc.getValue(); + mdl[model_names[idx]][i]["TexCoord0"] = tc; + } + mdl[model_names[idx]][i]["TriangleList"] = indices; if (skinning) diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 866cc39eec..a4683b4874 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -3719,7 +3719,9 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim U32 tri_count = 0; for (U32 i = 0; i < mVertexBuffer[5][mdl].size(); ++i) { - mVertexBuffer[5][mdl][i]->setBuffer(type_mask); + LLVertexBuffer* buff = mVertexBuffer[5][mdl][i]; + buff->setBuffer(type_mask & buff->getTypeMask()); + U32 num_indices = mVertexBuffer[5][mdl][i]->getNumIndices(); if (num_indices > 2) { @@ -3841,6 +3843,8 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim for (GLint i = 0; i < patch_count; ++i) { + type_mask = mVertexBuffer[5][base][i]->getTypeMask(); + LLPointer buff = new LLVertexBuffer(type_mask, 0); if (sizes[i*2+1] > 0 && sizes[i*2] > 0) @@ -3865,8 +3869,15 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim LLStrider index; buff->getVertexStrider(pos); - buff->getNormalStrider(norm); - buff->getTexCoord0Strider(tc); + if (type_mask & LLVertexBuffer::MAP_NORMAL) + { + buff->getNormalStrider(norm); + } + if (type_mask & LLVertexBuffer::MAP_TEXCOORD0) + { + buff->getTexCoord0Strider(tc); + } + buff->getIndexStrider(index); target_model->setVolumeFaceData(names[i], pos, norm, tc, index, buff->getNumVerts(), buff->getNumIndices()); @@ -4462,7 +4473,16 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) bool skinned = include_skin_weights && !mdl->mSkinWeights.empty(); - U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; + U32 mask = LLVertexBuffer::MAP_VERTEX; + + if (vf.mNormals) + { + mask |= LLVertexBuffer::MAP_NORMAL; + } + if (vf.mTexCoords) + { + mask |= LLVertexBuffer::MAP_TEXCOORD0; + } if (skinned) { @@ -4480,8 +4500,6 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) LLStrider weights_strider; vb->getVertexStrider(vertex_strider); - vb->getNormalStrider(normal_strider); - vb->getTexCoord0Strider(tc_strider); vb->getIndexStrider(index_strider); if (skinned) @@ -4490,8 +4508,18 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) } LLVector4a::memcpyNonAliased16((F32*) vertex_strider.get(), (F32*) vf.mPositions, num_vertices*4*sizeof(F32)); - LLVector4a::memcpyNonAliased16((F32*) tc_strider.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32)); - LLVector4a::memcpyNonAliased16((F32*) normal_strider.get(), (F32*) vf.mNormals, num_vertices*4*sizeof(F32)); + + if (vf.mTexCoords) + { + vb->getTexCoord0Strider(tc_strider); + LLVector4a::memcpyNonAliased16((F32*) tc_strider.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32)); + } + + if (vf.mNormals) + { + vb->getNormalStrider(normal_strider); + LLVector4a::memcpyNonAliased16((F32*) normal_strider.get(), (F32*) vf.mNormals, num_vertices*4*sizeof(F32)); + } if (skinned) { @@ -4750,6 +4778,8 @@ BOOL LLModelPreview::render() const F32 BRIGHTNESS = 0.9f; gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS); + const U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; + LLGLEnable normalize(GL_NORMALIZE); if (!mBaseModel.empty() && mVertexBuffer[5].empty()) @@ -4798,8 +4828,8 @@ BOOL LLModelPreview::render() for (U32 i = 0; i < mVertexBuffer[mPreviewLOD][model].size(); ++i) { LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i]; - - buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); + + buffer->setBuffer(type_mask & buffer->getTypeMask()); if (textures) { @@ -4918,7 +4948,7 @@ BOOL LLModelPreview::render() { LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i]; - buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); + buffer->setBuffer(type_mask & buffer->getTypeMask()); buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -4984,7 +5014,7 @@ BOOL LLModelPreview::render() { LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i]; - buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); + buffer->setBuffer(type_mask & buffer->getTypeMask()); LLStrider pos_strider; buffer->getVertexStrider(pos_strider, 0); @@ -5109,7 +5139,7 @@ BOOL LLModelPreview::render() position[j] = v; } - buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); + buffer->setBuffer(type_mask & buffer->getTypeMask()); glColor4fv(instance.mMaterial[i].mDiffuseColor.mV); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0); -- cgit v1.3 From 7201d55396be92b18074ac926698688f9067f222 Mon Sep 17 00:00:00 2001 From: "Nyx (Neal Orman)" Date: Mon, 20 Jun 2011 17:18:43 -0400 Subject: BUILDFIX: linux build broken - abs() used instead of fabs() linux caught the fact that we're using an integer absolute value function when we should be using a floating-point version. --- indra/llmath/llvolume.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 7c7c4306da..d401ce7de7 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -32,6 +32,7 @@ #if !LL_WINDOWS #include #endif +#include #include "llerror.h" #include "llmemtype.h" @@ -2383,8 +2384,8 @@ bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs const F32 epsilon = 0.00001f; if (rhs.mData[POSITION].equals3(mData[POSITION], epsilon) && - abs(rhs.mTexCoord[0]-mTexCoord[0]) < epsilon && - abs(rhs.mTexCoord[1]-mTexCoord[1]) < epsilon) + fabs(rhs.mTexCoord[0]-mTexCoord[0]) < epsilon && + fabs(rhs.mTexCoord[1]-mTexCoord[1]) < epsilon) { if (angle_cutoff > 1.f) { -- cgit v1.3 From f83b08b69c84d6df9cebb79167804cd295555481 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Fri, 24 Jun 2011 15:09:10 -0600 Subject: fix for SH-1878: Viewer hang in GLOD_Group::adaptTriangleBudget during LLModelPreview::genLODs; SH-1891: viewer crashes while previewing "RYOMA 3D XML File.dae"; SH-1890: Crash loading palm tree --- indra/llmath/llvolume.cpp | 58 ++++++++++++++++++++++----------- indra/llprimitive/llmodel.cpp | 10 +++--- indra/newview/llfloatermodelpreview.cpp | 11 +------ 3 files changed, 45 insertions(+), 34 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index d401ce7de7..bddb8d8c66 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2774,11 +2774,13 @@ void LLVolume::makeTetrahedron() n[2] = cv[2].getNormal(); n += 3; - tc[0] = cv[0].mTexCoord; - tc[1] = cv[1].mTexCoord; - tc[2] = cv[2].mTexCoord; - tc += 3; - + if(tc) + { + tc[0] = cv[0].mTexCoord; + tc[1] = cv[1].mTexCoord; + tc[2] = cv[2].mTexCoord; + tc += 3; + } //side 2 cv[0].setPosition(p[3]); @@ -2797,11 +2799,14 @@ void LLVolume::makeTetrahedron() n[2] = cv[2].getNormal(); n += 3; - tc[0] = cv[0].mTexCoord; - tc[1] = cv[1].mTexCoord; - tc[2] = cv[2].mTexCoord; - tc += 3; - + if(tc) + { + tc[0] = cv[0].mTexCoord; + tc[1] = cv[1].mTexCoord; + tc[2] = cv[2].mTexCoord; + tc += 3; + } + //side 3 cv[0].setPosition(p[3]); cv[1].setPosition(p[1]); @@ -2819,10 +2824,13 @@ void LLVolume::makeTetrahedron() n[2] = cv[2].getNormal(); n += 3; - tc[0] = cv[0].mTexCoord; - tc[1] = cv[1].mTexCoord; - tc[2] = cv[2].mTexCoord; - tc += 3; + if(tc) + { + tc[0] = cv[0].mTexCoord; + tc[1] = cv[1].mTexCoord; + tc[2] = cv[2].mTexCoord; + tc += 3; + } //side 4 cv[0].setPosition(p[2]); @@ -2841,10 +2849,13 @@ void LLVolume::makeTetrahedron() n[2] = cv[2].getNormal(); n += 3; - tc[0] = cv[0].mTexCoord; - tc[1] = cv[1].mTexCoord; - tc[2] = cv[2].mTexCoord; - tc += 3; + if(tc) + { + tc[0] = cv[0].mTexCoord; + tc[1] = cv[1].mTexCoord; + tc[2] = cv[2].mTexCoord; + tc += 3; + } //set index buffer for (U16 i = 0; i < 12; i++) @@ -5613,7 +5624,16 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) src.mPositions, vert_size); LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) src.mNormals, vert_size); - LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, tc_size); + + if(src.mTexCoords) + { + LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, tc_size); + } + else + { + ll_aligned_free_16(mTexCoords) ; + mTexCoords = NULL ; + } if (src.mBinormals) diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index f2fe20b3e7..972f256076 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -260,7 +260,7 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector& fa if (!tc_source) { - ll_aligned_free_16(face.mTexCoords); + ll_aligned_free_16(new_face.mTexCoords); new_face.mTexCoords = NULL; } @@ -291,7 +291,7 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector& fa if (!tc_source) { - ll_aligned_free_16(face.mTexCoords); + ll_aligned_free_16(new_face.mTexCoords); new_face.mTexCoords = NULL; } } @@ -479,7 +479,7 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector& fac if (!tc_source) { - ll_aligned_free_16(face.mTexCoords); + ll_aligned_free_16(new_face.mTexCoords); new_face.mTexCoords = NULL; } @@ -513,7 +513,7 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector& fac if (!tc_source) { - ll_aligned_free_16(face.mTexCoords); + ll_aligned_free_16(new_face.mTexCoords); new_face.mTexCoords = NULL; } } @@ -713,7 +713,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector& fac if (!t) { - ll_aligned_free_16(face.mTexCoords); + ll_aligned_free_16(new_face.mTexCoords); new_face.mTexCoords = NULL; } } diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 77713b6ebb..0006e3423b 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -4500,16 +4500,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) bool skinned = include_skin_weights && !mdl->mSkinWeights.empty(); - U32 mask = LLVertexBuffer::MAP_VERTEX; - - if (vf.mNormals) - { - mask |= LLVertexBuffer::MAP_NORMAL; - } - if (vf.mTexCoords) - { - mask |= LLVertexBuffer::MAP_TEXCOORD0; - } + U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0 ; if (skinned) { -- cgit v1.3 From 5c0df02df5abdadbf17235ae5d7208963c25f1ce Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 15 Aug 2011 12:18:06 -0500 Subject: SH-2147 Clarify and quiet log spam on mesh LoD unzip failure. --- indra/llmath/llvolume.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 2893e746e9..a0338294c1 100755 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2408,7 +2408,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) LLSD mdl; if (!unzip_llsd(mdl, is, size)) { - llwarns << "not a valid mesh asset!" << llendl; + LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD, will probably fetch from sim again." << llendl; return false; } -- cgit v1.3 From f7d17cad5cc3784abb0dea4fb5bec967cbc1f81b Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 17 Aug 2011 12:55:32 -0500 Subject: SH-2188 Fix for generally bad vertex buffer updates for rigged attachments and fix for viewer always thinking meshes initially have 8 texture entries. --- indra/llmath/llvolume.cpp | 173 ++----------------------------------- indra/llmath/llvolume.h | 6 +- indra/newview/lldrawpoolavatar.cpp | 41 ++++++--- indra/newview/llmeshrepository.cpp | 14 ++- indra/newview/llvovolume.cpp | 13 ++- 5 files changed, 47 insertions(+), 200 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index a0338294c1..b2fe9ba6c2 100755 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2078,7 +2078,7 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge mFaceMask = 0x0; mDetail = detail; mSculptLevel = -2; - mIsTetrahedron = FALSE; + mIsMeshAssetLoaded = FALSE; mLODScaleBias.setVec(1,1,1); mHullPoints = NULL; mHullIndices = NULL; @@ -2100,7 +2100,7 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge generate(); - if (mParams.getSculptID().isNull() && mParams.getSculptType() == LL_SCULPT_TYPE_NONE) + if (mParams.getSculptID().isNull() && mParams.getSculptType() == LL_SCULPT_TYPE_NONE || mParams.getSculptType() == LL_SCULPT_TYPE_MESH) { createVolumeFaces(); } @@ -2706,173 +2706,21 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) return true; } -void tetrahedron_set_normal(LLVolumeFace::VertexData* cv) -{ - LLVector4a v0; - v0.setSub(cv[1].getPosition(), cv[0].getNormal()); - LLVector4a v1; - v1.setSub(cv[2].getNormal(), cv[0].getPosition()); - - cv[0].getNormal().setCross3(v0,v1); - cv[0].getNormal().normalize3fast(); - cv[1].setNormal(cv[0].getNormal()); - cv[2].setNormal(cv[1].getNormal()); -} -BOOL LLVolume::isTetrahedron() +BOOL LLVolume::isMeshAssetLoaded() { - return mIsTetrahedron; + return mIsMeshAssetLoaded; } -void LLVolume::makeTetrahedron() +void LLVolume::setMeshAssetLoaded(BOOL loaded) { - mVolumeFaces.clear(); - - LLVolumeFace face; - - F32 x = 0.25f; - LLVector4a p[] = - { //unit tetrahedron corners - LLVector4a(x,x,x), - LLVector4a(-x,-x,x), - LLVector4a(-x,x,-x), - LLVector4a(x,-x,-x) - }; - - face.mExtents[0].splat(-x); - face.mExtents[1].splat(x); - - LLVolumeFace::VertexData cv[3]; - - //set texture coordinates - cv[0].mTexCoord = LLVector2(0,0); - cv[1].mTexCoord = LLVector2(1,0); - cv[2].mTexCoord = LLVector2(0.5f, 0.5f*F_SQRT3); - - - //side 1 - cv[0].setPosition(p[1]); - cv[1].setPosition(p[0]); - cv[2].setPosition(p[2]); - - tetrahedron_set_normal(cv); - - face.resizeVertices(12); - face.resizeIndices(12); - - LLVector4a* v = (LLVector4a*) face.mPositions; - LLVector4a* n = (LLVector4a*) face.mNormals; - LLVector2* tc = (LLVector2*) face.mTexCoords; - - v[0] = cv[0].getPosition(); - v[1] = cv[1].getPosition(); - v[2] = cv[2].getPosition(); - v += 3; - - n[0] = cv[0].getNormal(); - n[1] = cv[1].getNormal(); - n[2] = cv[2].getNormal(); - n += 3; - - if(tc) - { - tc[0] = cv[0].mTexCoord; - tc[1] = cv[1].mTexCoord; - tc[2] = cv[2].mTexCoord; - tc += 3; - } - - //side 2 - cv[0].setPosition(p[3]); - cv[1].setPosition(p[0]); - cv[2].setPosition(p[1]); - - tetrahedron_set_normal(cv); - - v[0] = cv[0].getPosition(); - v[1] = cv[1].getPosition(); - v[2] = cv[2].getPosition(); - v += 3; - - n[0] = cv[0].getNormal(); - n[1] = cv[1].getNormal(); - n[2] = cv[2].getNormal(); - n += 3; - - if(tc) - { - tc[0] = cv[0].mTexCoord; - tc[1] = cv[1].mTexCoord; - tc[2] = cv[2].mTexCoord; - tc += 3; - } - - //side 3 - cv[0].setPosition(p[3]); - cv[1].setPosition(p[1]); - cv[2].setPosition(p[2]); - - tetrahedron_set_normal(cv); - - v[0] = cv[0].getPosition(); - v[1] = cv[1].getPosition(); - v[2] = cv[2].getPosition(); - v += 3; - - n[0] = cv[0].getNormal(); - n[1] = cv[1].getNormal(); - n[2] = cv[2].getNormal(); - n += 3; - - if(tc) - { - tc[0] = cv[0].mTexCoord; - tc[1] = cv[1].mTexCoord; - tc[2] = cv[2].mTexCoord; - tc += 3; - } - - //side 4 - cv[0].setPosition(p[2]); - cv[1].setPosition(p[0]); - cv[2].setPosition(p[3]); - - tetrahedron_set_normal(cv); - - v[0] = cv[0].getPosition(); - v[1] = cv[1].getPosition(); - v[2] = cv[2].getPosition(); - v += 3; - - n[0] = cv[0].getNormal(); - n[1] = cv[1].getNormal(); - n[2] = cv[2].getNormal(); - n += 3; - - if(tc) - { - tc[0] = cv[0].mTexCoord; - tc[1] = cv[1].mTexCoord; - tc[2] = cv[2].mTexCoord; - tc += 3; - } - - //set index buffer - for (U16 i = 0; i < 12; i++) - { - face.mIndices[i] = i; - } - - mVolumeFaces.push_back(face); - mSculptLevel = 0; - mIsTetrahedron = TRUE; + mIsMeshAssetLoaded = loaded; } void LLVolume::copyVolumeFaces(const LLVolume* volume) { mVolumeFaces = volume->mVolumeFaces; mSculptLevel = 0; - mIsTetrahedron = FALSE; } void LLVolume::cacheOptimize() @@ -2886,13 +2734,6 @@ void LLVolume::cacheOptimize() S32 LLVolume::getNumFaces() const { - U8 sculpt_type = (mParams.getSculptType() & LL_SCULPT_TYPE_MASK); - - if (sculpt_type == LL_SCULPT_TYPE_MESH) - { - return LL_SCULPT_MESH_MAX_FACES; - } - return (S32)mProfilep->mFaces.size(); } @@ -7269,7 +7110,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) resizeVertices(num_vertices); resizeIndices(num_indices); - if ((volume->getParams().getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH) + if (!volume->isMeshAssetLoaded()) { mEdge.resize(num_indices); } diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index f67f8f644d..f0e59a3c00 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -1058,14 +1058,14 @@ protected: public: virtual bool unpackVolumeFaces(std::istream& is, S32 size); - virtual void makeTetrahedron(); - virtual BOOL isTetrahedron(); + virtual void setMeshAssetLoaded(BOOL loaded); + virtual BOOL isMeshAssetLoaded(); protected: BOOL mUnique; F32 mDetail; S32 mSculptLevel; - BOOL mIsTetrahedron; + BOOL mIsMeshAssetLoaded; LLVolumeParams mParams; LLPath *mPathp; diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 9f790d03fe..984014f309 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1283,30 +1283,38 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* return; } - LLVertexBuffer* buffer = face->getVertexBuffer(); + LLPointer buffer = face->getVertexBuffer(); + LLDrawable* drawable = face->getDrawable(); U32 data_mask = face->getRiggedVertexBufferDataMask(); - if (!buffer || + if (buffer.isNull() || buffer->getTypeMask() != data_mask || - buffer->getRequestedVerts() != vol_face.mNumVertices) + buffer->getRequestedVerts() != vol_face.mNumVertices || + buffer->getRequestedIndices() != vol_face.mNumIndices || + (drawable && drawable->isState(LLDrawable::REBUILD_ALL))) { face->setGeomIndex(0); face->setIndicesIndex(0); - face->setSize(vol_face.mNumVertices, vol_face.mNumIndices, true); - - - if (sShaderLevel > 0) - { - buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB); + + if (buffer.isNull() || buffer->getTypeMask() != data_mask) + { //make a new buffer + if (sShaderLevel > 0) + { + buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB); + } + else + { + buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB); + } + buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true); } else - { - buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB); + { //resize existing buffer + buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices); } - buffer->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), true); - + face->setSize(vol_face.mNumVertices, vol_face.mNumIndices); face->setVertexBuffer(buffer); U16 offset = 0; @@ -1407,6 +1415,11 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* } } } + + if (drawable && (face->getTEOffset() == drawable->getNumFaces()-1)) + { + drawable->clearState(LLDrawable::REBUILD_ALL); + } } void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) @@ -1437,7 +1450,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) LLVolume* volume = vobj->getVolume(); S32 te = face->getTEOffset(); - if (!volume || volume->getNumVolumeFaces() <= te) + if (!volume || volume->getNumVolumeFaces() <= te || !volume->isMeshAssetLoaded()) { continue; } diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 2b6b2a84e1..90a0d5da59 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1701,6 +1701,7 @@ void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header) { LLPointer volume = new LLVolume(volume_params, LLVolumeLODGroup::getVolumeScaleFromDetail(i)); volume->copyVolumeFaces(data.mModel[i]); + volume->setMeshAssetLoaded(TRUE); } } @@ -2154,11 +2155,6 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para if (volume) { - if (volume->getNumVolumeFaces() == 0 && !volume->isTetrahedron()) - { - volume->makeTetrahedron(); - } - LLVolumeParams params = volume->getParams(); LLVolumeLODGroup* group = LLPrimitive::getVolumeManager()->getGroup(params); @@ -2169,7 +2165,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para if (last_lod >= 0) { LLVolume* lod = group->refLOD(last_lod); - if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0) + if (lod && lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0) { group->derefLOD(lod); return last_lod; @@ -2181,7 +2177,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para for (S32 i = detail-1; i >= 0; --i) { LLVolume* lod = group->refLOD(i); - if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0) + if (lod && lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0) { group->derefLOD(lod); return i; @@ -2194,7 +2190,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para for (S32 i = detail+1; i < 4; ++i) { LLVolume* lod = group->refLOD(i); - if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0) + if (lod && lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0) { group->derefLOD(lod); return i; @@ -2445,7 +2441,6 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol if (volume->getNumVolumeFaces() <= 0) { llwarns << "Mesh loading returned empty volume." << llendl; - volume->makeTetrahedron(); } { //update system volume @@ -2453,6 +2448,7 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol if (sys_volume) { sys_volume->copyVolumeFaces(volume); + sys_volume->setMeshAssetLoaded(TRUE); LLPrimitive::getVolumeManager()->unrefVolume(sys_volume); } else diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index cbfd64cffb..b097ebcc1d 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -367,6 +367,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, // // Unpack texture entry data // + S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num); if (result & teDirtyBits) { @@ -972,12 +973,8 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo // if it's a mesh if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) { //meshes might not have all LODs, get the force detail to best existing LOD - LLUUID mesh_id = volume_params.getSculptID(); - //profile and path params don't matter for meshes - volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); - lod = gMeshRepo.getActualMeshLOD(volume_params, lod); if (lod == -1) { @@ -1033,14 +1030,13 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo updateSculptTexture(); - if (isSculpted()) { updateSculptTexture(); // if it's a mesh if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) { - if (getVolume()->getNumVolumeFaces() == 0 || getVolume()->isTetrahedron()) + if (!getVolume()->isMeshAssetLoaded()) { //load request not yet issued, request pipeline load this mesh LLUUID asset_id = volume_params.getSculptID(); @@ -3150,7 +3146,7 @@ U32 LLVOVolume::getHighLODTriangleCount() else if (isMesh()) { LLVolume* ref = LLPrimitive::getVolumeManager()->refVolume(volume->getParams(), 3); - if (ref->isTetrahedron() || ref->getNumVolumeFaces() == 0) + if (!ref->isMeshAssetLoaded() || ref->getNumVolumeFaces() == 0) { gMeshRepo.loadMesh(this, volume->getParams(), LLModel::LOD_HIGH); } @@ -3992,7 +3988,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) LLVOVolume* vobj = drawablep->getVOVolume(); - if (vobj->getVolume() && vobj->getVolume()->isTetrahedron() || (vobj->isMesh() && !gMeshRepo.meshRezEnabled())) + if (vobj->isMesh() && + (vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled())) { continue; } -- cgit v1.3 From 7e5be23686b4eefc2a7e161dcac41ec786484114 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Wed, 17 Aug 2011 14:43:39 -0400 Subject: add proper license headers to files that did not have them --- indra/fix-incredibuild.py | 23 ++++++++++++++++++++ indra/lib/python/indra/base/cllsd_test.py | 22 +++++++++++++++++++ indra/lib/python/indra/ipc/httputil.py | 21 ++++++++++++++++++ indra/lib/python/indra/ipc/siesta_test.py | 21 ++++++++++++++++++ indra/lib/python/uuid.py | 21 ++++++++++++++++++ indra/llmath/llcalc.cpp | 25 ++++++++++++++++++---- indra/llmath/llcalc.h | 23 +++++++++++++++++--- indra/llmath/llcalcparser.cpp | 23 +++++++++++++++++--- indra/llmath/llcalcparser.h | 23 +++++++++++++++++--- indra/llwindow/GL/glh_extensions.h | 4 ++++ indra/llwindow/GL/glh_genext.h | 3 +++ .../shaders/class1/avatar/objectSkinV.glsl | 23 +++++++++++++++++--- .../shaders/class1/deferred/alphaSkinnedV.glsl | 23 +++++++++++++++++--- .../shaders/class1/deferred/attachmentShadowF.glsl | 23 +++++++++++++++++--- .../shaders/class1/deferred/attachmentShadowV.glsl | 23 +++++++++++++++++--- .../shaders/class1/deferred/bumpSkinnedV.glsl | 23 +++++++++++++++++--- .../shaders/class1/deferred/diffuseSkinnedV.glsl | 23 +++++++++++++++++--- .../shaders/class1/deferred/sunLightSSAOF.glsl | 23 +++++++++++++++++--- .../shaders/class1/deferred/sunLightSSAOMSF.glsl | 23 +++++++++++++++++--- .../lighting/lightFullbrightShinyWaterF.glsl | 23 +++++++++++++++++--- .../class1/objects/fullbrightShinySkinnedV.glsl | 23 +++++++++++++++++--- .../class1/objects/fullbrightShinyWaterF.glsl | 23 +++++++++++++++++--- .../shaders/class1/objects/fullbrightSkinnedV.glsl | 23 +++++++++++++++++--- .../class1/objects/shinySimpleSkinnedV.glsl | 23 +++++++++++++++++--- .../shaders/class1/objects/simpleSkinnedV.glsl | 23 +++++++++++++++++--- .../shaders/class2/deferred/alphaSkinnedV.glsl | 23 +++++++++++++++++--- .../shaders/class2/deferred/sunLightSSAOF.glsl | 23 +++++++++++++++++--- .../shaders/class2/deferred/sunLightSSAOMSF.glsl | 23 +++++++++++++++++--- .../lighting/lightFullbrightShinyWaterF.glsl | 23 +++++++++++++++++--- .../lightFullbrightShinyWaterNonIndexedF.glsl | 23 +++++++++++++++++--- 30 files changed, 576 insertions(+), 70 deletions(-) (limited to 'indra/llmath') diff --git a/indra/fix-incredibuild.py b/indra/fix-incredibuild.py index b96b00dc85..98f16e9d97 100644 --- a/indra/fix-incredibuild.py +++ b/indra/fix-incredibuild.py @@ -1,3 +1,26 @@ +#!/usr/bin/env python +## +## $LicenseInfo:firstyear=2011&license=viewerlgpl$ +## Second Life Viewer Source Code +## Copyright (C) 2011, Linden Research, Inc. +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; +## version 2.1 of the License only. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +## $/LicenseInfo$ + import sys import os import glob diff --git a/indra/lib/python/indra/base/cllsd_test.py b/indra/lib/python/indra/base/cllsd_test.py index 0b20d99d80..1f06898ffd 100644 --- a/indra/lib/python/indra/base/cllsd_test.py +++ b/indra/lib/python/indra/base/cllsd_test.py @@ -1,3 +1,25 @@ +#!/usr/bin/python +## +## $LicenseInfo:firstyear=2011&license=viewerlgpl$ +## Second Life Viewer Source Code +## Copyright (C) 2011, Linden Research, Inc. +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; +## version 2.1 of the License only. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +## $/LicenseInfo$ from indra.base import llsd, lluuid from datetime import datetime import cllsd diff --git a/indra/lib/python/indra/ipc/httputil.py b/indra/lib/python/indra/ipc/httputil.py index c4ac0a379d..d53f34a771 100644 --- a/indra/lib/python/indra/ipc/httputil.py +++ b/indra/lib/python/indra/ipc/httputil.py @@ -1,3 +1,24 @@ +#!/usr/bin/python +## $LicenseInfo:firstyear=2011&license=viewerlgpl$ +## Second Life Viewer Source Code +## Copyright (C) 2011, Linden Research, Inc. +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; +## version 2.1 of the License only. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +## $/LicenseInfo$ import warnings diff --git a/indra/lib/python/indra/ipc/siesta_test.py b/indra/lib/python/indra/ipc/siesta_test.py index 177ea710d1..a35eed2460 100644 --- a/indra/lib/python/indra/ipc/siesta_test.py +++ b/indra/lib/python/indra/ipc/siesta_test.py @@ -1,3 +1,24 @@ +#!/usr/bin/python +## $LicenseInfo:firstyear=2011&license=viewerlgpl$ +## Second Life Viewer Source Code +## Copyright (C) 2011, Linden Research, Inc. +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; +## version 2.1 of the License only. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +## $/LicenseInfo$ from indra.base import llsd, lluuid from indra.ipc import siesta import datetime, math, unittest diff --git a/indra/lib/python/uuid.py b/indra/lib/python/uuid.py index 0bc21a35f8..e956383cca 100644 --- a/indra/lib/python/uuid.py +++ b/indra/lib/python/uuid.py @@ -1,3 +1,24 @@ +#!/usr/bin/python +## $LicenseInfo:firstyear=2011&license=viewerlgpl$ +## Second Life Viewer Source Code +## Copyright (C) 2011, Linden Research, Inc. +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; +## version 2.1 of the License only. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +## $/LicenseInfo$ r"""UUID objects (universally unique identifiers) according to RFC 4122. This module provides immutable UUID objects (class UUID) and the functions diff --git a/indra/llmath/llcalc.cpp b/indra/llmath/llcalc.cpp index 597d0815fb..1b2d609b67 100644 --- a/indra/llmath/llcalc.cpp +++ b/indra/llmath/llcalc.cpp @@ -1,9 +1,26 @@ /* * LLCalc.cpp - * SecondLife - * - * Created by Aimee Walton on 28/09/2008. - * Copyright 2008 Aimee Walton. + * Copyright 2008 Aimee Walton. + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2008, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ * */ diff --git a/indra/llmath/llcalc.h b/indra/llmath/llcalc.h index cc31950cb6..ceb9dce585 100644 --- a/indra/llmath/llcalc.h +++ b/indra/llmath/llcalc.h @@ -1,9 +1,26 @@ /* * LLCalc.h - * SecondLife - * - * Created by Aimee Walton on 28/09/2008. * Copyright 2008 Aimee Walton. + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2008, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ * */ diff --git a/indra/llmath/llcalcparser.cpp b/indra/llmath/llcalcparser.cpp index fd55376fa9..b4ca320659 100644 --- a/indra/llmath/llcalcparser.cpp +++ b/indra/llmath/llcalcparser.cpp @@ -1,9 +1,26 @@ /* * LLCalcParser.cpp - * SecondLife - * - * Created by Aimee Walton on 28/09/2008. * Copyright 2008 Aimee Walton. + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2008, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ * */ diff --git a/indra/llmath/llcalcparser.h b/indra/llmath/llcalcparser.h index 600e173661..bd9c8c2519 100644 --- a/indra/llmath/llcalcparser.h +++ b/indra/llmath/llcalcparser.h @@ -1,9 +1,26 @@ /* * LLCalcParser.h - * SecondLife - * - * Created by Aimee Walton on 28/09/2008. * Copyright 2008 Aimee Walton. + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2008, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ * */ diff --git a/indra/llwindow/GL/glh_extensions.h b/indra/llwindow/GL/glh_extensions.h index b936b5d307..d89d85930b 100644 --- a/indra/llwindow/GL/glh_extensions.h +++ b/indra/llwindow/GL/glh_extensions.h @@ -1,5 +1,7 @@ /* * glh_extensions.h + * $LicenseInfo:firstyear=2006&license=mit$ (mit used here to satisfy validity checker) + * Copyright (C) 2006, NVIDIA * From nVidia Corporation, downloaded 2006-12-18 from: * http://developer.nvidia.com/attach/8196 * ("NVParse Library with Source (.zip) (2390 KB)") @@ -8,6 +10,8 @@ * "The files bison.exe, bison.simple, and flex.exe are covered by * the GPL. All other files in this distribution can be used however * you want." + * $/LicenseInfo$ + */ #ifndef GLH_EXTENSIONS diff --git a/indra/llwindow/GL/glh_genext.h b/indra/llwindow/GL/glh_genext.h index 8d42025198..cd5d1604a8 100644 --- a/indra/llwindow/GL/glh_genext.h +++ b/indra/llwindow/GL/glh_genext.h @@ -1,5 +1,7 @@ /* * glh_genext.h + * $LicenseInfo:firstyear=2008&license=mit$ (mit used here to satisfy validity checker) + * Copyright (C) 2008, NVIDIA * From nVidia Corporation, downloaded 2006-12-18 from: * http://developer.nvidia.com/attach/8196 * ("NVParse Library with Source (.zip) (2390 KB)") @@ -8,6 +10,7 @@ * "The files bison.exe, bison.simple, and flex.exe are covered by * the GPL. All other files in this distribution can be used however * you want." + * $/LicenseInfo$ */ /* File generated by extgen.cpp -- do not modify */ diff --git a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl index 7613e50dca..09688b2be2 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl @@ -1,8 +1,25 @@ /** * @file objectSkinV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ */ diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl index ac3f7189c2..d57b8f8525 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl @@ -1,8 +1,25 @@ /** * @file alphaSkinnedV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ */ diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl index 870d593311..0c930848e5 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl @@ -1,8 +1,25 @@ /** * @file avatarShadowF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ */ diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl index c7a4f86727..bf4e79d815 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl @@ -1,8 +1,25 @@ /** * @file attachmentShadowV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ */ diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl index dc69519a85..7d934e7ff8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl @@ -1,8 +1,25 @@ /** * @file bumpV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ */ diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl index 2c4caea109..1470d7c9ca 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl @@ -1,8 +1,25 @@ /** * @file diffuseSkinnedV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ */ diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl index 665d8126a0..2f880d65dd 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl @@ -1,8 +1,25 @@ /** * @file sunLightSSAOF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ */ diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOMSF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOMSF.glsl index 32d1b2149a..abb64334ed 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOMSF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOMSF.glsl @@ -1,8 +1,25 @@ /** * @file sunLightSSAOF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ */ diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl index 19072cd052..925d6fbcfd 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl @@ -1,8 +1,25 @@ /** * @file lightFullbrightShinyWaterF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ */ diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl index 5283e80407..e1a7f263f7 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl @@ -1,8 +1,25 @@ /** * @file shinySimpleSkinnedV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ */ diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl index 8ffb252f57..e1f3919907 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl @@ -1,8 +1,25 @@ /** * @file fullbrightShinyWaterF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ */ diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl index 1db79791de..b540054c56 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl @@ -1,8 +1,25 @@ /** * @file fullbrightSkinnedV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ */ diff --git a/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl index eea41bb4f0..f5fd4ededd 100644 --- a/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl @@ -1,8 +1,25 @@ /** * @file shinySimpleSkinnedV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ */ diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl index af92e5e002..ad171f7b43 100644 --- a/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl @@ -1,8 +1,25 @@ /** * @file simpleSkinnedV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ */ diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl index 948a52da5b..20121da52d 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl @@ -1,8 +1,25 @@ /** * @file alphaSkinnedV.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ */ diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index d53850b489..681186d6b2 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -1,8 +1,25 @@ /** * @file sunLightSSAOF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ */ diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOMSF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOMSF.glsl index a2a76eed9f..0fd7b7525d 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOMSF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOMSF.glsl @@ -1,8 +1,25 @@ /** * @file sunLightSSAOF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ */ diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterF.glsl index a6e10a249d..e9dab85095 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterF.glsl @@ -1,8 +1,25 @@ /** * @file lightFullbrightShinyWaterF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ */ diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterNonIndexedF.glsl index b4bb665a2b..e0a7986705 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterNonIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterNonIndexedF.glsl @@ -1,8 +1,25 @@ /** * @file lightFullbrightShinyWaterF.glsl - * - * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. - * $License$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ */ -- cgit v1.3 From 56453f2982464b6d5c86c23e0e75f5adcdd0edff Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Mon, 22 Aug 2011 13:16:58 -0700 Subject: EXP-1129 FIX SLURLs with only 2 coordinates are interpreted as center of sim reviewed by Leslie --- indra/llmath/tests/v3math_test.cpp | 18 ++++++++++++++++++ indra/newview/llslurl.cpp | 6 +++--- 2 files changed, 21 insertions(+), 3 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/tests/v3math_test.cpp b/indra/llmath/tests/v3math_test.cpp index df7a77002f..e4ae1c10ef 100644 --- a/indra/llmath/tests/v3math_test.cpp +++ b/indra/llmath/tests/v3math_test.cpp @@ -564,4 +564,22 @@ namespace tut z1 = U8_to_F32(F32_to_U8(z, lowerz, upperz), lowerz, upperz); ensure("2:quantize8: Fail ", is_approx_equal(x1, vec3a.mV[VX]) && is_approx_equal(y1, vec3a.mV[VY]) && is_approx_equal(z1, vec3a.mV[VZ])); } + + template<> template<> + void v3math_object::test<35>() + { + LLSD sd = LLSD::emptyArray(); + sd[0] = 1.f; + + LLVector3 parsed_1(sd); + ensure("1:LLSD parse: Fail ", is_approx_equal(parsed_1.mV[VX], 1.f) && is_approx_equal(parsed_1.mV[VY], 0.f) && is_approx_equal(parsed_1.mV[VZ], 0.f)); + + sd[1] = 2.f; + LLVector3 parsed_2(sd); + ensure("2:LLSD parse: Fail ", is_approx_equal(parsed_2.mV[VX], 1.f) && is_approx_equal(parsed_2.mV[VY], 2.f) && is_approx_equal(parsed_2.mV[VZ], 0.f)); + + sd[2] = 3.f; + LLVector3 parsed_3(sd); + ensure("3:LLSD parse: Fail ", is_approx_equal(parsed_3.mV[VX], 1.f) && is_approx_equal(parsed_3.mV[VY], 2.f) && is_approx_equal(parsed_3.mV[VZ], 3.f)); + } } diff --git a/indra/newview/llslurl.cpp b/indra/newview/llslurl.cpp index 4cf1df1655..a853726dea 100644 --- a/indra/newview/llslurl.cpp +++ b/indra/newview/llslurl.cpp @@ -273,11 +273,11 @@ LLSLURL::LLSLURL(const std::string& slurl) mRegion = LLURI::unescape(path_array[0].asString()); path_array.erase(0); - // parse the x, y, z - if(path_array.size() >= 3) + // parse the x, y, and optionally z + if(path_array.size() >= 2) { - mPosition = LLVector3(path_array); + mPosition = LLVector3(path_array); // this construction handles LLSD without all components (values default to 0.f) if((F32(mPosition[VX]) < 0.f) || (mPosition[VX] > REGION_WIDTH_METERS) || (F32(mPosition[VY]) < 0.f) || -- cgit v1.3 From 8cef480b96dc779c5879f74224fb0a185ee550f2 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Mon, 29 Aug 2011 18:15:38 -0600 Subject: fix for SH-2311: crash at LLVOVolume::lineSegmentIntersect line 3435 and SH-2358: Crash in LLError::crashAndLoop: Invalid face index --- indra/llmath/llvolume.cpp | 2 +- indra/newview/llvovolume.cpp | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index b2fe9ba6c2..1a95f9cd46 100755 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2734,7 +2734,7 @@ void LLVolume::cacheOptimize() S32 LLVolume::getNumFaces() const { - return (S32)mProfilep->mFaces.size(); + return mIsMeshAssetLoaded ? getNumVolumeFaces() : (S32)mProfilep->mFaces.size(); } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index d3ef1771c3..6b0a5d8642 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1660,11 +1660,16 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) compiled = TRUE; sNumLODChanges += new_num_faces ; + if((S32)getNumTEs() != getVolume()->getNumFaces()) + { + setNumTEs(getVolume()->getNumFaces()); //mesh loading may change number of faces. + } + drawable->setState(LLDrawable::REBUILD_VOLUME); // for face->genVolumeTriangles() { LLFastTimer t(FTM_GEN_TRIANGLES); - if (new_num_faces != old_num_faces) + if (new_num_faces != old_num_faces || mNumFaces != (S32)getNumTEs()) { regenFaces(); } -- cgit v1.3 From 4331c112aba074562e9a8826fe6d271a94f790f0 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 14 Oct 2011 11:52:40 -0500 Subject: Backed out changeset b782a75c99e6 --- doc/contributions.txt | 9 +- indra/llaudio/llaudioengine_fmod.cpp | 2 +- indra/llaudio/llvorbisencode.cpp | 9 +- indra/llcharacter/llbvhloader.cpp | 3 +- indra/llcharacter/llkeyframemotionparam.cpp | 3 +- indra/llcharacter/llstatemachine.cpp | 3 +- indra/llcommon/CMakeLists.txt | 3 - indra/llcommon/llapp.cpp | 4 + indra/llcommon/llapr.cpp | 445 +++++++++++++++++---- indra/llcommon/llapr.h | 107 ++++- indra/llcommon/llaprpool.cpp | 202 ---------- indra/llcommon/llaprpool.h | 256 ------------ indra/llcommon/llcommon.cpp | 13 + indra/llcommon/llcommon.h | 2 + indra/llcommon/llerror.cpp | 3 - indra/llcommon/llerror.h | 1 + indra/llcommon/llfixedbuffer.cpp | 3 +- indra/llcommon/llscopedvolatileaprpool.h | 52 --- indra/llcommon/llthread.cpp | 151 ++++--- indra/llcommon/llthread.h | 124 ++---- indra/llcommon/llthreadsafequeue.cpp | 15 +- indra/llcommon/llthreadsafequeue.h | 16 +- indra/llcommon/llworkerthread.cpp | 8 +- indra/llcommon/llworkerthread.h | 3 +- indra/llcrashlogger/llcrashlogger.cpp | 3 +- indra/llimage/llimage.cpp | 8 +- indra/llimage/llimagedimensionsinfo.cpp | 2 +- indra/llimage/llimagej2c.cpp | 3 +- indra/llimage/llimageworker.cpp | 8 +- indra/llimage/llimageworker.h | 2 +- indra/llmath/llvolumemgr.cpp | 4 +- indra/llmessage/llares.cpp | 17 +- indra/llmessage/llcurl.cpp | 2 +- indra/llmessage/lliohttpserver.cpp | 10 +- indra/llmessage/lliohttpserver.h | 2 +- indra/llmessage/lliosocket.cpp | 99 +++-- indra/llmessage/lliosocket.h | 33 +- indra/llmessage/llmail.cpp | 17 +- indra/llmessage/llmail.h | 4 +- indra/llmessage/llpumpio.cpp | 74 ++-- indra/llmessage/llpumpio.h | 31 +- indra/llmessage/llurlrequest.cpp | 25 +- indra/llmessage/message.cpp | 17 +- indra/llmessage/tests/networkio.h | 9 +- indra/llplugin/llplugininstance.cpp | 6 +- indra/llplugin/llplugininstance.h | 2 - indra/llplugin/llpluginmessagepipe.cpp | 2 + indra/llplugin/llpluginprocesschild.cpp | 2 +- indra/llplugin/llpluginprocessparent.cpp | 57 +-- indra/llplugin/llpluginprocessparent.h | 2 - indra/llplugin/llpluginsharedmemory.cpp | 9 +- indra/llplugin/llpluginsharedmemory.h | 3 - indra/llplugin/slplugin/slplugin.cpp | 4 + indra/llvfs/lllfsthread.cpp | 10 +- indra/llvfs/llvfs.cpp | 5 +- .../gstreamer010/llmediaimplgstreamer.h | 1 + .../gstreamer010/llmediaimplgstreamer_syms.cpp | 15 +- .../media_plugins/webkit/linux_volume_catcher.cpp | 14 +- indra/newview/llappviewer.cpp | 47 +-- indra/newview/llappviewer.h | 2 +- indra/newview/llappviewerlinux.cpp | 1 - indra/newview/llappviewerlinux_api_dbus.cpp | 14 +- indra/newview/llappviewermacosx.cpp | 1 - indra/newview/llfloateranimpreview.cpp | 3 +- indra/newview/llmainlooprepeater.cpp | 2 +- indra/newview/lltexturecache.cpp | 61 +-- indra/newview/lltexturecache.h | 3 + indra/newview/lltexturefetch.cpp | 3 + indra/newview/llviewermenufile.cpp | 3 +- indra/newview/llvoavatar.cpp | 3 +- indra/newview/llvocache.cpp | 54 +-- indra/newview/llvocache.h | 5 +- indra/newview/llvoicevivox.cpp | 2 +- indra/newview/llwatchdog.cpp | 4 +- indra/newview/tests/llworldmap_test.cpp | 1 + indra/test/lltemplatemessagebuilder_tut.cpp | 2 + indra/test/message_tut.cpp | 2 + indra/test/test.cpp | 17 +- indra/test_apps/llplugintest/llmediaplugintest.cpp | 4 + .../updater/llupdateinstaller.cpp | 4 +- 80 files changed, 1080 insertions(+), 1097 deletions(-) delete mode 100644 indra/llcommon/llaprpool.cpp delete mode 100644 indra/llcommon/llaprpool.h delete mode 100644 indra/llcommon/llscopedvolatileaprpool.h (limited to 'indra/llmath') diff --git a/doc/contributions.txt b/doc/contributions.txt index 03e4978dd0..8765240caa 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -61,15 +61,11 @@ Aimee Trescothick Alejandro Rosenthal VWR-1184 Aleric Inglewood - SNOW-84 SNOW-240 - SNOW-477 SNOW-522 SNOW-626 - SNOW-744 SNOW-756 SNOW-764 - SNOW-766 VWR-10001 VWR-10579 VWR-10759 @@ -90,8 +86,11 @@ Aleric Inglewood VWR-24321 VWR-24354 VWR-24519 + SNOW-84 + SNOW-477 + SNOW-744 + SNOW-766 STORM-163 - STORM-864 Ales Beaumont VWR-9352 SNOW-240 diff --git a/indra/llaudio/llaudioengine_fmod.cpp b/indra/llaudio/llaudioengine_fmod.cpp index 88dfdb9c24..a40de9fa68 100644 --- a/indra/llaudio/llaudioengine_fmod.cpp +++ b/indra/llaudio/llaudioengine_fmod.cpp @@ -673,7 +673,7 @@ bool LLAudioBufferFMOD::loadWAV(const std::string& filename) return false; } - if (!LLAPRFile::isExist(filename, LL_APR_RPB)) + if (!LLAPRFile::isExist(filename, NULL, LL_APR_RPB)) { // File not found, abort. return false; diff --git a/indra/llaudio/llvorbisencode.cpp b/indra/llaudio/llvorbisencode.cpp index 44eeea0ca4..0e0c80a456 100644 --- a/indra/llaudio/llvorbisencode.cpp +++ b/indra/llaudio/llvorbisencode.cpp @@ -82,7 +82,8 @@ S32 check_for_invalid_wav_formats(const std::string& in_fname, std::string& erro error_msg.clear(); //******************************** - LLAPRFile infile(in_fname, LL_APR_RB); + LLAPRFile infile ; + infile.open(in_fname,LL_APR_RB); //******************************** if (!infile.getFileHandle()) { @@ -232,7 +233,8 @@ S32 encode_vorbis_file(const std::string& in_fname, const std::string& out_fname S32 data_left = 0; - LLAPRFile infile(in_fname,LL_APR_RB); + LLAPRFile infile ; + infile.open(in_fname,LL_APR_RB); if (!infile.getFileHandle()) { llwarns << "Couldn't open temporary ogg file for writing: " << in_fname @@ -240,7 +242,8 @@ S32 encode_vorbis_file(const std::string& in_fname, const std::string& out_fname return(LLVORBISENC_SOURCE_OPEN_ERR); } - LLAPRFile outfile(out_fname, LL_APR_WPB); + LLAPRFile outfile ; + outfile.open(out_fname,LL_APR_WPB); if (!outfile.getFileHandle()) { llwarns << "Couldn't open upload sound file for reading: " << in_fname diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp index a39a344684..532a2c1b0d 100644 --- a/indra/llcharacter/llbvhloader.cpp +++ b/indra/llcharacter/llbvhloader.cpp @@ -219,7 +219,8 @@ ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName) //-------------------------------------------------------------------- std::string path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,fileName); - LLAPRFile infile(path, LL_APR_R); + LLAPRFile infile ; + infile.open(path, LL_APR_R); apr_file_t *fp = infile.getFileHandle(); if (!fp) return E_ST_NO_XLT_FILE; diff --git a/indra/llcharacter/llkeyframemotionparam.cpp b/indra/llcharacter/llkeyframemotionparam.cpp index c3d5dec875..82fe8971f5 100644 --- a/indra/llcharacter/llkeyframemotionparam.cpp +++ b/indra/llcharacter/llkeyframemotionparam.cpp @@ -351,7 +351,8 @@ BOOL LLKeyframeMotionParam::loadMotions() // open the file //------------------------------------------------------------------------- S32 fileSize = 0; - LLAPRFile infile(path, LL_APR_R, &fileSize); + LLAPRFile infile ; + infile.open(path, LL_APR_R, NULL, &fileSize); apr_file_t* fp = infile.getFileHandle() ; if (!fp || fileSize == 0) { diff --git a/indra/llcharacter/llstatemachine.cpp b/indra/llcharacter/llstatemachine.cpp index dcc4ff5f0e..e0454131a5 100644 --- a/indra/llcharacter/llstatemachine.cpp +++ b/indra/llcharacter/llstatemachine.cpp @@ -204,7 +204,8 @@ LLFSMState* LLStateDiagram::getState(U32 state_id) BOOL LLStateDiagram::saveDotFile(const std::string& filename) { - LLAPRFile outfile(filename, LL_APR_W); + LLAPRFile outfile ; + outfile.open(filename, LL_APR_W); apr_file_t* dot_file = outfile.getFileHandle() ; if (!dot_file) diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index d5b0a67533..9342a22d46 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -32,7 +32,6 @@ set(llcommon_SOURCE_FILES llallocator_heap_profile.cpp llapp.cpp llapr.cpp - llaprpool.cpp llassettype.cpp llavatarname.cpp llbase32.cpp @@ -81,7 +80,6 @@ set(llcommon_SOURCE_FILES llrand.cpp llrefcount.cpp llrun.cpp - llscopedvolatileaprpool.h llsd.cpp llsdserialize.cpp llsdserialize_xml.cpp @@ -123,7 +121,6 @@ set(llcommon_HEADER_FILES llavatarname.h llapp.h llapr.h - llaprpool.h llassettype.h llassoclist.h llavatarconstants.h diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index e5bd2bfa3d..39daefd1ad 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -136,6 +136,10 @@ void LLApp::commonCtor() mOptions.append(sd); } + // Make sure we clean up APR when we exit + // Don't need to do this if we're cleaning up APR in the destructor + //atexit(ll_cleanup_apr); + // Set the application to this instance. sApplication = this; diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index 1e4a51102e..d1c44c9403 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -29,8 +29,212 @@ #include "linden_common.h" #include "llapr.h" #include "apr_dso.h" -#include "llscopedvolatileaprpool.h" +apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool +LLVolatileAPRPool *LLAPRFile::sAPRFilePoolp = NULL ; //global volatile APR memory pool. +apr_thread_mutex_t *gLogMutexp = NULL; +apr_thread_mutex_t *gCallStacksLogMutexp = NULL; + +const S32 FULL_VOLATILE_APR_POOL = 1024 ; //number of references to LLVolatileAPRPool + +void ll_init_apr() +{ + if (!gAPRPoolp) + { + // Initialize APR and create the global pool + apr_initialize(); + apr_pool_create(&gAPRPoolp, NULL); + + // Initialize the logging mutex + apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp); + apr_thread_mutex_create(&gCallStacksLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp); + } + + if(!LLAPRFile::sAPRFilePoolp) + { + LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE) ; + } +} + + +void ll_cleanup_apr() +{ + LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL; + + if (gLogMutexp) + { + // Clean up the logging mutex + + // All other threads NEED to be done before we clean up APR, so this is okay. + apr_thread_mutex_destroy(gLogMutexp); + gLogMutexp = NULL; + } + if (gCallStacksLogMutexp) + { + // Clean up the logging mutex + + // All other threads NEED to be done before we clean up APR, so this is okay. + apr_thread_mutex_destroy(gCallStacksLogMutexp); + gCallStacksLogMutexp = NULL; + } + if (gAPRPoolp) + { + apr_pool_destroy(gAPRPoolp); + gAPRPoolp = NULL; + } + if (LLAPRFile::sAPRFilePoolp) + { + delete LLAPRFile::sAPRFilePoolp ; + LLAPRFile::sAPRFilePoolp = NULL ; + } + apr_terminate(); +} + +// +// +//LLAPRPool +// +LLAPRPool::LLAPRPool(apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag) + : mParent(parent), + mReleasePoolFlag(releasePoolFlag), + mMaxSize(size), + mPool(NULL) +{ + createAPRPool() ; +} + +LLAPRPool::~LLAPRPool() +{ + releaseAPRPool() ; +} + +void LLAPRPool::createAPRPool() +{ + if(mPool) + { + return ; + } + + mStatus = apr_pool_create(&mPool, mParent); + ll_apr_warn_status(mStatus) ; + + if(mMaxSize > 0) //size is the number of blocks (which is usually 4K), NOT bytes. + { + apr_allocator_t *allocator = apr_pool_allocator_get(mPool); + if (allocator) + { + apr_allocator_max_free_set(allocator, mMaxSize) ; + } + } +} + +void LLAPRPool::releaseAPRPool() +{ + if(!mPool) + { + return ; + } + + if(!mParent || mReleasePoolFlag) + { + apr_pool_destroy(mPool) ; + mPool = NULL ; + } +} + +//virtual +apr_pool_t* LLAPRPool::getAPRPool() +{ + return mPool ; +} + +LLVolatileAPRPool::LLVolatileAPRPool(BOOL is_local, apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag) + : LLAPRPool(parent, size, releasePoolFlag), + mNumActiveRef(0), + mNumTotalRef(0), + mMutexPool(NULL), + mMutexp(NULL) +{ + //create mutex + if(!is_local) //not a local apr_pool, that is: shared by multiple threads. + { + apr_pool_create(&mMutexPool, NULL); // Create a pool for mutex + apr_thread_mutex_create(&mMutexp, APR_THREAD_MUTEX_UNNESTED, mMutexPool); + } +} + +LLVolatileAPRPool::~LLVolatileAPRPool() +{ + //delete mutex + if(mMutexp) + { + apr_thread_mutex_destroy(mMutexp); + apr_pool_destroy(mMutexPool); + } +} + +// +//define this virtual function to avoid any mistakenly calling LLAPRPool::getAPRPool(). +// +//virtual +apr_pool_t* LLVolatileAPRPool::getAPRPool() +{ + return LLVolatileAPRPool::getVolatileAPRPool() ; +} + +apr_pool_t* LLVolatileAPRPool::getVolatileAPRPool() +{ + LLScopedLock lock(mMutexp) ; + + mNumTotalRef++ ; + mNumActiveRef++ ; + + if(!mPool) + { + createAPRPool() ; + } + + return mPool ; +} + +void LLVolatileAPRPool::clearVolatileAPRPool() +{ + LLScopedLock lock(mMutexp) ; + + if(mNumActiveRef > 0) + { + mNumActiveRef--; + if(mNumActiveRef < 1) + { + if(isFull()) + { + mNumTotalRef = 0 ; + + //destroy the apr_pool. + releaseAPRPool() ; + } + else + { + //This does not actually free the memory, + //it just allows the pool to re-use this memory for the next allocation. + apr_pool_clear(mPool) ; + } + } + } + else + { + llassert_always(mNumActiveRef > 0) ; + } + + //paranoia check if the pool is jammed. + //will remove the check before going to release. + llassert_always(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ; +} + +BOOL LLVolatileAPRPool::isFull() +{ + return mNumTotalRef > FULL_VOLATILE_APR_POOL ; +} //--------------------------------------------------------------------- // // LLScopedLock @@ -109,17 +313,15 @@ void ll_apr_assert_status(apr_status_t status, apr_dso_handle_t *handle) // LLAPRFile::LLAPRFile() : mFile(NULL), - mVolatileFilePoolp(NULL), - mRegularFilePoolp(NULL) + mCurrentFilePoolp(NULL) { } -LLAPRFile::LLAPRFile(std::string const& filename, apr_int32_t flags, S32* sizep, access_t access_type) +LLAPRFile::LLAPRFile(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool) : mFile(NULL), - mVolatileFilePoolp(NULL), - mRegularFilePoolp(NULL) + mCurrentFilePoolp(NULL) { - open(filename, flags, access_type, sizep); + open(filename, flags, pool); } LLAPRFile::~LLAPRFile() @@ -136,58 +338,36 @@ apr_status_t LLAPRFile::close() mFile = NULL ; } - if (mVolatileFilePoolp) + if(mCurrentFilePoolp) { - mVolatileFilePoolp->clearVolatileAPRPool() ; - mVolatileFilePoolp = NULL ; - } - - if (mRegularFilePoolp) - { - delete mRegularFilePoolp; - mRegularFilePoolp = NULL; + mCurrentFilePoolp->clearVolatileAPRPool() ; + mCurrentFilePoolp = NULL ; } return ret ; } -apr_status_t LLAPRFile::open(std::string const& filename, apr_int32_t flags, access_t access_type, S32* sizep) +apr_status_t LLAPRFile::open(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool, S32* sizep) { - llassert_always(!mFile); - llassert_always(!mVolatileFilePoolp && !mRegularFilePoolp); + apr_status_t s ; - apr_status_t status; - { - apr_pool_t* apr_file_open_pool; // The use of apr_pool_t is OK here. - // This is a temporary variable for a pool that is passed directly to apr_file_open below. - if (access_type == short_lived) - { - // Use a "volatile" thread-local pool. - mVolatileFilePoolp = &LLThreadLocalData::tldata().mVolatileAPRPool; - // Access the pool and increment its reference count. - // The reference count of LLVolatileAPRPool objects will be decremented - // again in LLAPRFile::close by calling mVolatileFilePoolp->clearVolatileAPRPool(). - apr_file_open_pool = mVolatileFilePoolp->getVolatileAPRPool(); - } - else - { - mRegularFilePoolp = new LLAPRPool(LLThreadLocalData::tldata().mRootPool); - apr_file_open_pool = (*mRegularFilePoolp)(); - } - status = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, apr_file_open_pool); - } - if (status != APR_SUCCESS || !mFile) + //check if already open some file + llassert_always(!mFile) ; + llassert_always(!mCurrentFilePoolp) ; + + apr_pool_t* apr_pool = pool ? pool->getVolatileAPRPool() : NULL ; + s = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, getAPRFilePool(apr_pool)); + + if (s != APR_SUCCESS || !mFile) { mFile = NULL ; - close() ; + if (sizep) { *sizep = 0; } - return status; } - - if (sizep) + else if (sizep) { S32 file_size = 0; apr_off_t offset = 0; @@ -201,7 +381,49 @@ apr_status_t LLAPRFile::open(std::string const& filename, apr_int32_t flags, acc *sizep = file_size; } - return status; + if(!mCurrentFilePoolp) + { + mCurrentFilePoolp = pool ; + + if(!mFile) + { + close() ; + } + } + + return s ; +} + +//use gAPRPoolp. +apr_status_t LLAPRFile::open(const std::string& filename, apr_int32_t flags, BOOL use_global_pool) +{ + apr_status_t s; + + //check if already open some file + llassert_always(!mFile) ; + llassert_always(!mCurrentFilePoolp) ; + llassert_always(use_global_pool) ; //be aware of using gAPRPoolp. + + s = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, gAPRPoolp); + if (s != APR_SUCCESS || !mFile) + { + mFile = NULL ; + close() ; + return s; + } + + return s; +} + +apr_pool_t* LLAPRFile::getAPRFilePool(apr_pool_t* pool) +{ + if(!pool) + { + mCurrentFilePoolp = sAPRFilePoolp ; + return mCurrentFilePoolp->getVolatileAPRPool() ; + } + + return pool ; } // File I/O @@ -259,6 +481,45 @@ S32 LLAPRFile::seek(apr_seek_where_t where, S32 offset) //static components of LLAPRFile // +//static +apr_status_t LLAPRFile::close(apr_file_t* file_handle, LLVolatileAPRPool* pool) +{ + apr_status_t ret = APR_SUCCESS ; + if(file_handle) + { + ret = apr_file_close(file_handle); + file_handle = NULL ; + } + + if(pool) + { + pool->clearVolatileAPRPool() ; + } + + return ret ; +} + +//static +apr_file_t* LLAPRFile::open(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags) +{ + apr_status_t s; + apr_file_t* file_handle ; + + pool = pool ? pool : LLAPRFile::sAPRFilePoolp ; + + s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool->getVolatileAPRPool()); + if (s != APR_SUCCESS || !file_handle) + { + ll_apr_warn_status(s); + LL_WARNS("APR") << " Attempting to open filename: " << filename << LL_ENDL; + file_handle = NULL ; + close(file_handle, pool) ; + return NULL; + } + + return file_handle ; +} + //static S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset) { @@ -292,15 +553,13 @@ S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset) } //static -S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes) +S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool) { - apr_file_t* file_handle; - LLScopedVolatileAPRPool pool; - apr_status_t s = apr_file_open(&file_handle, filename.c_str(), APR_READ|APR_BINARY, APR_OS_DEFAULT, pool); - if (s != APR_SUCCESS || !file_handle) + //***************************************** + apr_file_t* file_handle = open(filename, pool, APR_READ|APR_BINARY); + //***************************************** + if (!file_handle) { - ll_apr_warn_status(s); - LL_WARNS("APR") << " while attempting to open file \"" << filename << '"' << LL_ENDL; return 0; } @@ -330,13 +589,14 @@ S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nb } } - apr_file_close(file_handle); - + //***************************************** + close(file_handle, pool) ; + //***************************************** return (S32)bytes_read; } //static -S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes) +S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool) { apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY; if (offset < 0) @@ -345,13 +605,11 @@ S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 n offset = 0; } - apr_file_t* file_handle; - LLScopedVolatileAPRPool pool; - apr_status_t s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool); - if (s != APR_SUCCESS || !file_handle) + //***************************************** + apr_file_t* file_handle = open(filename, pool, flags); + //***************************************** + if (!file_handle) { - ll_apr_warn_status(s); - LL_WARNS("APR") << " while attempting to open file \"" << filename << '"' << LL_ENDL; return 0; } @@ -381,18 +639,21 @@ S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 n } } - apr_file_close(file_handle); + //***************************************** + LLAPRFile::close(file_handle, pool); + //***************************************** return (S32)bytes_written; } //static -bool LLAPRFile::remove(const std::string& filename) +bool LLAPRFile::remove(const std::string& filename, LLVolatileAPRPool* pool) { apr_status_t s; - LLScopedVolatileAPRPool pool; - s = apr_file_remove(filename.c_str(), pool); + pool = pool ? pool : LLAPRFile::sAPRFilePoolp ; + s = apr_file_remove(filename.c_str(), pool->getVolatileAPRPool()); + pool->clearVolatileAPRPool() ; if (s != APR_SUCCESS) { @@ -404,12 +665,13 @@ bool LLAPRFile::remove(const std::string& filename) } //static -bool LLAPRFile::rename(const std::string& filename, const std::string& newname) +bool LLAPRFile::rename(const std::string& filename, const std::string& newname, LLVolatileAPRPool* pool) { apr_status_t s; - LLScopedVolatileAPRPool pool; - s = apr_file_rename(filename.c_str(), newname.c_str(), pool); + pool = pool ? pool : LLAPRFile::sAPRFilePoolp ; + s = apr_file_rename(filename.c_str(), newname.c_str(), pool->getVolatileAPRPool()); + pool->clearVolatileAPRPool() ; if (s != APR_SUCCESS) { @@ -421,44 +683,49 @@ bool LLAPRFile::rename(const std::string& filename, const std::string& newname) } //static -bool LLAPRFile::isExist(const std::string& filename, apr_int32_t flags) +bool LLAPRFile::isExist(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags) { - apr_file_t* file_handle; + apr_file_t* apr_file; apr_status_t s; - LLScopedVolatileAPRPool pool; - s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool); + pool = pool ? pool : LLAPRFile::sAPRFilePoolp ; + s = apr_file_open(&apr_file, filename.c_str(), flags, APR_OS_DEFAULT, pool->getVolatileAPRPool()); - if (s != APR_SUCCESS || !file_handle) + if (s != APR_SUCCESS || !apr_file) { + pool->clearVolatileAPRPool() ; return false; } else { - apr_file_close(file_handle); + apr_file_close(apr_file) ; + pool->clearVolatileAPRPool() ; return true; } } //static -S32 LLAPRFile::size(const std::string& filename) +S32 LLAPRFile::size(const std::string& filename, LLVolatileAPRPool* pool) { - apr_file_t* file_handle; + apr_file_t* apr_file; apr_finfo_t info; apr_status_t s; - LLScopedVolatileAPRPool pool; - s = apr_file_open(&file_handle, filename.c_str(), APR_READ, APR_OS_DEFAULT, pool); + pool = pool ? pool : LLAPRFile::sAPRFilePoolp ; + s = apr_file_open(&apr_file, filename.c_str(), APR_READ, APR_OS_DEFAULT, pool->getVolatileAPRPool()); - if (s != APR_SUCCESS || !file_handle) + if (s != APR_SUCCESS || !apr_file) { + pool->clearVolatileAPRPool() ; + return 0; } else { - apr_status_t s = apr_file_info_get(&info, APR_FINFO_SIZE, file_handle); + apr_status_t s = apr_file_info_get(&info, APR_FINFO_SIZE, apr_file); - apr_file_close(file_handle) ; + apr_file_close(apr_file) ; + pool->clearVolatileAPRPool() ; if (s == APR_SUCCESS) { @@ -472,29 +739,31 @@ S32 LLAPRFile::size(const std::string& filename) } //static -bool LLAPRFile::makeDir(const std::string& dirname) +bool LLAPRFile::makeDir(const std::string& dirname, LLVolatileAPRPool* pool) { apr_status_t s; - LLScopedVolatileAPRPool pool; - s = apr_dir_make(dirname.c_str(), APR_FPROT_OS_DEFAULT, pool); + pool = pool ? pool : LLAPRFile::sAPRFilePoolp ; + s = apr_dir_make(dirname.c_str(), APR_FPROT_OS_DEFAULT, pool->getVolatileAPRPool()); + pool->clearVolatileAPRPool() ; if (s != APR_SUCCESS) { ll_apr_warn_status(s); - LL_WARNS("APR") << " while attempting to make directory: " << dirname << LL_ENDL; + LL_WARNS("APR") << " Attempting to make directory: " << dirname << LL_ENDL; return false; } return true; } //static -bool LLAPRFile::removeDir(const std::string& dirname) +bool LLAPRFile::removeDir(const std::string& dirname, LLVolatileAPRPool* pool) { apr_status_t s; - LLScopedVolatileAPRPool pool; - s = apr_file_remove(dirname.c_str(), pool); + pool = pool ? pool : LLAPRFile::sAPRFilePoolp ; + s = apr_file_remove(dirname.c_str(), pool->getVolatileAPRPool()); + pool->clearVolatileAPRPool() ; if (s != APR_SUCCESS) { diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index 3f846f1314..af33ce666f 100644 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -50,9 +50,71 @@ #include "apr_atomic.h" #include "llstring.h" +extern LL_COMMON_API apr_thread_mutex_t* gLogMutexp; +extern apr_thread_mutex_t* gCallStacksLogMutexp; + struct apr_dso_handle_t; -class LLAPRPool; -class LLVolatileAPRPool; + +/** + * @brief initialize the common apr constructs -- apr itself, the + * global pool, and a mutex. + */ +void LL_COMMON_API ll_init_apr(); + +/** + * @brief Cleanup those common apr constructs. + */ +void LL_COMMON_API ll_cleanup_apr(); + +// +//LL apr_pool +//manage apr_pool_t, destroy allocated apr_pool in the destruction function. +// +class LL_COMMON_API LLAPRPool +{ +public: + LLAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE) ; + virtual ~LLAPRPool() ; + + virtual apr_pool_t* getAPRPool() ; + apr_status_t getStatus() {return mStatus ; } + +protected: + void releaseAPRPool() ; + void createAPRPool() ; + +protected: + apr_pool_t* mPool ; //pointing to an apr_pool + apr_pool_t* mParent ; //parent pool + apr_size_t mMaxSize ; //max size of mPool, mPool should return memory to system if allocated memory beyond this limit. However it seems not to work. + apr_status_t mStatus ; //status when creating the pool + BOOL mReleasePoolFlag ; //if set, mPool is destroyed when LLAPRPool is deleted. default value is true. +}; + +// +//volatile LL apr_pool +//which clears memory automatically. +//so it can not hold static data or data after memory is cleared +// +class LL_COMMON_API LLVolatileAPRPool : public LLAPRPool +{ +public: + LLVolatileAPRPool(BOOL is_local = TRUE, apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE); + virtual ~LLVolatileAPRPool(); + + /*virtual*/ apr_pool_t* getAPRPool() ; //define this virtual function to avoid any mistakenly calling LLAPRPool::getAPRPool(). + apr_pool_t* getVolatileAPRPool() ; + void clearVolatileAPRPool() ; + + BOOL isFull() ; + +private: + S32 mNumActiveRef ; //number of active pointers pointing to the apr_pool. + S32 mNumTotalRef ; //number of total pointers pointing to the apr_pool since last creating. + + apr_thread_mutex_t *mMutexp; + apr_pool_t *mMutexPool; +} ; /** * @class LLScopedLock @@ -143,20 +205,15 @@ class LL_COMMON_API LLAPRFile : boost::noncopyable // make this non copyable since a copy closes the file private: apr_file_t* mFile ; - LLVolatileAPRPool* mVolatileFilePoolp; // (Thread local) APR pool currently in use. - LLAPRPool* mRegularFilePoolp; // ...or a regular pool. + LLVolatileAPRPool *mCurrentFilePoolp ; //currently in use apr_pool, could be one of them: sAPRFilePoolp, or a temp pool. public: - enum access_t { - long_lived, // Use a global pool for long-lived file accesses. - short_lived // Use a volatile pool for short-lived file accesses. - }; - LLAPRFile() ; - LLAPRFile(std::string const& filename, apr_int32_t flags, S32* sizep = NULL, access_t access_type = short_lived); + LLAPRFile(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool = NULL); ~LLAPRFile() ; - - apr_status_t open(const std::string& filename, apr_int32_t flags, access_t access_type, S32* sizep = NULL); + + apr_status_t open(const std::string& filename, apr_int32_t flags, LLVolatileAPRPool* pool = NULL, S32* sizep = NULL); + apr_status_t open(const std::string& filename, apr_int32_t flags, BOOL use_global_pool); //use gAPRPoolp. apr_status_t close() ; // Returns actual offset, -1 if seek fails @@ -169,24 +226,32 @@ public: apr_file_t* getFileHandle() {return mFile;} +private: + apr_pool_t* getAPRFilePool(apr_pool_t* pool) ; + // //******************************************************************************************************************************* //static components // +public: + static LLVolatileAPRPool *sAPRFilePoolp ; //a global apr_pool for APRFile, which is used only when local pool does not exist. + private: + static apr_file_t* open(const std::string& filename, LLVolatileAPRPool* pool, apr_int32_t flags); + static apr_status_t close(apr_file_t* file, LLVolatileAPRPool* pool) ; static S32 seek(apr_file_t* file, apr_seek_where_t where, S32 offset); public: // returns false if failure: - static bool remove(const std::string& filename); - static bool rename(const std::string& filename, const std::string& newname); - static bool isExist(const std::string& filename, apr_int32_t flags = APR_READ); - static S32 size(const std::string& filename); - static bool makeDir(const std::string& dirname); - static bool removeDir(const std::string& dirname); + static bool remove(const std::string& filename, LLVolatileAPRPool* pool = NULL); + static bool rename(const std::string& filename, const std::string& newname, LLVolatileAPRPool* pool = NULL); + static bool isExist(const std::string& filename, LLVolatileAPRPool* pool = NULL, apr_int32_t flags = APR_READ); + static S32 size(const std::string& filename, LLVolatileAPRPool* pool = NULL); + static bool makeDir(const std::string& dirname, LLVolatileAPRPool* pool = NULL); + static bool removeDir(const std::string& dirname, LLVolatileAPRPool* pool = NULL); // Returns bytes read/written, 0 if read/write fails: - static S32 readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes); - static S32 writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes); // offset<0 means append + static S32 readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool = NULL); + static S32 writeEx(const std::string& filename, void *buf, S32 offset, S32 nbytes, LLVolatileAPRPool* pool = NULL); // offset<0 means append //******************************************************************************************************************************* }; @@ -202,4 +267,6 @@ bool LL_COMMON_API ll_apr_warn_status(apr_status_t status, apr_dso_handle_t* han void LL_COMMON_API ll_apr_assert_status(apr_status_t status); void LL_COMMON_API ll_apr_assert_status(apr_status_t status, apr_dso_handle_t* handle); +extern "C" LL_COMMON_API apr_pool_t* gAPRPoolp; // Global APR memory pool + #endif // LL_LLAPR_H diff --git a/indra/llcommon/llaprpool.cpp b/indra/llcommon/llaprpool.cpp deleted file mode 100644 index 6f21b61b65..0000000000 --- a/indra/llcommon/llaprpool.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/** - * @file llaprpool.cpp - * - * $LicenseInfo:firstyear=2011&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2011, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - * - * CHANGELOG - * and additional copyright holders. - * - * 04/04/2010 - * - Initial version, written by Aleric Inglewood @ SL - * - * 10/11/2010 - * - Added APR_HAS_THREADS #if's to allow creation and destruction - * of subpools by threads other than the parent pool owner. - */ - -#include "linden_common.h" - -#include "llerror.h" -#include "llaprpool.h" -#include "llthread.h" - -// Create a subpool from parent. -void LLAPRPool::create(LLAPRPool& parent) -{ - llassert(!mPool); // Must be non-initialized. - mParent = &parent; - if (!mParent) // Using the default parameter? - { - // By default use the root pool of the current thread. - mParent = &LLThreadLocalData::tldata().mRootPool; - } - llassert(mParent->mPool); // Parent must be initialized. -#if APR_HAS_THREADS - // As per the documentation of APR (ie http://apr.apache.org/docs/apr/1.4/apr__pools_8h.html): - // - // Note that most operations on pools are not thread-safe: a single pool should only be - // accessed by a single thread at any given time. The one exception to this rule is creating - // a subpool of a given pool: one or more threads can safely create subpools at the same - // time that another thread accesses the parent pool. - // - // In other words, it's safe for any thread to create a (sub)pool, independent of who - // owns the parent pool. - mOwner = apr_os_thread_current(); -#else - mOwner = mParent->mOwner; - llassert(apr_os_thread_equal(mOwner, apr_os_thread_current())); -#endif - apr_status_t const apr_pool_create_status = apr_pool_create(&mPool, mParent->mPool); - llassert_always(apr_pool_create_status == APR_SUCCESS); - llassert(mPool); // Initialized. - apr_pool_cleanup_register(mPool, this, &s_plain_cleanup, &apr_pool_cleanup_null); -} - -// Destroy the (sub)pool, if any. -void LLAPRPool::destroy(void) -{ - // Only do anything if we are not already (being) destroyed. - if (mPool) - { -#if !APR_HAS_THREADS - // If we are a root pool, then every thread may destruct us: in that case - // we have to assume that no other thread will use this pool concurrently, - // of course. Otherwise, if we are a subpool, only the thread that owns - // the parent may destruct us, since that is the pool that is still alive, - // possibly being used by others and being altered here. - llassert(!mParent || apr_os_thread_equal(mParent->mOwner, apr_os_thread_current())); -#endif - apr_pool_t* pool = mPool; // The use of apr_pool_t is OK here. - // Temporary store before destroying the pool. - mPool = NULL; // Mark that we are BEING destructed. - apr_pool_cleanup_kill(pool, this, &s_plain_cleanup); - apr_pool_destroy(pool); - } -} - -bool LLAPRPool::parent_is_being_destructed(void) -{ - return mParent && (!mParent->mPool || mParent->parent_is_being_destructed()); -} - -LLAPRInitialization::LLAPRInitialization(void) -{ - static bool apr_initialized = false; - - if (!apr_initialized) - { - apr_initialize(); - } - - apr_initialized = true; -} - -bool LLAPRRootPool::sCountInitialized = false; -apr_uint32_t volatile LLAPRRootPool::sCount; - -apr_thread_mutex_t* gLogMutexp; -apr_thread_mutex_t* gCallStacksLogMutexp; - -LLAPRRootPool::LLAPRRootPool(void) : LLAPRInitialization(), LLAPRPool(0) -{ - // sCountInitialized don't need locking because when we get here there is still only a single thread. - if (!sCountInitialized) - { - // Initialize the logging mutex - apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, mPool); - apr_thread_mutex_create(&gCallStacksLogMutexp, APR_THREAD_MUTEX_UNNESTED, mPool); - - apr_status_t status = apr_atomic_init(mPool); - llassert_always(status == APR_SUCCESS); - apr_atomic_set32(&sCount, 1); // Set to 1 to account for the global root pool. - sCountInitialized = true; - - // Initialize thread-local APR pool support. - // Because this recursively calls LLAPRRootPool::LLAPRRootPool(void) - // it must be done last, so that sCount is already initialized. - LLThreadLocalData::init(); - } - apr_atomic_inc32(&sCount); -} - -LLAPRRootPool::~LLAPRRootPool() -{ - if (!apr_atomic_dec32(&sCount)) - { - // The last pool was destructed. Cleanup remainder of APR. - LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL; - - if (gLogMutexp) - { - // Clean up the logging mutex - - // All other threads NEED to be done before we clean up APR, so this is okay. - apr_thread_mutex_destroy(gLogMutexp); - gLogMutexp = NULL; - } - if (gCallStacksLogMutexp) - { - // Clean up the logging mutex - - // All other threads NEED to be done before we clean up APR, so this is okay. - apr_thread_mutex_destroy(gCallStacksLogMutexp); - gCallStacksLogMutexp = NULL; - } - - // Must destroy ALL, and therefore this last LLAPRRootPool, before terminating APR. - static_cast(this)->destroy(); - - apr_terminate(); - } -} - -//static -// Return a global root pool that is independent of LLThreadLocalData. -// Normally you should NOT use this. Only use for early initialization -// (before main) and deinitialization (after main). -LLAPRRootPool& LLAPRRootPool::get(void) -{ - static LLAPRRootPool global_APRpool(0); - return global_APRpool; -} - -void LLVolatileAPRPool::clearVolatileAPRPool() -{ - llassert_always(mNumActiveRef > 0); - if (--mNumActiveRef == 0) - { - if (isOld()) - { - destroy(); - mNumTotalRef = 0 ; - } - else - { - // This does not actually free the memory, - // it just allows the pool to re-use this memory for the next allocation. - clear(); - } - } - - // Paranoia check if the pool is jammed. - llassert(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ; -} diff --git a/indra/llcommon/llaprpool.h b/indra/llcommon/llaprpool.h deleted file mode 100644 index bf4102c584..0000000000 --- a/indra/llcommon/llaprpool.h +++ /dev/null @@ -1,256 +0,0 @@ -/** - * @file llaprpool.h - * @brief Implementation of LLAPRPool - * - * $LicenseInfo:firstyear=2011&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2011, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - * - * CHANGELOG - * and additional copyright holders. - * - * 04/04/2010 - * - Initial version, written by Aleric Inglewood @ SL - * - * 10/11/2010 - * - Added APR_HAS_THREADS #if's to allow creation and destruction - * of subpools by threads other than the parent pool owner. - * - * 05/02/2011 - * - Fixed compilation on windows: Suppress compile warning 4996 - * and include before including , - * by Merov Linden @ SL. - */ - -#ifndef LL_LLAPRPOOL_H -#define LL_LLAPRPOOL_H - -#ifdef LL_WINDOWS -#pragma warning(push) -#pragma warning(disable:4996) -#include -#include // Needed before including apr_portable.h -#pragma warning(pop) -#endif - -#include "apr_portable.h" -#include "apr_pools.h" -#include "llerror.h" - -extern void ll_init_apr(); - -/** - * @brief A wrapper around the APR memory pool API. - * - * Usage of this class should be restricted to passing it to libapr-1 function calls that need it. - * - */ -class LL_COMMON_API LLAPRPool -{ -protected: - //! Pointer to the underlaying pool. NULL if not initialized. - apr_pool_t* mPool; // The use of apr_pool_t is OK here. - // This is the wrapped pointer that it is all about! - //! Pointer to the parent pool, if any. Only valid when mPool is non-zero. - LLAPRPool* mParent; - //! The thread that owns this memory pool. Only valid when mPool is non-zero. - apr_os_thread_t mOwner; - -public: - /// Construct an uninitialized (destructed) pool. - LLAPRPool(void) : mPool(NULL) { } - - /// Construct a subpool from an existing pool. - /// This is not a copy-constructor, this class doesn't have one! - LLAPRPool(LLAPRPool& parent) : mPool(NULL) { create(parent); } - - /// Destruct the memory pool (free all of its subpools and allocated memory). - ~LLAPRPool() { destroy(); } - -protected: - /// Create a pool that is allocated from the Operating System. Only used by LLAPRRootPool. - LLAPRPool(int) : mPool(NULL), mParent(NULL), mOwner(apr_os_thread_current()) - { - apr_status_t const apr_pool_create_status = apr_pool_create(&mPool, NULL); - llassert_always(apr_pool_create_status == APR_SUCCESS); - llassert(mPool); - apr_pool_cleanup_register(mPool, this, &s_plain_cleanup, &apr_pool_cleanup_null); - } - -public: - /// Create a subpool from parent. May only be called for an uninitialized/destroyed pool. - /// The default parameter causes the root pool of the current thread to be used. - void create(LLAPRPool& parent = *static_cast(NULL)); - - /// Destroy the (sub)pool, if any. - void destroy(void); - - // Use some safebool idiom (http://www.artima.com/cppsource/safebool.html) rather than operator bool. - typedef LLAPRPool* const LLAPRPool::* const bool_type; - /// Return true if the pool is initialized. - operator bool_type() const { return mPool ? &LLAPRPool::mParent : 0; } - - /// Painful, but we have to either provide access to this, or wrap - /// every APR function call that needs an apr pool as argument. - /// NEVER destroy a pool that is returned by this function! - apr_pool_t* operator()(void) const // The use of apr_pool_t is OK here. - // This is the accessor for passing the pool to libapr-1 functions. - { - llassert(mPool); - llassert(apr_os_thread_equal(mOwner, apr_os_thread_current())); - return mPool; - } - - /// Free all memory without destructing the pool. - void clear(void) - { - llassert(mPool); - llassert(apr_os_thread_equal(mOwner, apr_os_thread_current())); - apr_pool_clear(mPool); - } - -// These methods would make this class 'complete' (as wrapper around the libapr -// pool functions), but we don't use memory pools in the viewer (only when -// we are forced to pass one to a libapr call), so don't define them in order -// not to encourage people to use them. -#if 0 - void* palloc(size_t size) - { - llassert(mPool); - llassert(apr_os_thread_equal(mOwner, apr_os_thread_current())); - return apr_palloc(mPool, size); - } - void* pcalloc(size_t size) - { - llassert(mPool); - llassert(apr_os_thread_equal(mOwner, apr_os_thread_current())); - return apr_pcalloc(mPool, size); - } -#endif - -private: - bool parent_is_being_destructed(void); - static apr_status_t s_plain_cleanup(void* userdata) { return static_cast(userdata)->plain_cleanup(); } - - apr_status_t plain_cleanup(void) - { - if (mPool && // We are not being destructed, - parent_is_being_destructed()) // but our parent is. - // This means the pool is being destructed recursively by libapr - // because one of its parents is being destructed. - { - mPool = NULL; // Stop destroy() from destructing the pool again. - } - return APR_SUCCESS; - } -}; - -class LLAPRInitialization -{ -public: - LLAPRInitialization(void); -}; - -/** - * @brief Root memory pool (allocates memory from the operating system). - * - * This class should only be used by LLThreadLocalData - * (and LLMutexRootPool when APR_HAS_THREADS isn't defined). - */ -class LL_COMMON_API LLAPRRootPool : public LLAPRInitialization, public LLAPRPool -{ -private: - /// Construct a root memory pool. Should only be used by LLThreadLocalData and LLMutexRootPool. - friend class LLThreadLocalData; -#if !APR_HAS_THREADS - friend class LLMutexRootPool; -#endif - /// Construct a root memory pool. - /// Should only be used by LLThreadLocalData. - LLAPRRootPool(void); - ~LLAPRRootPool(); - -private: - // Keep track of how many root pools exist and when the last one is destructed. - static bool sCountInitialized; - static apr_uint32_t volatile sCount; - -public: - // Return a global root pool that is independent of LLThreadLocalData. - // Normally you should not use this. Only use for early initialization - // (before main) and deinitialization (after main). - static LLAPRRootPool& get(void); - -#if APR_POOL_DEBUG - void grab_ownership(void) - { - // You need a patched libapr to use this. - // See http://web.archiveorange.com/archive/v/5XO9y2zoxUOMt6Gmi1OI - apr_pool_owner_set(mPool); - } -#endif - -private: - // Used for constructing the Special Global Root Pool (returned by LLAPRRootPool::get). - // It is the same as the default constructor but omits to increment sCount. As a result, - // we must be sure that at least one other LLAPRRootPool is created before termination - // of the application (which is the case: we create one LLAPRRootPool per thread). - LLAPRRootPool(int) : LLAPRInitialization(), LLAPRPool(0) { } -}; - -/** Volatile memory pool - * - * 'Volatile' APR memory pool which normally only clears memory, - * and does not destroy the pool (the same pool is reused) for - * greater efficiency. However, as a safe guard the apr pool - * is destructed every FULL_VOLATILE_APR_POOL uses to allow - * the system memory to be allocated more efficiently and not - * get scattered through RAM. - */ -class LL_COMMON_API LLVolatileAPRPool : protected LLAPRPool -{ -public: - LLVolatileAPRPool(void) : mNumActiveRef(0), mNumTotalRef(0) { } - - void clearVolatileAPRPool(void); - - bool isOld(void) const { return mNumTotalRef > FULL_VOLATILE_APR_POOL; } - bool isUnused() const { return mNumActiveRef == 0; } - -private: - friend class LLScopedVolatileAPRPool; - friend class LLAPRFile; - apr_pool_t* getVolatileAPRPool(void) // The use of apr_pool_t is OK here. - { - if (!mPool) create(); - ++mNumActiveRef; - ++mNumTotalRef; - return LLAPRPool::operator()(); - } - -private: - S32 mNumActiveRef; // Number of active uses of the pool. - S32 mNumTotalRef; // Number of total uses of the pool since last creation. - - // Maximum number of references to LLVolatileAPRPool until the pool is recreated. - static S32 const FULL_VOLATILE_APR_POOL = 1024; -}; - -#endif // LL_LLAPRPOOL_H diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp index b8a7394852..8be9e4f4de 100644 --- a/indra/llcommon/llcommon.cpp +++ b/indra/llcommon/llcommon.cpp @@ -30,10 +30,18 @@ #include "llmemory.h" #include "llthread.h" +//static +BOOL LLCommon::sAprInitialized = FALSE; + //static void LLCommon::initClass() { LLMemory::initClass(); + if (!sAprInitialized) + { + ll_init_apr(); + sAprInitialized = TRUE; + } LLTimer::initClass(); LLThreadSafeRefCount::initThreadSafeRefCount(); // LLWorkerThread::initClass(); @@ -47,5 +55,10 @@ void LLCommon::cleanupClass() // LLWorkerThread::cleanupClass(); LLThreadSafeRefCount::cleanupThreadSafeRefCount(); LLTimer::cleanupClass(); + if (sAprInitialized) + { + ll_cleanup_apr(); + sAprInitialized = FALSE; + } LLMemory::cleanupClass(); } diff --git a/indra/llcommon/llcommon.h b/indra/llcommon/llcommon.h index 171590f3d8..ca9cad5d05 100644 --- a/indra/llcommon/llcommon.h +++ b/indra/llcommon/llcommon.h @@ -35,6 +35,8 @@ class LL_COMMON_API LLCommon public: static void initClass(); static void cleanupClass(); +private: + static BOOL sAprInitialized; }; #endif diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 75048073ca..bb64152407 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -866,9 +866,6 @@ You get: */ -extern apr_thread_mutex_t* gLogMutexp; -extern apr_thread_mutex_t* gCallStacksLogMutexp; - namespace { bool checkLevelMap(const LevelMap& map, const std::string& key, LLError::ELevel& level) diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 15d167c32e..4a42241c4f 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -296,4 +296,5 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG; Such computation is done iff the message will be logged. */ + #endif // LL_LLERROR_H diff --git a/indra/llcommon/llfixedbuffer.cpp b/indra/llcommon/llfixedbuffer.cpp index 4b5cdbe288..d394f179fb 100644 --- a/indra/llcommon/llfixedbuffer.cpp +++ b/indra/llcommon/llfixedbuffer.cpp @@ -30,7 +30,8 @@ LLFixedBuffer::LLFixedBuffer(const U32 max_lines) : LLLineBuffer(), - mMaxLines(max_lines) + mMaxLines(max_lines), + mMutex(NULL) { mTimer.reset(); } diff --git a/indra/llcommon/llscopedvolatileaprpool.h b/indra/llcommon/llscopedvolatileaprpool.h deleted file mode 100644 index dbaf4edcad..0000000000 --- a/indra/llcommon/llscopedvolatileaprpool.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @file llscopedvolatileaprpool.h - * @brief Implementation of LLScopedVolatileAPRPool - * - * $LicenseInfo:firstyear=2010&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2011, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLSCOPEDVOLATILEAPRPOOL_H -#define LL_LLSCOPEDVOLATILEAPRPOOL_H - -#include "llthread.h" - -/** Scoped volatile memory pool. - * - * As the LLVolatileAPRPool should never keep allocations very - * long, its most common use is for allocations with a lifetime - * equal to it's scope. - * - * This is a convenience class that makes just a little easier to type. - */ -class LL_COMMON_API LLScopedVolatileAPRPool -{ -private: - LLVolatileAPRPool& mPool; - apr_pool_t* mScopedAPRpool; // The use of apr_pool_t is OK here. -public: - LLScopedVolatileAPRPool() : mPool(LLThreadLocalData::tldata().mVolatileAPRPool), mScopedAPRpool(mPool.getVolatileAPRPool()) { } - ~LLScopedVolatileAPRPool() { mPool.clearVolatileAPRPool(); } - //! @attention Only use this to pass the underlaying pointer to a libapr-1 function that requires it. - operator apr_pool_t*() const { return mScopedAPRpool; } // The use of apr_pool_t is OK here. -}; - -#endif diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 4917e3b935..49d05ef411 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -63,9 +63,6 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap { LLThread *threadp = (LLThread *)datap; - // Create a thread local data. - LLThreadLocalData::create(threadp); - // Run the user supplied function threadp->run(); @@ -78,20 +75,38 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap } -LLThread::LLThread(std::string const& name) : - mPaused(false), +LLThread::LLThread(const std::string& name, apr_pool_t *poolp) : + mPaused(FALSE), mName(name), mAPRThreadp(NULL), - mStatus(STOPPED), - mThreadLocalData(NULL) + mStatus(STOPPED) { - mRunCondition = new LLCondition; + // Thread creation probably CAN be paranoid about APR being initialized, if necessary + if (poolp) + { + mIsLocalPool = FALSE; + mAPRPoolp = poolp; + } + else + { + mIsLocalPool = TRUE; + apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread + } + mRunCondition = new LLCondition(mAPRPoolp); + + mLocalAPRFilePoolp = NULL ; } LLThread::~LLThread() { shutdown(); + + if(mLocalAPRFilePoolp) + { + delete mLocalAPRFilePoolp ; + mLocalAPRFilePoolp = NULL ; + } } void LLThread::shutdown() @@ -128,7 +143,7 @@ void LLThread::shutdown() if (!isStopped()) { // This thread just wouldn't stop, even though we gave it time - llwarns << "LLThread::shutdown() exiting thread before clean exit!" << llendl; + llwarns << "LLThread::~LLThread() exiting thread before clean exit!" << llendl; // Put a stake in its heart. apr_thread_exit(mAPRThreadp, -1); return; @@ -138,8 +153,15 @@ void LLThread::shutdown() delete mRunCondition; mRunCondition = 0; + + if (mIsLocalPool && mAPRPoolp) + { + apr_pool_destroy(mAPRPoolp); + mAPRPoolp = 0; + } } + void LLThread::start() { llassert(isStopped()); @@ -148,7 +170,7 @@ void LLThread::start() mStatus = RUNNING; apr_status_t status = - apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, tldata().mRootPool()); + apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, mAPRPoolp); if(status == APR_SUCCESS) { @@ -173,7 +195,7 @@ void LLThread::pause() if (!mPaused) { // this will cause the thread to stop execution as soon as checkPause() is called - mPaused = true; // Does not need to be atomic since this is only set/unset from the main thread + mPaused = 1; // Does not need to be atomic since this is only set/unset from the main thread } } @@ -181,7 +203,7 @@ void LLThread::unpause() { if (mPaused) { - mPaused = false; + mPaused = 0; } wake(); // wake up the thread if necessary @@ -258,76 +280,85 @@ void LLThread::wakeLocked() } } -#ifdef SHOW_ASSERT -// This allows the use of llassert(is_main_thread()) to assure the current thread is the main thread. -static apr_os_thread_t main_thread_id; -LL_COMMON_API bool is_main_thread(void) { return apr_os_thread_equal(main_thread_id, apr_os_thread_current()); } -#endif - -// The thread private handle to access the LLThreadLocalData instance. -apr_threadkey_t* LLThreadLocalData::sThreadLocalDataKey; +//============================================================================ -//static -void LLThreadLocalData::init(void) +LLMutex::LLMutex(apr_pool_t *poolp) : + mAPRMutexp(NULL) { - // Only do this once. - if (sThreadLocalDataKey) + //if (poolp) + //{ + // mIsLocalPool = FALSE; + // mAPRPoolp = poolp; + //} + //else { - return; + mIsLocalPool = TRUE; + apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread } + apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp); +} - apr_status_t status = apr_threadkey_private_create(&sThreadLocalDataKey, &LLThreadLocalData::destroy, LLAPRRootPool::get()()); - ll_apr_assert_status(status); // Or out of memory, or system-imposed limit on the - // total number of keys per process {PTHREAD_KEYS_MAX} - // has been exceeded. - - // Create the thread-local data for the main thread (this function is called by the main thread). - LLThreadLocalData::create(NULL); -#ifdef SHOW_ASSERT - // This function is called by the main thread. - main_thread_id = apr_os_thread_current(); +LLMutex::~LLMutex() +{ +#if MUTEX_DEBUG + llassert_always(!isLocked()); // better not be locked! #endif + apr_thread_mutex_destroy(mAPRMutexp); + mAPRMutexp = NULL; + if (mIsLocalPool) + { + apr_pool_destroy(mAPRPoolp); + } } -// This is called once for every thread when the thread is destructed. -//static -void LLThreadLocalData::destroy(void* thread_local_data) + +void LLMutex::lock() { - delete static_cast(thread_local_data); + apr_thread_mutex_lock(mAPRMutexp); +#if MUTEX_DEBUG + // Have to have the lock before we can access the debug info + U32 id = LLThread::currentID(); + if (mIsLocked[id] != FALSE) + llerrs << "Already locked in Thread: " << id << llendl; + mIsLocked[id] = TRUE; +#endif } -//static -void LLThreadLocalData::create(LLThread* threadp) +void LLMutex::unlock() { - LLThreadLocalData* new_tld = new LLThreadLocalData; - if (threadp) - { - threadp->mThreadLocalData = new_tld; - } - apr_status_t status = apr_threadkey_private_set(new_tld, sThreadLocalDataKey); - llassert_always(status == APR_SUCCESS); +#if MUTEX_DEBUG + // Access the debug info while we have the lock + U32 id = LLThread::currentID(); + if (mIsLocked[id] != TRUE) + llerrs << "Not locked in Thread: " << id << llendl; + mIsLocked[id] = FALSE; +#endif + apr_thread_mutex_unlock(mAPRMutexp); } -//static -LLThreadLocalData& LLThreadLocalData::tldata(void) +bool LLMutex::isLocked() { - if (!sThreadLocalDataKey) + apr_status_t status = apr_thread_mutex_trylock(mAPRMutexp); + if (APR_STATUS_IS_EBUSY(status)) { - LLThreadLocalData::init(); + return true; + } + else + { + apr_thread_mutex_unlock(mAPRMutexp); + return false; } - - void* data; - apr_status_t status = apr_threadkey_private_get(&data, sThreadLocalDataKey); - llassert_always(status == APR_SUCCESS); - return *static_cast(data); } //============================================================================ -LLCondition::LLCondition(LLAPRPool& parent) : LLMutex(parent) +LLCondition::LLCondition(apr_pool_t *poolp) : + LLMutex(poolp) { - apr_thread_cond_create(&mAPRCondp, mPool()); + // base class (LLMutex) has already ensured that mAPRPoolp is set up. + + apr_thread_cond_create(&mAPRCondp, mAPRPoolp); } @@ -365,7 +396,7 @@ void LLThreadSafeRefCount::initThreadSafeRefCount() { if (!sMutex) { - sMutex = new LLMutex; + sMutex = new LLMutex(0); } } diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index 757832b8ca..f1c6cd75af 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -29,34 +29,12 @@ #include "llapp.h" #include "llapr.h" -#include "llmemory.h" #include "apr_thread_cond.h" -#include "llaprpool.h" - -#ifdef SHOW_ASSERT -extern LL_COMMON_API bool is_main_thread(void); -#endif class LLThread; class LLMutex; class LLCondition; -class LL_COMMON_API LLThreadLocalData -{ -private: - static apr_threadkey_t* sThreadLocalDataKey; - -public: - // Thread-local memory pools. - LLAPRRootPool mRootPool; - LLVolatileAPRPool mVolatileAPRPool; - - static void init(void); - static void destroy(void* thread_local_data); - static void create(LLThread* pthread); - static LLThreadLocalData& tldata(void); -}; - class LL_COMMON_API LLThread { public: @@ -67,7 +45,7 @@ public: QUITTING= 2 // Someone wants this thread to quit } EThreadStatus; - LLThread(std::string const& name); + LLThread(const std::string& name, apr_pool_t *poolp = NULL); virtual ~LLThread(); // Warning! You almost NEVER want to destroy a thread unless it's in the STOPPED state. virtual void shutdown(); // stops the thread @@ -82,7 +60,7 @@ public: // Called from MAIN THREAD. void pause(); void unpause(); - bool isPaused() { return isStopped() || mPaused; } + bool isPaused() { return isStopped() || mPaused == TRUE; } // Cause the thread to wake up and check its condition void wake(); @@ -96,11 +74,11 @@ public: // this kicks off the apr thread void start(void); - // Return thread-local data for the current thread. - static LLThreadLocalData& tldata(void) { return LLThreadLocalData::tldata(); } + apr_pool_t *getAPRPool() { return mAPRPoolp; } + LLVolatileAPRPool* getLocalAPRFilePool() { return mLocalAPRFilePoolp ; } private: - bool mPaused; + BOOL mPaused; // static function passed to APR thread creation routine static void *APR_THREAD_FUNC staticRun(apr_thread_t *apr_threadp, void *datap); @@ -110,10 +88,14 @@ protected: LLCondition* mRunCondition; apr_thread_t *mAPRThreadp; + apr_pool_t *mAPRPoolp; + BOOL mIsLocalPool; EThreadStatus mStatus; - friend void LLThreadLocalData::create(LLThread* threadp); - LLThreadLocalData* mThreadLocalData; + //a local apr_pool for APRFile operations in this thread. If it exists, LLAPRFile::sAPRFilePoolp should not be used. + //Note: this pool is used by APRFile ONLY, do NOT use it for any other purposes. + // otherwise it will cause severe memory leaking!!! --bao + LLVolatileAPRPool *mLocalAPRFilePoolp ; void setQuitting(); @@ -143,80 +125,30 @@ protected: #define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO) -#ifdef MUTEX_DEBUG -// We really shouldn't be using recursive locks. Make sure of that in debug mode. -#define MUTEX_FLAG APR_THREAD_MUTEX_UNNESTED -#else -// Use the fastest platform-optimal lock behavior (can be recursive or non-recursive). -#define MUTEX_FLAG APR_THREAD_MUTEX_DEFAULT -#endif - -class LL_COMMON_API LLMutexBase -{ -public: - void lock() { apr_thread_mutex_lock(mAPRMutexp); } - void unlock() { apr_thread_mutex_unlock(mAPRMutexp); } - // Returns true if lock was obtained successfully. - bool trylock() { return !APR_STATUS_IS_EBUSY(apr_thread_mutex_trylock(mAPRMutexp)); } - - // non-blocking, but does do a lock/unlock so not free - bool isLocked() { bool is_not_locked = trylock(); if (is_not_locked) unlock(); return !is_not_locked; } - -protected: - // mAPRMutexp is initialized and uninitialized in the derived class. - apr_thread_mutex_t* mAPRMutexp; -}; - -class LL_COMMON_API LLMutex : public LLMutexBase +class LL_COMMON_API LLMutex { public: - LLMutex(LLAPRPool& parent = LLThread::tldata().mRootPool) : mPool(parent) - { - apr_thread_mutex_create(&mAPRMutexp, MUTEX_FLAG, mPool()); - } - ~LLMutex() - { - llassert(!isLocked()); // better not be locked! - apr_thread_mutex_destroy(mAPRMutexp); - mAPRMutexp = NULL; - } - + LLMutex(apr_pool_t *apr_poolp); // NULL pool constructs a new pool for the mutex + virtual ~LLMutex(); + + void lock(); // blocks + void unlock(); + bool isLocked(); // non-blocking, but does do a lock/unlock so not free + protected: - LLAPRPool mPool; -}; - -#if APR_HAS_THREADS -// No need to use a root pool in this case. -typedef LLMutex LLMutexRootPool; -#else // APR_HAS_THREADS -class LL_COMMON_API LLMutexRootPool : public LLMutexBase -{ -public: - LLMutexRootPool(void) - { - apr_thread_mutex_create(&mAPRMutexp, MUTEX_FLAG, mRootPool()); - } - ~LLMutexRootPool() - { -#if APR_POOL_DEBUG - // It is allowed to destruct root pools from a different thread. - mRootPool.grab_ownership(); + apr_thread_mutex_t *mAPRMutexp; + apr_pool_t *mAPRPoolp; + BOOL mIsLocalPool; +#if MUTEX_DEBUG + std::map mIsLocked; #endif - llassert(!isLocked()); - apr_thread_mutex_destroy(mAPRMutexp); - mAPRMutexp = NULL; - } - -protected: - LLAPRRootPool mRootPool; }; -#endif // APR_HAS_THREADS // Actually a condition/mutex pair (since each condition needs to be associated with a mutex). class LL_COMMON_API LLCondition : public LLMutex { public: - LLCondition(LLAPRPool& parent = LLThread::tldata().mRootPool); + LLCondition(apr_pool_t *apr_poolp); // Defaults to global pool, could use the thread pool as well. ~LLCondition(); void wait(); // blocks @@ -227,10 +159,10 @@ protected: apr_thread_cond_t *mAPRCondp; }; -class LL_COMMON_API LLMutexLock +class LLMutexLock { public: - LLMutexLock(LLMutexBase* mutex) + LLMutexLock(LLMutex* mutex) { mMutex = mutex; mMutex->lock(); @@ -240,7 +172,7 @@ public: mMutex->unlock(); } private: - LLMutexBase* mMutex; + LLMutex* mMutex; }; //============================================================================ diff --git a/indra/llcommon/llthreadsafequeue.cpp b/indra/llcommon/llthreadsafequeue.cpp index 05d24944f3..8a73e632a9 100644 --- a/indra/llcommon/llthreadsafequeue.cpp +++ b/indra/llcommon/llthreadsafequeue.cpp @@ -34,11 +34,19 @@ //----------------------------------------------------------------------------- -LLThreadSafeQueueImplementation::LLThreadSafeQueueImplementation(unsigned int capacity): +LLThreadSafeQueueImplementation::LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity): + mOwnsPool(pool == 0), + mPool(pool), mQueue(0) { - mPool.create(); - apr_status_t status = apr_queue_create(&mQueue, capacity, mPool()); + if(mOwnsPool) { + apr_status_t status = apr_pool_create(&mPool, 0); + if(status != APR_SUCCESS) throw LLThreadSafeQueueError("failed to allocate pool"); + } else { + ; // No op. + } + + apr_status_t status = apr_queue_create(&mQueue, capacity, mPool); if(status != APR_SUCCESS) throw LLThreadSafeQueueError("failed to allocate queue"); } @@ -51,6 +59,7 @@ LLThreadSafeQueueImplementation::~LLThreadSafeQueueImplementation() " elements;" << "memory will be leaked" << LL_ENDL; apr_queue_term(mQueue); } + if(mOwnsPool && (mPool != 0)) apr_pool_destroy(mPool); } diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h index 43d0b396f2..58cac38769 100644 --- a/indra/llcommon/llthreadsafequeue.h +++ b/indra/llcommon/llthreadsafequeue.h @@ -30,9 +30,9 @@ #include #include -#include "llaprpool.h" +struct apr_pool_t; // From apr_pools.h class LLThreadSafeQueueImplementation; // See below. @@ -75,7 +75,7 @@ struct apr_queue_t; // From apr_queue.h class LL_COMMON_API LLThreadSafeQueueImplementation { public: - LLThreadSafeQueueImplementation(unsigned int capacity); + LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity); ~LLThreadSafeQueueImplementation(); void pushFront(void * element); bool tryPushFront(void * element); @@ -84,7 +84,8 @@ public: size_t size(); private: - LLAPRPool mPool; // The pool used for mQueue. + bool mOwnsPool; + apr_pool_t * mPool; apr_queue_t * mQueue; }; @@ -98,8 +99,9 @@ class LLThreadSafeQueue public: typedef ElementT value_type; - // Constructor. - LLThreadSafeQueue(unsigned int capacity = 1024); + // If the pool is set to NULL one will be allocated and managed by this + // queue. + LLThreadSafeQueue(apr_pool_t * pool = 0, unsigned int capacity = 1024); // Add an element to the front of queue (will block if the queue has // reached capacity). @@ -137,8 +139,8 @@ private: template -LLThreadSafeQueue::LLThreadSafeQueue(unsigned int capacity) : - mImplementation(capacity) +LLThreadSafeQueue::LLThreadSafeQueue(apr_pool_t * pool, unsigned int capacity): + mImplementation(pool, capacity) { ; // No op. } diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp index 6b308bb917..3ac50832fd 100644 --- a/indra/llcommon/llworkerthread.cpp +++ b/indra/llcommon/llworkerthread.cpp @@ -37,7 +37,12 @@ LLWorkerThread::LLWorkerThread(const std::string& name, bool threaded) : LLQueuedThread(name, threaded) { - mDeleteMutex = new LLMutex; + mDeleteMutex = new LLMutex(NULL); + + if(!mLocalAPRFilePoolp) + { + mLocalAPRFilePoolp = new LLVolatileAPRPool() ; + } } LLWorkerThread::~LLWorkerThread() @@ -199,6 +204,7 @@ LLWorkerClass::LLWorkerClass(LLWorkerThread* workerthread, const std::string& na mWorkerClassName(name), mRequestHandle(LLWorkerThread::nullHandle()), mRequestPriority(LLWorkerThread::PRIORITY_NORMAL), + mMutex(NULL), mWorkFlags(0) { if (!mWorkerThread) diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h index bef5ef53fe..9bff18303e 100644 --- a/indra/llcommon/llworkerthread.h +++ b/indra/llcommon/llworkerthread.h @@ -94,6 +94,7 @@ public: private: void deleteWorker(LLWorkerClass* workerclass); // schedule for deletion + }; //============================================================================ @@ -193,7 +194,7 @@ protected: U32 mRequestPriority; // last priority set private: - LLMutexRootPool mMutex; // Use LLMutexRootPool since this object is created and destructed by multiple threads. + LLMutex mMutex; LLAtomicU32 mWorkFlags; }; diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp index 8f7916f565..68e45f36e4 100644 --- a/indra/llcrashlogger/llcrashlogger.cpp +++ b/indra/llcrashlogger/llcrashlogger.cpp @@ -390,7 +390,8 @@ bool LLCrashLogger::init() return false; } - gServicePump = new LLPumpIO; + gServicePump = new LLPumpIO(gAPRPoolp); + gServicePump->prime(gAPRPoolp); LLHTTPClient::setPump(*gServicePump); //If we've opened the crash logger, assume we can delete the marker file if it exists diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index f4399d4ed4..39211bf7fa 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -51,7 +51,7 @@ LLMutex* LLImage::sMutex = NULL; //static void LLImage::initClass() { - sMutex = new LLMutex; + sMutex = new LLMutex(NULL); } //static @@ -1557,7 +1557,8 @@ BOOL LLImageFormatted::load(const std::string &filename) resetLastError(); S32 file_size = 0; - LLAPRFile infile(filename, LL_APR_RB, &file_size); + LLAPRFile infile ; + infile.open(filename, LL_APR_RB, NULL, &file_size); apr_file_t* apr_file = infile.getFileHandle(); if (!apr_file) { @@ -1592,7 +1593,8 @@ BOOL LLImageFormatted::save(const std::string &filename) { resetLastError(); - LLAPRFile outfile(filename, LL_APR_WB); + LLAPRFile outfile ; + outfile.open(filename, LL_APR_WB); if (!outfile.getFileHandle()) { setLastError("Unable to open file for writing", filename); diff --git a/indra/llimage/llimagedimensionsinfo.cpp b/indra/llimage/llimagedimensionsinfo.cpp index 8a10956a5b..835664c60f 100644 --- a/indra/llimage/llimagedimensionsinfo.cpp +++ b/indra/llimage/llimagedimensionsinfo.cpp @@ -40,7 +40,7 @@ bool LLImageDimensionsInfo::load(const std::string& src_filename,U32 codec) mSrcFilename = src_filename; S32 file_size = 0; - apr_status_t s = mInfile.open(src_filename, LL_APR_RB, LLAPRFile::long_lived, &file_size); + apr_status_t s = mInfile.open(src_filename, LL_APR_RB, NULL, &file_size); if (s != APR_SUCCESS) { diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index 5f488a6764..cb2a85fa91 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -358,7 +358,8 @@ BOOL LLImageJ2C::loadAndValidate(const std::string &filename) resetLastError(); S32 file_size = 0; - LLAPRFile infile(filename, LL_APR_RB, &file_size); + LLAPRFile infile ; + infile.open(filename, LL_APR_RB, NULL, &file_size); apr_file_t* apr_file = infile.getFileHandle() ; if (!apr_file) { diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp index 2c6d6f31ea..28dc3bd313 100644 --- a/indra/llimage/llimageworker.cpp +++ b/indra/llimage/llimageworker.cpp @@ -35,18 +35,20 @@ LLImageDecodeThread::LLImageDecodeThread(bool threaded) : LLQueuedThread("imagedecode", threaded) { + mCreationMutex = new LLMutex(getAPRPool()); } //virtual LLImageDecodeThread::~LLImageDecodeThread() { + delete mCreationMutex ; } // MAIN THREAD // virtual S32 LLImageDecodeThread::update(U32 max_time_ms) { - LLMutexLock lock(&mCreationMutex); + LLMutexLock lock(mCreationMutex); for (creation_list_t::iterator iter = mCreationList.begin(); iter != mCreationList.end(); ++iter) { @@ -69,7 +71,7 @@ S32 LLImageDecodeThread::update(U32 max_time_ms) LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image, U32 priority, S32 discard, BOOL needs_aux, Responder* responder) { - LLMutexLock lock(&mCreationMutex); + LLMutexLock lock(mCreationMutex); handle_t handle = generateHandle(); mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder)); return handle; @@ -79,7 +81,7 @@ LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* // Returns the size of the mutex guarded list as an indication of sanity S32 LLImageDecodeThread::tut_size() { - LLMutexLock lock(&mCreationMutex); + LLMutexLock lock(mCreationMutex); S32 res = mCreationList.size(); return res; } diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h index 6a24b7522a..c684222fa5 100644 --- a/indra/llimage/llimageworker.h +++ b/indra/llimage/llimageworker.h @@ -98,7 +98,7 @@ private: }; typedef std::list creation_list_t; creation_list_t mCreationList; - LLMutex mCreationMutex; + LLMutex* mCreationMutex; }; #endif diff --git a/indra/llmath/llvolumemgr.cpp b/indra/llmath/llvolumemgr.cpp index 734440d312..88c195936c 100644 --- a/indra/llmath/llvolumemgr.cpp +++ b/indra/llmath/llvolumemgr.cpp @@ -49,7 +49,7 @@ LLVolumeMgr::LLVolumeMgr() { // the LLMutex magic interferes with easy unit testing, // so you now must manually call useMutex() to use it - //mDataMutex = new LLMutex; + //mDataMutex = new LLMutex(gAPRPoolp); } LLVolumeMgr::~LLVolumeMgr() @@ -216,7 +216,7 @@ void LLVolumeMgr::useMutex() { if (!mDataMutex) { - mDataMutex = new LLMutex; + mDataMutex = new LLMutex(gAPRPoolp); } } diff --git a/indra/llmessage/llares.cpp b/indra/llmessage/llares.cpp index fab9858b69..5a67035ed1 100644 --- a/indra/llmessage/llares.cpp +++ b/indra/llmessage/llares.cpp @@ -28,7 +28,6 @@ #include "linden_common.h" #include "llares.h" -#include "llscopedvolatileaprpool.h" #include #include @@ -465,6 +464,11 @@ void LLAres::search(const std::string &query, LLResType type, bool LLAres::process(U64 timeout) { + if (!gAPRPoolp) + { + ll_init_apr(); + } + ares_socket_t socks[ARES_GETSOCK_MAXNUM]; apr_pollfd_t aprFds[ARES_GETSOCK_MAXNUM]; apr_int32_t nsds = 0; @@ -478,7 +482,10 @@ bool LLAres::process(U64 timeout) return nsds > 0; } - LLScopedVolatileAPRPool scoped_pool; + apr_status_t status; + LLAPRPool pool; + status = pool.getStatus() ; + ll_apr_assert_status(status); for (int i = 0; i < ARES_GETSOCK_MAXNUM; i++) { @@ -495,7 +502,7 @@ bool LLAres::process(U64 timeout) apr_socket_t *aprSock = NULL; - apr_status_t status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], scoped_pool); + status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], pool.getAPRPool()); if (status != APR_SUCCESS) { ll_apr_warn_status(status); @@ -504,7 +511,7 @@ bool LLAres::process(U64 timeout) aprFds[nactive].desc.s = aprSock; aprFds[nactive].desc_type = APR_POLL_SOCKET; - aprFds[nactive].p = scoped_pool; + aprFds[nactive].p = pool.getAPRPool(); aprFds[nactive].rtnevents = 0; aprFds[nactive].client_data = &socks[i]; @@ -513,7 +520,7 @@ bool LLAres::process(U64 timeout) if (nactive > 0) { - apr_status_t status = apr_poll(aprFds, nactive, &nsds, timeout); + status = apr_poll(aprFds, nactive, &nsds, timeout); if (status != APR_SUCCESS && status != APR_TIMEUP) { diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 4d3b382f7a..a485fa0160 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -1039,7 +1039,7 @@ void LLCurl::initClass() S32 mutex_count = CRYPTO_num_locks(); for (S32 i=0; i factory_ptr(factory); - LLIOServerSocket* server = new LLIOServerSocket(socket, factory_ptr); + LLIOServerSocket* server = new LLIOServerSocket(pool, socket, factory_ptr); LLPumpIO::chain_t chain; chain.push_back(LLIOPipe::ptr_t(server)); diff --git a/indra/llmessage/lliohttpserver.h b/indra/llmessage/lliohttpserver.h index 2294e4b8ae..5c1b0531ff 100644 --- a/indra/llmessage/lliohttpserver.h +++ b/indra/llmessage/lliohttpserver.h @@ -50,7 +50,7 @@ class LLIOHTTPServer public: typedef void (*timing_callback_t)(const char* hashed_name, F32 time, void* data); - static LLHTTPNode& create(LLPumpIO& pump, U16 port); + static LLHTTPNode& create(apr_pool_t* pool, LLPumpIO& pump, U16 port); /**< Creates an HTTP wire server on the pump for the given TCP port. * * Returns the root node of the new server. Add LLHTTPNode instances diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp index e802d9b3a6..ca84fa8bb8 100644 --- a/indra/llmessage/lliosocket.cpp +++ b/indra/llmessage/lliosocket.cpp @@ -35,7 +35,6 @@ #include "llhost.h" #include "llmemtype.h" #include "llpumpio.h" -#include "llthread.h" // // constants @@ -99,31 +98,51 @@ void ll_debug_socket(const char* msg, apr_socket_t* apr_sock) /// // static -LLSocket::ptr_t LLSocket::create(EType type, U16 port) +LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port) { LLMemType m1(LLMemType::MTYPE_IO_TCP); + LLSocket::ptr_t rv; + apr_socket_t* socket = NULL; + apr_pool_t* new_pool = NULL; apr_status_t status = APR_EGENERAL; - LLSocket::ptr_t rv(new LLSocket); + + // create a pool for the socket + status = apr_pool_create(&new_pool, pool); + if(ll_apr_warn_status(status)) + { + if(new_pool) apr_pool_destroy(new_pool); + return rv; + } if(STREAM_TCP == type) { - status = apr_socket_create(&rv->mSocket, APR_INET, SOCK_STREAM, APR_PROTO_TCP, rv->mPool()); + status = apr_socket_create( + &socket, + APR_INET, + SOCK_STREAM, + APR_PROTO_TCP, + new_pool); } else if(DATAGRAM_UDP == type) { - status = apr_socket_create(&rv->mSocket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, rv->mPool()); + status = apr_socket_create( + &socket, + APR_INET, + SOCK_DGRAM, + APR_PROTO_UDP, + new_pool); } else { - rv.reset(); + if(new_pool) apr_pool_destroy(new_pool); return rv; } if(ll_apr_warn_status(status)) { - rv->mSocket = NULL; - rv.reset(); + if(new_pool) apr_pool_destroy(new_pool); return rv; } + rv = ptr_t(new LLSocket(socket, new_pool)); if(port > 0) { apr_sockaddr_t* sa = NULL; @@ -133,7 +152,7 @@ LLSocket::ptr_t LLSocket::create(EType type, U16 port) APR_UNSPEC, port, 0, - rv->mPool()); + new_pool); if(ll_apr_warn_status(status)) { rv.reset(); @@ -141,8 +160,8 @@ LLSocket::ptr_t LLSocket::create(EType type, U16 port) } // This allows us to reuse the address on quick down/up. This // is unlikely to create problems. - ll_apr_warn_status(apr_socket_opt_set(rv->mSocket, APR_SO_REUSEADDR, 1)); - status = apr_socket_bind(rv->mSocket, sa); + ll_apr_warn_status(apr_socket_opt_set(socket, APR_SO_REUSEADDR, 1)); + status = apr_socket_bind(socket, sa); if(ll_apr_warn_status(status)) { rv.reset(); @@ -156,7 +175,7 @@ LLSocket::ptr_t LLSocket::create(EType type, U16 port) // to keep a queue of incoming connections for ACCEPT. lldebugs << "Setting listen state for socket." << llendl; status = apr_socket_listen( - rv->mSocket, + socket, LL_DEFAULT_LISTEN_BACKLOG); if(ll_apr_warn_status(status)) { @@ -177,28 +196,21 @@ LLSocket::ptr_t LLSocket::create(EType type, U16 port) } // static -LLSocket::ptr_t LLSocket::create(apr_status_t& status, LLSocket::ptr_t& listen_socket) +LLSocket::ptr_t LLSocket::create(apr_socket_t* socket, apr_pool_t* pool) { LLMemType m1(LLMemType::MTYPE_IO_TCP); - if (!listen_socket->getSocket()) - { - status = APR_ENOSOCKET; - return LLSocket::ptr_t(); - } - LLSocket::ptr_t rv(new LLSocket); - lldebugs << "accepting socket" << llendl; - status = apr_socket_accept(&rv->mSocket, listen_socket->getSocket(), rv->mPool()); - if (status != APR_SUCCESS) + LLSocket::ptr_t rv; + if(!socket) { - rv->mSocket = NULL; - rv.reset(); return rv; } + rv = ptr_t(new LLSocket(socket, pool)); rv->mPort = PORT_EPHEMERAL; rv->setOptions(); return rv; } + bool LLSocket::blockingConnect(const LLHost& host) { if(!mSocket) return false; @@ -211,7 +223,7 @@ bool LLSocket::blockingConnect(const LLHost& host) APR_UNSPEC, host.getPort(), 0, - mPool()))) + mPool))) { return false; } @@ -222,11 +234,13 @@ bool LLSocket::blockingConnect(const LLHost& host) return true; } -LLSocket::LLSocket() : - mSocket(NULL), - mPool(LLThread::tldata().mRootPool), +LLSocket::LLSocket(apr_socket_t* socket, apr_pool_t* pool) : + mSocket(socket), + mPool(pool), mPort(PORT_INVALID) { + ll_debug_socket("Constructing wholely formed socket", mSocket); + LLMemType m1(LLMemType::MTYPE_IO_TCP); } LLSocket::~LLSocket() @@ -238,6 +252,10 @@ LLSocket::~LLSocket() ll_debug_socket("Destroying socket", mSocket); apr_socket_close(mSocket); } + if(mPool) + { + apr_pool_destroy(mPool); + } } void LLSocket::setOptions() @@ -498,8 +516,10 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl( /// LLIOServerSocket::LLIOServerSocket( + apr_pool_t* pool, LLIOServerSocket::socket_t listener, factory_t factory) : + mPool(pool), mListenSocket(listener), mReactor(factory), mInitialized(false), @@ -559,15 +579,21 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl( lldebugs << "accepting socket" << llendl; PUMP_DEBUG; - apr_status_t status; - LLSocket::ptr_t llsocket(LLSocket::create(status, mListenSocket)); + apr_pool_t* new_pool = NULL; + apr_status_t status = apr_pool_create(&new_pool, mPool); + apr_socket_t* socket = NULL; + status = apr_socket_accept( + &socket, + mListenSocket->getSocket(), + new_pool); + LLSocket::ptr_t llsocket(LLSocket::create(socket, new_pool)); //EStatus rv = STATUS_ERROR; - if(llsocket && status == APR_SUCCESS) + if(llsocket) { PUMP_DEBUG; apr_sockaddr_t* remote_addr; - apr_socket_addr_get(&remote_addr, APR_REMOTE, llsocket->getSocket()); + apr_socket_addr_get(&remote_addr, APR_REMOTE, socket); char* remote_host_string; apr_sockaddr_ip_get(&remote_host_string, remote_addr); @@ -582,6 +608,7 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl( { chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(llsocket))); pump->addChain(chain, mResponseTimeout); + status = STATUS_OK; } else { @@ -590,8 +617,7 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl( } else { - char buf[256]; - llwarns << "Unable to accept linden socket: " << apr_strerror(status, buf, sizeof(buf)) << llendl; + llwarns << "Unable to create linden socket." << llendl; } PUMP_DEBUG; @@ -604,10 +630,11 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl( #if 0 LLIODataSocket::LLIODataSocket( U16 suggested_port, - U16 start_discovery_port) : + U16 start_discovery_port, + apr_pool_t* pool) : mSocket(NULL) { - if(PORT_INVALID == suggested_port) return; + if(!pool || (PORT_INVALID == suggested_port)) return; if(ll_apr_warn_status(apr_socket_create(&mSocket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, pool))) return; apr_sockaddr_t* sa = NULL; if(ll_apr_warn_status(apr_sockaddr_info_get(&sa, APR_ANYADDR, APR_UNSPEC, suggested_port, 0, pool))) return; diff --git a/indra/llmessage/lliosocket.h b/indra/llmessage/lliosocket.h index 1e35225512..6806e5084a 100644 --- a/indra/llmessage/lliosocket.h +++ b/indra/llmessage/lliosocket.h @@ -38,6 +38,7 @@ */ #include "lliopipe.h" +#include "apr_pools.h" #include "apr_network_io.h" #include "llchainio.h" @@ -87,22 +88,34 @@ public: * socket. If you intend the socket to be known to external * clients without prior port notification, do not use * PORT_EPHEMERAL. + * @param pool The apr pool to use. A child pool will be created + * and associated with the socket. * @param type The type of socket to create * @param port The port for the socket * @return A valid socket shared pointer if the call worked. */ static ptr_t create( + apr_pool_t* pool, EType type, U16 port = PORT_EPHEMERAL); /** - * @brief Create a LLSocket by accepting a connection from a listen socket. + * @brief Create a LLSocket when you already have an apr socket. * - * @param status Output. Status of the accept if a valid listen socket was passed. - * @param listen_socket The listen socket to use. + * This method assumes an ephemeral port. This is typically used + * by calls which spawn a socket such as a call to + * accept() as in the server socket. This call should + * not fail if you have a valid apr socket. + * Because of the nature of how accept() works, you are expected + * to create a new pool for the socket, use that pool for the + * accept, and pass it in here where it will be bound with the + * socket and destroyed at the same time. + * @param socket The apr socket to use + * @param pool The pool used to create the socket. *NOTE: The pool + * passed in will be DESTROYED. * @return A valid socket shared pointer if the call worked. */ - static ptr_t create(apr_status_t& status, ptr_t& listen_socket); + static ptr_t create(apr_socket_t* socket, apr_pool_t* pool); /** * @brief Perform a blocking connect to a host. Do not use in production. @@ -137,7 +150,7 @@ protected: * @brief Protected constructor since should only make sockets * with one of the two create() calls. */ - LLSocket(void); + LLSocket(apr_socket_t* socket, apr_pool_t* pool); /** * @brief Set default socket options. @@ -154,8 +167,8 @@ protected: // The apr socket. apr_socket_t* mSocket; - // Our memory pool. - LLAPRPool mPool; + // our memory pool + apr_pool_t* mPool; // The port if we know it. U16 mPort; @@ -280,7 +293,7 @@ class LLIOServerSocket : public LLIOPipe public: typedef LLSocket::ptr_t socket_t; typedef boost::shared_ptr factory_t; - LLIOServerSocket(socket_t listener, factory_t reactor); + LLIOServerSocket(apr_pool_t* pool, socket_t listener, factory_t reactor); virtual ~LLIOServerSocket(); /** @@ -312,6 +325,7 @@ protected: //@} protected: + apr_pool_t* mPool; socket_t mListenSocket; factory_t mReactor; bool mInitialized; @@ -345,7 +359,8 @@ public: */ LLIODataSocket( U16 suggested_port, - U16 start_discovery_port); + U16 start_discovery_port, + apr_pool_t* pool); virtual ~LLIODataSocket(); protected: diff --git a/indra/llmessage/llmail.cpp b/indra/llmessage/llmail.cpp index 8a898ab1b0..08b31e9c7a 100644 --- a/indra/llmessage/llmail.cpp +++ b/indra/llmessage/llmail.cpp @@ -50,7 +50,6 @@ #include "llstring.h" #include "lluuid.h" #include "net.h" -#include "llaprpool.h" // // constants @@ -58,7 +57,7 @@ const size_t LL_MAX_KNOWN_GOOD_MAIL_SIZE = 4096; static bool gMailEnabled = true; -static LLAPRPool gMailPool; +static apr_pool_t* gMailPool; static apr_sockaddr_t* gSockAddr; static apr_socket_t* gMailSocket; @@ -83,7 +82,7 @@ bool connect_smtp() gSockAddr->sa.sin.sin_family, SOCK_STREAM, APR_PROTO_TCP, - gMailPool()); + gMailPool); if(ll_apr_warn_status(status)) return false; status = apr_socket_connect(gMailSocket, gSockAddr); if(ll_apr_warn_status(status)) @@ -140,19 +139,19 @@ BOOL LLMail::send( } // static -void LLMail::init(const std::string& hostname) +void LLMail::init(const std::string& hostname, apr_pool_t* pool) { gMailSocket = NULL; - if (hostname.empty()) + if(hostname.empty() || !pool) { + gMailPool = NULL; gSockAddr = NULL; - gMailPool.destroy(); } else { - gMailPool.create(); + gMailPool = pool; - // Collect all the information into a sockaddr structure. the + // collect all the information into a socaddr sturcture. the // documentation is a bit unclear, but I either have to // specify APR_UNSPEC or not specify any flags. I am not sure // which option is better. @@ -162,7 +161,7 @@ void LLMail::init(const std::string& hostname) APR_UNSPEC, 25, APR_IPV4_ADDR_OK, - gMailPool()); + gMailPool); ll_apr_warn_status(status); } } diff --git a/indra/llmessage/llmail.h b/indra/llmessage/llmail.h index 0a5c532088..3791714363 100644 --- a/indra/llmessage/llmail.h +++ b/indra/llmessage/llmail.h @@ -27,13 +27,15 @@ #ifndef LL_LLMAIL_H #define LL_LLMAIL_H +typedef struct apr_pool_t apr_pool_t; + #include "llsd.h" class LLMail { public: // if hostname is NULL, then the host is resolved as 'mail' - static void init(const std::string& hostname); + static void init(const std::string& hostname, apr_pool_t* pool); // Allow all email transmission to be disabled/enabled. static void enable(bool mail_enabled); diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp index 89cfd66e1b..a8d2a0a224 100644 --- a/indra/llmessage/llpumpio.cpp +++ b/indra/llmessage/llpumpio.cpp @@ -37,7 +37,6 @@ #include "llmemtype.h" #include "llstl.h" #include "llstat.h" -#include "llthread.h" // These should not be enabled in production, but they can be // intensely useful during development for finding certain kinds of @@ -163,12 +162,14 @@ struct ll_delete_apr_pollset_fd_client_data /** * LLPumpIO */ -LLPumpIO::LLPumpIO(void) : +LLPumpIO::LLPumpIO(apr_pool_t* pool) : mState(LLPumpIO::NORMAL), mRebuildPollset(false), mPollset(NULL), mPollsetClientID(0), mNextLock(0), + mPool(NULL), + mCurrentPool(NULL), mCurrentPoolReallocCount(0), mChainsMutex(NULL), mCallbackMutex(NULL), @@ -177,24 +178,21 @@ LLPumpIO::LLPumpIO(void) : mCurrentChain = mRunningChains.end(); LLMemType m1(LLMemType::MTYPE_IO_PUMP); - initialize(); + initialize(pool); } LLPumpIO::~LLPumpIO() { LLMemType m1(LLMemType::MTYPE_IO_PUMP); -#if LL_THREADS_APR - if (mChainsMutex) apr_thread_mutex_destroy(mChainsMutex); - if (mCallbackMutex) apr_thread_mutex_destroy(mCallbackMutex); -#endif - mChainsMutex = NULL; - mCallbackMutex = NULL; - if(mPollset) - { -// lldebugs << "cleaning up pollset" << llendl; - apr_pollset_destroy(mPollset); - mPollset = NULL; - } + cleanup(); +} + +bool LLPumpIO::prime(apr_pool_t* pool) +{ + LLMemType m1(LLMemType::MTYPE_IO_PUMP); + cleanup(); + initialize(pool); + return ((pool == NULL) ? false : true); } bool LLPumpIO::addChain(const chain_t& chain, F32 timeout) @@ -354,7 +352,8 @@ bool LLPumpIO::setConditional(LLIOPipe* pipe, const apr_pollfd_t* poll) { // each fd needs a pool to work with, so if one was // not specified, use this pool. - value.second.p = (*mCurrentChain).mDescriptorsPool->operator()(); + // *FIX: Should it always be this pool? + value.second.p = mPool; } value.second.client_data = new S32(++mPollsetClientID); (*mCurrentChain).mDescriptors.push_back(value); @@ -826,15 +825,39 @@ void LLPumpIO::control(LLPumpIO::EControl op) } } -void LLPumpIO::initialize(void) +void LLPumpIO::initialize(apr_pool_t* pool) { LLMemType m1(LLMemType::MTYPE_IO_PUMP); - mPool.create(); + if(!pool) return; #if LL_THREADS_APR // SJB: Windows defaults to NESTED and OSX defaults to UNNESTED, so use UNNESTED explicitly. - apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, mPool()); - apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, mPool()); + apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, pool); + apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, pool); +#endif + mPool = pool; +} + +void LLPumpIO::cleanup() +{ + LLMemType m1(LLMemType::MTYPE_IO_PUMP); +#if LL_THREADS_APR + if(mChainsMutex) apr_thread_mutex_destroy(mChainsMutex); + if(mCallbackMutex) apr_thread_mutex_destroy(mCallbackMutex); #endif + mChainsMutex = NULL; + mCallbackMutex = NULL; + if(mPollset) + { +// lldebugs << "cleaning up pollset" << llendl; + apr_pollset_destroy(mPollset); + mPollset = NULL; + } + if(mCurrentPool) + { + apr_pool_destroy(mCurrentPool); + mCurrentPool = NULL; + } + mPool = NULL; } void LLPumpIO::rebuildPollset() @@ -862,19 +885,21 @@ void LLPumpIO::rebuildPollset() if(mCurrentPool && (0 == (++mCurrentPoolReallocCount % POLLSET_POOL_RECYCLE_COUNT))) { - mCurrentPool.destroy(); + apr_pool_destroy(mCurrentPool); + mCurrentPool = NULL; mCurrentPoolReallocCount = 0; } if(!mCurrentPool) { - mCurrentPool.create(mPool); + apr_status_t status = apr_pool_create(&mCurrentPool, mPool); + (void)ll_apr_warn_status(status); } // add all of the file descriptors run_it = mRunningChains.begin(); LLChainInfo::conditionals_t::iterator fd_it; LLChainInfo::conditionals_t::iterator fd_end; - apr_pollset_create(&mPollset, size, mCurrentPool(), 0); + apr_pollset_create(&mPollset, size, mCurrentPool, 0); for(; run_it != run_end; ++run_it) { fd_it = (*run_it).mDescriptors.begin(); @@ -1132,8 +1157,7 @@ bool LLPumpIO::handleChainError( LLPumpIO::LLChainInfo::LLChainInfo() : mInit(false), mLock(0), - mEOS(false), - mDescriptorsPool(new LLAPRPool(LLThread::tldata().mRootPool)) + mEOS(false) { LLMemType m1(LLMemType::MTYPE_IO_PUMP); mTimer.setTimerExpirySec(DEFAULT_CHAIN_EXPIRY_SECS); diff --git a/indra/llmessage/llpumpio.h b/indra/llmessage/llpumpio.h index 75c35ae7ab..9303c9d7fc 100644 --- a/indra/llmessage/llpumpio.h +++ b/indra/llmessage/llpumpio.h @@ -30,12 +30,11 @@ #define LL_LLPUMPIO_H #include -#include #if LL_LINUX // needed for PATH_MAX in APR. #include #endif -#include "llaprpool.h" +#include "apr_pools.h" #include "llbuffer.h" #include "llframetimer.h" #include "lliopipe.h" @@ -59,8 +58,9 @@ extern const F32 NEVER_CHAIN_EXPIRY_SECS; * pump() on a thread used for IO and call * respond() on a thread that is expected to do higher * level processing. You can call almost any other method from any - * thread - see notes for each method for details. - * + * thread - see notes for each method for details. In order for the + * threading abstraction to work, you need to call prime() + * with a valid apr pool. * A pump instance manages much of the state for the pipe, including * the list of pipes in the chain, the channel for each element in the * chain, the buffer, and if any pipe has marked the stream or process @@ -79,13 +79,24 @@ public: /** * @brief Constructor. */ - LLPumpIO(void); + LLPumpIO(apr_pool_t* pool); /** * @brief Destructor. */ ~LLPumpIO(); + /** + * @brief Prepare this pump for usage. + * + * If you fail to call this method prior to use, the pump will + * try to work, but will not come with any thread locking + * mechanisms. + * @param pool The apr pool to use. + * @return Returns true if the pump is primed. + */ + bool prime(apr_pool_t* pool); + /** * @brief Typedef for having a chain of pipes. */ @@ -357,7 +368,6 @@ protected: typedef std::pair pipe_conditional_t; typedef std::vector conditionals_t; conditionals_t mDescriptors; - boost::shared_ptr mDescriptorsPool; }; // All the running chains & info @@ -376,9 +386,9 @@ protected: callbacks_t mPendingCallbacks; callbacks_t mCallbacks; - // Memory pool for pollsets & mutexes. - LLAPRPool mPool; - LLAPRPool mCurrentPool; + // memory allocator for pollsets & mutexes. + apr_pool_t* mPool; + apr_pool_t* mCurrentPool; S32 mCurrentPoolReallocCount; #if LL_THREADS_APR @@ -390,7 +400,8 @@ protected: #endif protected: - void initialize(); + void initialize(apr_pool_t* pool); + void cleanup(); /** * @brief Given the internal state of the chains, rebuild the pollset diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index 83b6f7cf71..cb9d1c3731 100644 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -40,7 +40,6 @@ #include "llstring.h" #include "apr_env.h" #include "llapr.h" -#include "llscopedvolatileaprpool.h" static const U32 HTTP_STATUS_PIPE_ERROR = 499; /** @@ -211,31 +210,27 @@ void LLURLRequest::setCallback(LLURLRequestComplete* callback) // is called with use_proxy = FALSE void LLURLRequest::useProxy(bool use_proxy) { - static std::string env_proxy; + static char *env_proxy; - if (use_proxy && env_proxy.empty()) + if (use_proxy && (env_proxy == NULL)) { - char* env_proxy_str; - LLScopedVolatileAPRPool scoped_pool; - apr_status_t status = apr_env_get(&env_proxy_str, "ALL_PROXY", scoped_pool); + apr_status_t status; + LLAPRPool pool; + status = apr_env_get(&env_proxy, "ALL_PROXY", pool.getAPRPool()); if (status != APR_SUCCESS) { - status = apr_env_get(&env_proxy_str, "http_proxy", scoped_pool); + status = apr_env_get(&env_proxy, "http_proxy", pool.getAPRPool()); } if (status != APR_SUCCESS) { - use_proxy = false; + use_proxy = FALSE; } - else - { - // env_proxy_str is stored in the scoped_pool, so we have to make a copy. - env_proxy = env_proxy_str; - } } - lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = \"" << env_proxy << "\"" << llendl; - if (use_proxy) + lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (env_proxy ? env_proxy : "(null)") << llendl; + + if (env_proxy && use_proxy) { mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, env_proxy); } diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index 302cfc7ca2..2f0d815be5 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -97,10 +97,8 @@ std::string get_shared_secret(); class LLMessagePollInfo { public: - LLMessagePollInfo(void) : mPool(LLThread::tldata().mRootPool) { } apr_socket_t *mAPRSocketp; apr_pollfd_t mPollFD; - LLAPRPool mPool; }; namespace @@ -289,13 +287,20 @@ LLMessageSystem::LLMessageSystem(const std::string& filename, U32 port, } // LL_DEBUGS("Messaging") << << "*** port: " << mPort << llendl; - mPollInfop = new LLMessagePollInfo; - + // + // Create the data structure that we can poll on + // + if (!gAPRPoolp) + { + LL_ERRS("Messaging") << "No APR pool before message system initialization!" << llendl; + ll_init_apr(); + } apr_socket_t *aprSocketp = NULL; - apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, mPollInfop->mPool()); + apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, gAPRPoolp); + mPollInfop = new LLMessagePollInfo; mPollInfop->mAPRSocketp = aprSocketp; - mPollInfop->mPollFD.p = mPollInfop->mPool(); + mPollInfop->mPollFD.p = gAPRPoolp; mPollInfop->mPollFD.desc_type = APR_POLL_SOCKET; mPollInfop->mPollFD.reqevents = APR_POLLIN; mPollInfop->mPollFD.rtnevents = 0; diff --git a/indra/llmessage/tests/networkio.h b/indra/llmessage/tests/networkio.h index 23e1c791f4..2aff90ca1e 100644 --- a/indra/llmessage/tests/networkio.h +++ b/indra/llmessage/tests/networkio.h @@ -30,6 +30,7 @@ #define LL_NETWORKIO_H #include "llmemory.h" // LLSingleton +#include "llapr.h" #include "llares.h" #include "llpumpio.h" #include "llhttpclient.h" @@ -47,8 +48,14 @@ public: mServicePump(NULL), mDone(false) { + ll_init_apr(); + if (! gAPRPoolp) + { + throw std::runtime_error("Can't initialize APR"); + } + // Create IO Pump to use for HTTP Requests. - mServicePump = new LLPumpIO; + mServicePump = new LLPumpIO(gAPRPoolp); LLHTTPClient::setPump(*mServicePump); if (ll_init_ares() == NULL || !gAres->isInitialized()) { diff --git a/indra/llplugin/llplugininstance.cpp b/indra/llplugin/llplugininstance.cpp index 9c9909a017..c326961db4 100644 --- a/indra/llplugin/llplugininstance.cpp +++ b/indra/llplugin/llplugininstance.cpp @@ -29,7 +29,8 @@ #include "linden_common.h" #include "llplugininstance.h" -#include "llthread.h" // Needed for LLThread::tldata().mRootPool + +#include "llapr.h" /** Virtual destructor. */ LLPluginInstanceMessageListener::~LLPluginInstanceMessageListener() @@ -47,7 +48,6 @@ const char *LLPluginInstance::PLUGIN_INIT_FUNCTION_NAME = "LLPluginInitEntryPoin * @param[in] owner Plugin instance. TODO:DOC is this a good description of what "owner" is? */ LLPluginInstance::LLPluginInstance(LLPluginInstanceMessageListener *owner) : - mDSOHandlePool(LLThread::tldata().mRootPool), mDSOHandle(NULL), mPluginUserData(NULL), mPluginSendMessageFunction(NULL) @@ -79,7 +79,7 @@ int LLPluginInstance::load(std::string &plugin_file) int result = apr_dso_load(&mDSOHandle, plugin_file.c_str(), - mDSOHandlePool()); + gAPRPoolp); if(result != APR_SUCCESS) { char buf[1024]; diff --git a/indra/llplugin/llplugininstance.h b/indra/llplugin/llplugininstance.h index 1c3898e2e7..50531ca77f 100644 --- a/indra/llplugin/llplugininstance.h +++ b/indra/llplugin/llplugininstance.h @@ -30,7 +30,6 @@ #include "llstring.h" #include "llapr.h" -#include "llaprpool.h" #include "apr_dso.h" @@ -89,7 +88,6 @@ private: static void staticReceiveMessage(const char *message_string, void **user_data); void receiveMessage(const char *message_string); - LLAPRPool mDSOHandlePool; apr_dso_handle_t *mDSOHandle; void *mPluginUserData; diff --git a/indra/llplugin/llpluginmessagepipe.cpp b/indra/llplugin/llpluginmessagepipe.cpp index dd47300b9c..8d13e38ad5 100644 --- a/indra/llplugin/llpluginmessagepipe.cpp +++ b/indra/llplugin/llpluginmessagepipe.cpp @@ -92,6 +92,8 @@ void LLPluginMessagePipeOwner::killMessagePipe(void) } LLPluginMessagePipe::LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket): + mInputMutex(gAPRPoolp), + mOutputMutex(gAPRPoolp), mOwner(owner), mSocket(socket) { diff --git a/indra/llplugin/llpluginprocesschild.cpp b/indra/llplugin/llpluginprocesschild.cpp index 2fa5dcdd01..45a86476ac 100644 --- a/indra/llplugin/llpluginprocesschild.cpp +++ b/indra/llplugin/llpluginprocesschild.cpp @@ -40,7 +40,7 @@ LLPluginProcessChild::LLPluginProcessChild() { mState = STATE_UNINITIALIZED; mInstance = NULL; - mSocket = LLSocket::create(LLSocket::STREAM_TCP); + mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); mSleepTime = PLUGIN_IDLE_SECONDS; // default: send idle messages at 100Hz mCPUElapsed = 0.0f; mBlockingRequest = false; diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index eaf7ec4bf3..c002de0462 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -33,7 +33,6 @@ #include "llpluginmessageclasses.h" #include "llapr.h" -#include "llscopedvolatileaprpool.h" //virtual LLPluginProcessParentOwner::~LLPluginProcessParentOwner() @@ -43,7 +42,6 @@ LLPluginProcessParentOwner::~LLPluginProcessParentOwner() bool LLPluginProcessParent::sUseReadThread = false; apr_pollset_t *LLPluginProcessParent::sPollSet = NULL; -LLAPRPool LLPluginProcessParent::sPollSetPool; bool LLPluginProcessParent::sPollsetNeedsRebuild = false; LLMutex *LLPluginProcessParent::sInstancesMutex; std::list LLPluginProcessParent::sInstances; @@ -54,7 +52,7 @@ class LLPluginProcessParentPollThread: public LLThread { public: LLPluginProcessParentPollThread() : - LLThread("LLPluginProcessParentPollThread") + LLThread("LLPluginProcessParentPollThread", gAPRPoolp) { } protected: @@ -79,11 +77,12 @@ protected: }; -LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner* owner) +LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner): + mIncomingQueueMutex(gAPRPoolp) { if(!sInstancesMutex) { - sInstancesMutex = new LLMutex; + sInstancesMutex = new LLMutex(gAPRPoolp); } mOwner = owner; @@ -96,7 +95,6 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner* owner) mBlocked = false; mPolledInput = false; mPollFD.client_data = NULL; - mPollFDPool.create(); mPluginLaunchTimeout = 60.0f; mPluginLockupTimeout = 15.0f; @@ -171,28 +169,44 @@ void LLPluginProcessParent::init(const std::string &launcher_filename, const std bool LLPluginProcessParent::accept() { bool result = false; + apr_status_t status = APR_EGENERAL; + apr_socket_t *new_socket = NULL; + + status = apr_socket_accept( + &new_socket, + mListenSocket->getSocket(), + gAPRPoolp); - mSocket = LLSocket::create(status, mListenSocket); if(status == APR_SUCCESS) { // llinfos << "SUCCESS" << llendl; // Success. Create a message pipe on the new socket + + // we MUST create a new pool for the LLSocket, since it will take ownership of it and delete it in its destructor! + apr_pool_t* new_pool = NULL; + status = apr_pool_create(&new_pool, gAPRPoolp); + + mSocket = LLSocket::create(new_socket, new_pool); new LLPluginMessagePipe(this, mSocket); result = true; } + else if(APR_STATUS_IS_EAGAIN(status)) + { +// llinfos << "EAGAIN" << llendl; + + // No incoming connections. This is not an error. + status = APR_SUCCESS; + } else { - mSocket.reset(); - // EAGAIN means "No incoming connections". This is not an error. - if (!APR_STATUS_IS_EAGAIN(status)) - { - // Some other error. - ll_apr_warn_status(status); - errorState(); - } +// llinfos << "Error:" << llendl; + ll_apr_warn_status(status); + + // Some other error. + errorState(); } return result; @@ -258,10 +272,10 @@ void LLPluginProcessParent::idle(void) case STATE_INITIALIZED: { + apr_status_t status = APR_SUCCESS; - LLScopedVolatileAPRPool addr_pool; apr_sockaddr_t* addr = NULL; - mListenSocket = LLSocket::create(LLSocket::STREAM_TCP); + mListenSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); mBoundPort = 0; // This code is based on parts of LLSocket::create() in lliosocket.cpp. @@ -272,7 +286,7 @@ void LLPluginProcessParent::idle(void) APR_INET, 0, // port 0 = ephemeral ("find me a port") 0, - addr_pool); + gAPRPoolp); if(ll_apr_warn_status(status)) { @@ -584,7 +598,7 @@ void LLPluginProcessParent::setMessagePipe(LLPluginMessagePipe *message_pipe) if(message_pipe != NULL) { // Set up the apr_pollfd_t - mPollFD.p = mPollFDPool(); + mPollFD.p = gAPRPoolp; mPollFD.desc_type = APR_POLL_SOCKET; mPollFD.reqevents = APR_POLLIN|APR_POLLERR|APR_POLLHUP; mPollFD.rtnevents = 0; @@ -631,7 +645,6 @@ void LLPluginProcessParent::updatePollset() // delete the existing pollset. apr_pollset_destroy(sPollSet); sPollSet = NULL; - sPollSetPool.destroy(); } std::list::iterator iter; @@ -654,14 +667,12 @@ void LLPluginProcessParent::updatePollset() { #ifdef APR_POLLSET_NOCOPY // The pollset doesn't exist yet. Create it now. - sPollSetPool.create(); - apr_status_t status = apr_pollset_create(&sPollSet, count, sPollSetPool(), APR_POLLSET_NOCOPY); + apr_status_t status = apr_pollset_create(&sPollSet, count, gAPRPoolp, APR_POLLSET_NOCOPY); if(status != APR_SUCCESS) { #endif // APR_POLLSET_NOCOPY LL_WARNS("PluginPoll") << "Couldn't create pollset. Falling back to non-pollset mode." << LL_ENDL; sPollSet = NULL; - sPollSetPool.destroy(); #ifdef APR_POLLSET_NOCOPY } else diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h index 6beeb64c7e..32394809ef 100644 --- a/indra/llplugin/llpluginprocessparent.h +++ b/indra/llplugin/llpluginprocessparent.h @@ -176,9 +176,7 @@ private: static bool sUseReadThread; apr_pollfd_t mPollFD; - LLAPRPool mPollFDPool; static apr_pollset_t *sPollSet; - static LLAPRPool sPollSetPool; static bool sPollsetNeedsRebuild; static LLMutex *sInstancesMutex; static std::list sInstances; diff --git a/indra/llplugin/llpluginsharedmemory.cpp b/indra/llplugin/llpluginsharedmemory.cpp index e2ff645a9c..63ff5085c6 100644 --- a/indra/llplugin/llpluginsharedmemory.cpp +++ b/indra/llplugin/llpluginsharedmemory.cpp @@ -187,8 +187,7 @@ bool LLPluginSharedMemory::create(size_t size) mName += createName(); mSize = size; - mPool.create(); - apr_status_t status = apr_shm_create( &(mImpl->mAprSharedMemory), mSize, mName.c_str(), mPool()); + apr_status_t status = apr_shm_create( &(mImpl->mAprSharedMemory), mSize, mName.c_str(), gAPRPoolp ); if(ll_apr_warn_status(status)) { @@ -211,7 +210,7 @@ bool LLPluginSharedMemory::destroy(void) } mImpl->mAprSharedMemory = NULL; } - mPool.destroy(); + return true; } @@ -220,8 +219,7 @@ bool LLPluginSharedMemory::attach(const std::string &name, size_t size) mName = name; mSize = size; - mPool.create(); - apr_status_t status = apr_shm_attach( &(mImpl->mAprSharedMemory), mName.c_str(), mPool() ); + apr_status_t status = apr_shm_attach( &(mImpl->mAprSharedMemory), mName.c_str(), gAPRPoolp ); if(ll_apr_warn_status(status)) { @@ -243,7 +241,6 @@ bool LLPluginSharedMemory::detach(void) } mImpl->mAprSharedMemory = NULL; } - mPool.destroy(); return true; } diff --git a/indra/llplugin/llpluginsharedmemory.h b/indra/llplugin/llpluginsharedmemory.h index 84b7a58c32..c6cd49cabb 100644 --- a/indra/llplugin/llpluginsharedmemory.h +++ b/indra/llplugin/llpluginsharedmemory.h @@ -28,8 +28,6 @@ #ifndef LL_LLPLUGINSHAREDMEMORY_H #define LL_LLPLUGINSHAREDMEMORY_H -#include "llaprpool.h" - class LLPluginSharedMemoryPlatformImpl; /** @@ -110,7 +108,6 @@ private: bool close(void); bool unlink(void); - LLAPRPool mPool; std::string mName; size_t mSize; void *mMappedAddress; diff --git a/indra/llplugin/slplugin/slplugin.cpp b/indra/llplugin/slplugin/slplugin.cpp index ff86e4e135..516a58db88 100644 --- a/indra/llplugin/slplugin/slplugin.cpp +++ b/indra/llplugin/slplugin/slplugin.cpp @@ -176,6 +176,8 @@ int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdL int main(int argc, char **argv) #endif { + ll_init_apr(); + // Set up llerror logging { LLError::initForApplication("."); @@ -391,6 +393,8 @@ int main(int argc, char **argv) delete plugin; + ll_cleanup_apr(); + return 0; } diff --git a/indra/llvfs/lllfsthread.cpp b/indra/llvfs/lllfsthread.cpp index bf49b9668e..3d3ed9f6d4 100644 --- a/indra/llvfs/lllfsthread.cpp +++ b/indra/llvfs/lllfsthread.cpp @@ -67,6 +67,10 @@ LLLFSThread::LLLFSThread(bool threaded) : LLQueuedThread("LFS", threaded), mPriorityCounter(PRIORITY_LOWBITS) { + if(!mLocalAPRFilePoolp) + { + mLocalAPRFilePoolp = new LLVolatileAPRPool() ; + } } LLLFSThread::~LLLFSThread() @@ -178,7 +182,8 @@ bool LLLFSThread::Request::processRequest() if (mOperation == FILE_READ) { llassert(mOffset >= 0); - LLAPRFile infile(mFileName, LL_APR_RB); + LLAPRFile infile ; // auto-closes + infile.open(mFileName, LL_APR_RB, mThread->getLocalAPRFilePool()); if (!infile.getFileHandle()) { llwarns << "LLLFS: Unable to read file: " << mFileName << llendl; @@ -200,7 +205,8 @@ bool LLLFSThread::Request::processRequest() apr_int32_t flags = APR_CREATE|APR_WRITE|APR_BINARY; if (mOffset < 0) flags |= APR_APPEND; - LLAPRFile outfile(mFileName, flags); + LLAPRFile outfile ; // auto-closes + outfile.open(mFileName, flags, mThread->getLocalAPRFilePool()); if (!outfile.getFileHandle()) { llwarns << "LLLFS: Unable to write file: " << mFileName << llendl; diff --git a/indra/llvfs/llvfs.cpp b/indra/llvfs/llvfs.cpp index 1a64623028..c1fe21c57d 100644 --- a/indra/llvfs/llvfs.cpp +++ b/indra/llvfs/llvfs.cpp @@ -234,7 +234,7 @@ LLVFS::LLVFS(const std::string& index_filename, const std::string& data_filename mDataFP(NULL), mIndexFP(NULL) { - mDataMutex = new LLMutex; + mDataMutex = new LLMutex(0); S32 i; for (i = 0; i < VFSLOCK_COUNT; i++) @@ -2094,7 +2094,8 @@ void LLVFS::dumpFiles() std::string filename = id.asString() + extension; llinfos << " Writing " << filename << llendl; - LLAPRFile outfile(filename, LL_APR_WB); + LLAPRFile outfile; + outfile.open(filename, LL_APR_WB); outfile.write(&buffer[0], size); outfile.close(); diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h b/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h index 77d6d19663..6bc272c009 100644 --- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h +++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h @@ -37,6 +37,7 @@ extern "C" { #include #include +#include "apr_pools.h" #include "apr_dso.h" } diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp index 93a10424dd..2e4baaa9eb 100644 --- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp +++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp @@ -28,18 +28,16 @@ #if LL_GSTREAMER010_ENABLED -#include "linden_common.h" - #include extern "C" { #include +#include "apr_pools.h" #include "apr_dso.h" } #include "llmediaimplgstreamertriviallogging.h" -#include "llaprpool.h" #define LL_GST_SYM(REQ, GSTSYM, RTN, ...) RTN (*ll##GSTSYM)(__VA_ARGS__) = NULL #include "llmediaimplgstreamer_syms_raw.inc" @@ -58,7 +56,7 @@ void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname) } static bool sSymsGrabbed = false; -static LLAPRPool sSymGSTDSOMemoryPool; +static apr_pool_t *sSymGSTDSOMemoryPool = NULL; static apr_dso_handle_t *sSymGSTDSOHandleG = NULL; static apr_dso_handle_t *sSymGSTDSOHandleV = NULL; @@ -80,11 +78,11 @@ bool grab_gst_syms(std::string gst_dso_name, #define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##GSTSYM, sSymGSTDSOHandle, #GSTSYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #GSTSYM); if (REQ) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #GSTSYM, (void*)ll##GSTSYM);}while(0) //attempt to load the shared libraries - sSymGSTDSOMemoryPool.create(); + apr_pool_create(&sSymGSTDSOMemoryPool, NULL); if ( APR_SUCCESS == (rv = apr_dso_load(&sSymGSTDSOHandle, gst_dso_name.c_str(), - sSymGSTDSOMemoryPool()) )) + sSymGSTDSOMemoryPool) )) { INFOMSG("Found DSO: %s", gst_dso_name.c_str()); #include "llmediaimplgstreamer_syms_raw.inc" @@ -98,7 +96,7 @@ bool grab_gst_syms(std::string gst_dso_name, if ( APR_SUCCESS == (rv = apr_dso_load(&sSymGSTDSOHandle, gst_dso_name_vid.c_str(), - sSymGSTDSOMemoryPool()) )) + sSymGSTDSOMemoryPool) )) { INFOMSG("Found DSO: %s", gst_dso_name_vid.c_str()); #include "llmediaimplgstreamer_syms_rawv.inc" @@ -152,7 +150,8 @@ void ungrab_gst_syms() if ( sSymGSTDSOMemoryPool ) { - sSymGSTDSOMemoryPool.destroy(); + apr_pool_destroy(sSymGSTDSOMemoryPool); + sSymGSTDSOMemoryPool = NULL; } // NULL-out all of the symbols we'd grabbed diff --git a/indra/media_plugins/webkit/linux_volume_catcher.cpp b/indra/media_plugins/webkit/linux_volume_catcher.cpp index 94dfd80700..91be3a89e9 100644 --- a/indra/media_plugins/webkit/linux_volume_catcher.cpp +++ b/indra/media_plugins/webkit/linux_volume_catcher.cpp @@ -65,7 +65,7 @@ extern "C" { #undef LL_PA_SYM static bool sSymsGrabbed = false; -static LLAPRPool sSymPADSOMemoryPool; +static apr_pool_t *sSymPADSOMemoryPool = NULL; static apr_dso_handle_t *sSymPADSOHandleG = NULL; bool grab_pa_syms(std::string pulse_dso_name) @@ -84,11 +84,11 @@ bool grab_pa_syms(std::string pulse_dso_name) #define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##PASYM, sSymPADSOHandle, #PASYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #PASYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #PASYM, (void*)ll##PASYM);}while(0) //attempt to load the shared library - sSymPADSOMemoryPool.create(); + apr_pool_create(&sSymPADSOMemoryPool, NULL); if ( APR_SUCCESS == (rv = apr_dso_load(&sSymPADSOHandle, pulse_dso_name.c_str(), - sSymPADSOMemoryPool()) )) + sSymPADSOMemoryPool) )) { INFOMSG("Found DSO: %s", pulse_dso_name.c_str()); @@ -130,8 +130,12 @@ void ungrab_pa_syms() apr_dso_unload(sSymPADSOHandleG); sSymPADSOHandleG = NULL; } - - sSymPADSOMemoryPool.destroy(); + + if ( sSymPADSOMemoryPool ) + { + apr_pool_destroy(sSymPADSOMemoryPool); + sSymPADSOMemoryPool = NULL; + } // NULL-out all of the symbols we'd grabbed #define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{ll##PASYM = NULL;}while(0) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 1f76e2af40..a23f809b71 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1026,7 +1026,7 @@ bool LLAppViewer::mainLoop() //------------------------------------------- // Create IO Pump to use for HTTP Requests. - gServicePump = new LLPumpIO; + gServicePump = new LLPumpIO(gAPRPoolp); LLHTTPClient::setPump(*gServicePump); LLCurl::setCAFile(gDirUtilp->getCAFile()); @@ -1387,16 +1387,16 @@ bool LLAppViewer::cleanup() } // *TODO - generalize this and move DSO wrangling to a helper class -brad - for(std::map >::iterator plugin = mPlugins.begin(); - plugin != mPlugins.end(); ++plugin) + std::set::const_iterator i; + for(i = mPlugins.begin(); i != mPlugins.end(); ++i) { int (*ll_plugin_stop_func)(void) = NULL; - apr_status_t rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll_plugin_stop_func, plugin->first, "ll_plugin_stop"); + apr_status_t rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll_plugin_stop_func, *i, "ll_plugin_stop"); ll_plugin_stop_func(); - rv = apr_dso_unload(plugin->first); + rv = apr_dso_unload(*i); } - mPlugins.clear(); // Forget handles and destroy all memory pools. + mPlugins.clear(); //flag all elements as needing to be destroyed immediately // to ensure shutdown order @@ -1828,7 +1828,7 @@ bool LLAppViewer::initThreads() if (LLFastTimer::sLog || LLFastTimer::sMetricLog) { - LLFastTimer::sLogLock = new LLMutex; + LLFastTimer::sLogLock = new LLMutex(NULL); mFastTimerLogThread = new LLFastTimerLogThread(LLFastTimer::sLogName); mFastTimerLogThread->start(); } @@ -2969,7 +2969,8 @@ void LLAppViewer::handleViewerCrash() else crash_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,ERROR_MARKER_FILE_NAME); llinfos << "Creating crash marker file " << crash_file_name << llendl; - LLAPRFile crash_file(crash_file_name, LL_APR_W); + LLAPRFile crash_file ; + crash_file.open(crash_file_name, LL_APR_W); if (crash_file.getFileHandle()) { LL_INFOS("MarkerFile") << "Created crash marker file " << crash_file_name << LL_ENDL; @@ -3033,10 +3034,11 @@ bool LLAppViewer::anotherInstanceRunning() LL_DEBUGS("MarkerFile") << "Checking marker file for lock..." << LL_ENDL; //Freeze case checks - if (LLAPRFile::isExist(marker_file, LL_APR_RB)) + if (LLAPRFile::isExist(marker_file, NULL, LL_APR_RB)) { // File exists, try opening with write permissions - LLAPRFile outfile(marker_file, LL_APR_WB); + LLAPRFile outfile ; + outfile.open(marker_file, LL_APR_WB); apr_file_t* fMarker = outfile.getFileHandle() ; if (!fMarker) { @@ -3075,25 +3077,25 @@ void LLAppViewer::initMarkerFile() std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME); std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME); - if (LLAPRFile::isExist(mMarkerFileName, LL_APR_RB) && !anotherInstanceRunning()) + if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB) && !anotherInstanceRunning()) { gLastExecEvent = LAST_EXEC_FROZE; LL_INFOS("MarkerFile") << "Exec marker found: program froze on previous execution" << LL_ENDL; } - if(LLAPRFile::isExist(logout_marker_file, LL_APR_RB)) + if(LLAPRFile::isExist(logout_marker_file, NULL, LL_APR_RB)) { gLastExecEvent = LAST_EXEC_LOGOUT_FROZE; LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; LLAPRFile::remove(logout_marker_file); } - if(LLAPRFile::isExist(llerror_marker_file, LL_APR_RB)) + if(LLAPRFile::isExist(llerror_marker_file, NULL, LL_APR_RB)) { if(gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) gLastExecEvent = LAST_EXEC_LOGOUT_CRASH; else gLastExecEvent = LAST_EXEC_LLERROR_CRASH; LL_INFOS("MarkerFile") << "Last exec LLError crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; LLAPRFile::remove(llerror_marker_file); } - if(LLAPRFile::isExist(error_marker_file, LL_APR_RB)) + if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB)) { if(gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) gLastExecEvent = LAST_EXEC_LOGOUT_CRASH; else gLastExecEvent = LAST_EXEC_OTHER_CRASH; @@ -3109,7 +3111,7 @@ void LLAppViewer::initMarkerFile() // Create the marker file for this execution & lock it apr_status_t s; - s = mMarkerFile.open(mMarkerFileName, LL_APR_W, LLAPRFile::long_lived); + s = mMarkerFile.open(mMarkerFileName, LL_APR_W, TRUE); if (s == APR_SUCCESS && mMarkerFile.getFileHandle()) { @@ -4325,7 +4327,8 @@ void LLAppViewer::sendLogoutRequest() gLogoutInProgress = TRUE; mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME); - LLAPRFile outfile(mLogoutMarkerFileName, LL_APR_W); + LLAPRFile outfile ; + outfile.open(mLogoutMarkerFileName, LL_APR_W); mLogoutMarkerFile = outfile.getFileHandle() ; if (mLogoutMarkerFile) { @@ -4775,15 +4778,14 @@ void LLAppViewer::loadEventHostModule(S32 listen_port) } #endif // LL_WINDOWS - boost::shared_ptr eventhost_dso_memory_pool_ptr(new LLAPRPool); - LLAPRPool& eventhost_dso_memory_pool(*eventhost_dso_memory_pool_ptr); - apr_dso_handle_t* eventhost_dso_handle = NULL; + apr_dso_handle_t * eventhost_dso_handle = NULL; + apr_pool_t * eventhost_dso_memory_pool = NULL; //attempt to load the shared library - eventhost_dso_memory_pool.create(); + apr_pool_create(&eventhost_dso_memory_pool, NULL); apr_status_t rv = apr_dso_load(&eventhost_dso_handle, dso_path.c_str(), - eventhost_dso_memory_pool()); + eventhost_dso_memory_pool); llassert_always(! ll_apr_warn_status(rv, eventhost_dso_handle)); llassert_always(eventhost_dso_handle != NULL); @@ -4803,8 +4805,7 @@ void LLAppViewer::loadEventHostModule(S32 listen_port) llerrs << "problem loading eventhost plugin, status: " << status << llendl; } - // Store the handle and link it to the pool that was used to allocate it. - mPlugins[eventhost_dso_handle] = eventhost_dso_memory_pool_ptr; + mPlugins.insert(eventhost_dso_handle); } void LLAppViewer::launchUpdater() diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 00b12d50ae..a18e6cbb02 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -266,7 +266,7 @@ private: LLAllocator mAlloc; - std::map > mPlugins; + std::set mPlugins; U32 mAvailPhysicalMemInKB ; U32 mAvailVirtualMemInKB ; diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index d4c6131c80..898cc1c0ba 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -110,7 +110,6 @@ int main( int argc, char **argv ) } delete viewer_app_ptr; viewer_app_ptr = NULL; - return 0; } diff --git a/indra/newview/llappviewerlinux_api_dbus.cpp b/indra/newview/llappviewerlinux_api_dbus.cpp index 1ae469dfcf..32e7e0a83d 100644 --- a/indra/newview/llappviewerlinux_api_dbus.cpp +++ b/indra/newview/llappviewerlinux_api_dbus.cpp @@ -27,11 +27,11 @@ #if LL_DBUS_ENABLED #include "linden_common.h" -#include "llaprpool.h" extern "C" { #include +#include "apr_pools.h" #include "apr_dso.h" } @@ -44,7 +44,7 @@ extern "C" { #undef LL_DBUS_SYM static bool sSymsGrabbed = false; -static LLAPRPool sSymDBUSDSOMemoryPool; +static apr_pool_t *sSymDBUSDSOMemoryPool = NULL; static apr_dso_handle_t *sSymDBUSDSOHandleG = NULL; bool grab_dbus_syms(std::string dbus_dso_name) @@ -63,11 +63,11 @@ bool grab_dbus_syms(std::string dbus_dso_name) #define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##DBUSSYM, sSymDBUSDSOHandle, #DBUSSYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #DBUSSYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #DBUSSYM, (void*)ll##DBUSSYM);}while(0) //attempt to load the shared library - sSymDBUSDSOMemoryPool.create(); + apr_pool_create(&sSymDBUSDSOMemoryPool, NULL); if ( APR_SUCCESS == (rv = apr_dso_load(&sSymDBUSDSOHandle, dbus_dso_name.c_str(), - sSymDBUSDSOMemoryPool()) )) + sSymDBUSDSOMemoryPool) )) { INFOMSG("Found DSO: %s", dbus_dso_name.c_str()); @@ -109,7 +109,11 @@ void ungrab_dbus_syms() sSymDBUSDSOHandleG = NULL; } - sSymDBUSDSOMemoryPool.destroy(); + if ( sSymDBUSDSOMemoryPool ) + { + apr_pool_destroy(sSymDBUSDSOMemoryPool); + sSymDBUSDSOMemoryPool = NULL; + } // NULL-out all of the symbols we'd grabbed #define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) do{ll##DBUSSYM = NULL;}while(0) diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 13c8745eaf..1cd80986d8 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -113,7 +113,6 @@ int main( int argc, char **argv ) } delete viewer_app_ptr; viewer_app_ptr = NULL; - return 0; } diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp index 9b96332c10..deebd69ec1 100644 --- a/indra/newview/llfloateranimpreview.cpp +++ b/indra/newview/llfloateranimpreview.cpp @@ -223,7 +223,8 @@ BOOL LLFloaterAnimPreview::postBuild() // now load bvh file S32 file_size; - LLAPRFile infile(mFilenameAndPath, LL_APR_RB, &file_size); + LLAPRFile infile ; + infile.open(mFilenameAndPath, LL_APR_RB, NULL, &file_size); if (!infile.getFileHandle()) { diff --git a/indra/newview/llmainlooprepeater.cpp b/indra/newview/llmainlooprepeater.cpp index d73048a28b..5c020e6d98 100644 --- a/indra/newview/llmainlooprepeater.cpp +++ b/indra/newview/llmainlooprepeater.cpp @@ -46,7 +46,7 @@ void LLMainLoopRepeater::start(void) { if(mQueue != 0) return; - mQueue = new LLThreadSafeQueue(1024); + mQueue = new LLThreadSafeQueue(gAPRPoolp, 1024); mMainLoopConnection = LLEventPumps::instance(). obtain("mainloop").listen(LLEventPump::inventName(), boost::bind(&LLMainLoopRepeater::onMainLoop, this, _1)); mRepeaterConnection = LLEventPumps::instance(). diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index a47ea8581a..f54214b95c 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -176,7 +176,7 @@ private: bool LLTextureCacheLocalFileWorker::doRead() { - S32 local_size = LLAPRFile::size(mFileName); + S32 local_size = LLAPRFile::size(mFileName, mCache->getLocalAPRFilePool()); if (local_size > 0 && mFileName.size() > 4) { @@ -250,7 +250,7 @@ bool LLTextureCacheLocalFileWorker::doRead() } mReadData = new U8[mDataSize]; - S32 bytes_read = LLAPRFile::readEx(mFileName, mReadData, mOffset, mDataSize); + S32 bytes_read = LLAPRFile::readEx(mFileName, mReadData, mOffset, mDataSize, mCache->getLocalAPRFilePool()); if (bytes_read != mDataSize) { @@ -331,7 +331,7 @@ bool LLTextureCacheRemoteWorker::doRead() // Is it a JPEG2000 file? { local_filename = filename + ".j2c"; - local_size = LLAPRFile::size(local_filename); + local_size = LLAPRFile::size(local_filename, mCache->getLocalAPRFilePool()); if (local_size > 0) { mImageFormat = IMG_CODEC_J2C; @@ -341,7 +341,7 @@ bool LLTextureCacheRemoteWorker::doRead() if (local_size == 0) { local_filename = filename + ".jpg"; - local_size = LLAPRFile::size(local_filename); + local_size = LLAPRFile::size(local_filename, mCache->getLocalAPRFilePool()); if (local_size > 0) { mImageFormat = IMG_CODEC_JPEG; @@ -352,7 +352,7 @@ bool LLTextureCacheRemoteWorker::doRead() if (local_size == 0) { local_filename = filename + ".tga"; - local_size = LLAPRFile::size(local_filename); + local_size = LLAPRFile::size(local_filename, mCache->getLocalAPRFilePool()); if (local_size > 0) { mImageFormat = IMG_CODEC_TGA; @@ -378,7 +378,8 @@ bool LLTextureCacheRemoteWorker::doRead() } // Allocate read buffer mReadData = new U8[mDataSize]; - S32 bytes_read = LLAPRFile::readEx(local_filename, mReadData, mOffset, mDataSize); + S32 bytes_read = LLAPRFile::readEx(local_filename, + mReadData, mOffset, mDataSize, mCache->getLocalAPRFilePool()); if (bytes_read != mDataSize) { llwarns << "Error reading file from local cache: " << local_filename @@ -429,7 +430,8 @@ bool LLTextureCacheRemoteWorker::doRead() size = llmin(size, mDataSize); // Allocate the read buffer mReadData = new U8[size]; - S32 bytes_read = LLAPRFile::readEx(mCache->mHeaderDataFileName, mReadData, offset, size); + S32 bytes_read = LLAPRFile::readEx(mCache->mHeaderDataFileName, + mReadData, offset, size, mCache->getLocalAPRFilePool()); if (bytes_read != size) { llwarns << "LLTextureCacheWorker: " << mID @@ -455,7 +457,7 @@ bool LLTextureCacheRemoteWorker::doRead() if (!done && (mState == BODY)) { std::string filename = mCache->getTextureFileName(mID); - S32 filesize = LLAPRFile::size(filename); + S32 filesize = LLAPRFile::size(filename, mCache->getLocalAPRFilePool()); if (filesize && (filesize + TEXTURE_CACHE_ENTRY_SIZE) > mOffset) { @@ -497,7 +499,8 @@ bool LLTextureCacheRemoteWorker::doRead() // Read the data at last S32 bytes_read = LLAPRFile::readEx(filename, mReadData + data_offset, - file_offset, file_size); + file_offset, file_size, + mCache->getLocalAPRFilePool()); if (bytes_read != file_size) { llwarns << "LLTextureCacheWorker: " << mID @@ -598,13 +601,13 @@ bool LLTextureCacheRemoteWorker::doWrite() U8* padBuffer = new U8[TEXTURE_CACHE_ENTRY_SIZE]; memset(padBuffer, 0, TEXTURE_CACHE_ENTRY_SIZE); // Init with zeros memcpy(padBuffer, mWriteData, mDataSize); // Copy the write buffer - bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, padBuffer, offset, size); + bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, padBuffer, offset, size, mCache->getLocalAPRFilePool()); delete [] padBuffer; } else { // Write the header record (== first TEXTURE_CACHE_ENTRY_SIZE bytes of the raw file) in the header file - bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, mWriteData, offset, size); + bytes_written = LLAPRFile::writeEx(mCache->mHeaderDataFileName, mWriteData, offset, size, mCache->getLocalAPRFilePool()); } if (bytes_written <= 0) @@ -639,7 +642,8 @@ bool LLTextureCacheRemoteWorker::doWrite() // llinfos << "Writing Body: " << filename << " Bytes: " << file_offset+file_size << llendl; S32 bytes_written = LLAPRFile::writeEx( filename, mWriteData + TEXTURE_CACHE_ENTRY_SIZE, - 0, file_size); + 0, file_size, + mCache->getLocalAPRFilePool()); if (bytes_written <= 0) { llwarns << "LLTextureCacheWorker: " << mID @@ -736,6 +740,9 @@ void LLTextureCacheWorker::endWork(S32 param, bool aborted) LLTextureCache::LLTextureCache(bool threaded) : LLWorkerThread("TextureCache", threaded), + mWorkersMutex(NULL), + mHeaderMutex(NULL), + mListMutex(NULL), mHeaderAPRFile(NULL), mReadOnly(TRUE), //do not allow to change the texture cache until setReadOnly() is called. mTexturesSizeTotal(0), @@ -839,7 +846,7 @@ BOOL LLTextureCache::isInLocal(const LLUUID& id) // Is it a JPEG2000 file? { local_filename = filename + ".j2c"; - local_size = LLAPRFile::size(local_filename); + local_size = LLAPRFile::size(local_filename, getLocalAPRFilePool()); if (local_size > 0) { return TRUE ; @@ -849,7 +856,7 @@ BOOL LLTextureCache::isInLocal(const LLUUID& id) // If not, is it a jpeg file? { local_filename = filename + ".jpg"; - local_size = LLAPRFile::size(local_filename); + local_size = LLAPRFile::size(local_filename, getLocalAPRFilePool()); if (local_size > 0) { return TRUE ; @@ -859,7 +866,7 @@ BOOL LLTextureCache::isInLocal(const LLUUID& id) // Hmm... What about a targa file? (used for UI texture mostly) { local_filename = filename + ".tga"; - local_size = LLAPRFile::size(local_filename); + local_size = LLAPRFile::size(local_filename, getLocalAPRFilePool()); if (local_size > 0) { return TRUE ; @@ -905,10 +912,10 @@ void LLTextureCache::purgeCache(ELLPath location) if(LLFile::isdir(mTexturesDirName)) { std::string file_name = gDirUtilp->getExpandedFilename(location, entries_filename); - LLAPRFile::remove(file_name); + LLAPRFile::remove(file_name, getLocalAPRFilePool()); file_name = gDirUtilp->getExpandedFilename(location, cache_filename); - LLAPRFile::remove(file_name); + LLAPRFile::remove(file_name, getLocalAPRFilePool()); purgeAllTextures(true); } @@ -984,9 +991,7 @@ LLAPRFile* LLTextureCache::openHeaderEntriesFile(bool readonly, S32 offset) { llassert_always(mHeaderAPRFile == NULL); apr_int32_t flags = readonly ? APR_READ|APR_BINARY : APR_READ|APR_WRITE|APR_BINARY; - // All code calling openHeaderEntriesFile, immediately calls closeHeaderEntriesFile, - // so this file is very short-lived. - mHeaderAPRFile = new LLAPRFile(mHeaderEntriesFileName, flags); + mHeaderAPRFile = new LLAPRFile(mHeaderEntriesFileName, flags, getLocalAPRFilePool()); if(offset > 0) { mHeaderAPRFile->seek(APR_SET, offset); @@ -1009,9 +1014,10 @@ void LLTextureCache::readEntriesHeader() { // mHeaderEntriesInfo initializes to default values so safe not to read it llassert_always(mHeaderAPRFile == NULL); - if (LLAPRFile::isExist(mHeaderEntriesFileName)) + if (LLAPRFile::isExist(mHeaderEntriesFileName, getLocalAPRFilePool())) { - LLAPRFile::readEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo)); + LLAPRFile::readEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo), + getLocalAPRFilePool()); } else //create an empty entries header. { @@ -1026,7 +1032,8 @@ void LLTextureCache::writeEntriesHeader() llassert_always(mHeaderAPRFile == NULL); if (!mReadOnly) { - LLAPRFile::writeEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo)); + LLAPRFile::writeEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo), + getLocalAPRFilePool()); } } @@ -1616,7 +1623,7 @@ void LLTextureCache::purgeTextures(bool validate) if (uuididx == validate_idx) { LL_DEBUGS("TextureCache") << "Validating: " << filename << "Size: " << entries[idx].mBodySize << LL_ENDL; - S32 bodysize = LLAPRFile::size(filename); + S32 bodysize = LLAPRFile::size(filename, getLocalAPRFilePool()); if (bodysize != entries[idx].mBodySize) { LL_WARNS("TextureCache") << "TEXTURE CACHE BODY HAS BAD SIZE: " << bodysize << " != " << entries[idx].mBodySize @@ -1851,7 +1858,7 @@ void LLTextureCache::removeCachedTexture(const LLUUID& id) mTexturesSizeMap.erase(id); } mHeaderIDMap.erase(id); - LLAPRFile::remove(getTextureFileName(id)); + LLAPRFile::remove(getTextureFileName(id), getLocalAPRFilePool()); } //called after mHeaderMutex is locked. @@ -1863,7 +1870,7 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename) { if (entry.mBodySize == 0) // Always attempt to remove when mBodySize > 0. { - if (LLAPRFile::isExist(filename)) // Sanity check. Shouldn't exist when body size is 0. + if (LLAPRFile::isExist(filename, getLocalAPRFilePool())) // Sanity check. Shouldn't exist when body size is 0. { LL_WARNS("TextureCache") << "Entry has body size of zero but file " << filename << " exists. Deleting this file, too." << LL_ENDL; } @@ -1884,7 +1891,7 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename) if (file_maybe_exists) { - LLAPRFile::remove(filename); + LLAPRFile::remove(filename, getLocalAPRFilePool()); } } diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h index 79f5ba5835..64e3a2658c 100644 --- a/indra/newview/lltexturecache.h +++ b/indra/newview/lltexturecache.h @@ -142,6 +142,9 @@ protected: std::string getTextureFileName(const LLUUID& id); void addCompleted(Responder* responder, bool success); +protected: + //void setFileAPRPool(apr_pool_t* pool) { mFileAPRPool = pool ; } + private: void setDirNames(ELLPath location); void readHeaderCache(); diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 139b434aeb..18c3a3b87d 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -674,6 +674,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, mRetryAttempt(0), mActiveCount(0), mGetStatus(0), + mWorkMutex(NULL), mFirstPacket(0), mLastPacket(-1), mTotalPackets(0), @@ -1815,6 +1816,8 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image mDebugPause(FALSE), mPacketCount(0), mBadPacketCount(0), + mQueueMutex(getAPRPool()), + mNetworkQueueMutex(getAPRPool()), mTextureCache(cache), mImageDecodeThread(imagedecodethread), mTextureBandwidth(0), diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 6bee7556cd..fda291f3c1 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -736,7 +736,8 @@ void upload_new_resource(const std::string& src_filename, std::string name, uuid = tid.makeAssetID(gAgent.getSecureSessionID()); // copy this file into the vfs for upload S32 file_size; - LLAPRFile infile(filename, LL_APR_RB, &file_size); + LLAPRFile infile ; + infile.open(filename, LL_APR_RB, NULL, &file_size); if (infile.getFileHandle()) { LLVFile file(gVFS, uuid, asset_type, LLVFile::WRITE); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 2cd9b09932..fd89044995 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -7190,7 +7190,8 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id ) // static void LLVOAvatar::dumpArchetypeXML( void* ) { - LLAPRFile outfile(gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER, "new archetype.xml"), LL_APR_WB); + LLAPRFile outfile; + outfile.open(gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,"new archetype.xml"), LL_APR_WB ); apr_file_t* file = outfile.getFileHandle() ; if (!file) { diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index d25831b4f1..a933500706 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -30,14 +30,14 @@ #include "llregionhandle.h" #include "llviewercontrol.h" -static BOOL check_read(LLAPRFile& apr_file, void* src, S32 n_bytes) +BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes) { - return apr_file.read(src, n_bytes) == n_bytes ; + return apr_file->read(src, n_bytes) == n_bytes ; } -static BOOL check_write(LLAPRFile& apr_file, void* src, S32 n_bytes) +BOOL check_write(LLAPRFile* apr_file, void* src, S32 n_bytes) { - return apr_file.write(src, n_bytes) == n_bytes ; + return apr_file->write(src, n_bytes) == n_bytes ; } @@ -70,7 +70,7 @@ LLVOCacheEntry::LLVOCacheEntry() mDP.assignBuffer(mBuffer, 0); } -LLVOCacheEntry::LLVOCacheEntry(LLAPRFile& apr_file) +LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file) { S32 size = -1; BOOL success; @@ -185,7 +185,7 @@ void LLVOCacheEntry::dump() const << llendl; } -BOOL LLVOCacheEntry::writeToFile(LLAPRFile& apr_file) const +BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const { BOOL success; success = check_write(apr_file, (void*)&mLocalID, sizeof(U32)); @@ -266,6 +266,7 @@ LLVOCache::LLVOCache(): mCacheSize(1) { mEnabled = gSavedSettings.getBOOL("ObjectCacheEnabled"); + mLocalAPRFilePoolp = new LLVolatileAPRPool() ; } LLVOCache::~LLVOCache() @@ -275,6 +276,7 @@ LLVOCache::~LLVOCache() writeCacheHeader(); clearCacheInMemory(); } + delete mLocalAPRFilePoolp; } void LLVOCache::setDirNames(ELLPath location) @@ -435,7 +437,7 @@ void LLVOCache::removeFromCache(HeaderEntryInfo* entry) std::string filename; getObjectCacheFilename(entry->mHandle, filename); - LLAPRFile::remove(filename); + LLAPRFile::remove(filename, mLocalAPRFilePoolp); entry->mTime = INVALID_TIME ; updateEntry(entry) ; //update the head file. } @@ -452,12 +454,12 @@ void LLVOCache::readCacheHeader() clearCacheInMemory(); bool success = true ; - if (LLAPRFile::isExist(mHeaderFileName)) + if (LLAPRFile::isExist(mHeaderFileName, mLocalAPRFilePoolp)) { - LLAPRFile apr_file(mHeaderFileName, APR_READ|APR_BINARY); + LLAPRFile apr_file(mHeaderFileName, APR_READ|APR_BINARY, mLocalAPRFilePoolp); //read the meta element - success = check_read(apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ; + success = check_read(&apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ; if(success) { @@ -470,7 +472,7 @@ void LLVOCache::readCacheHeader() { entry = new HeaderEntryInfo() ; } - success = check_read(apr_file, entry, sizeof(HeaderEntryInfo)); + success = check_read(&apr_file, entry, sizeof(HeaderEntryInfo)); if(!success) //failed { @@ -539,17 +541,17 @@ void LLVOCache::writeCacheHeader() bool success = true ; { - LLAPRFile apr_file(mHeaderFileName, APR_CREATE|APR_WRITE|APR_BINARY); + LLAPRFile apr_file(mHeaderFileName, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp); //write the meta element - success = check_write(apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ; + success = check_write(&apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)) ; mNumEntries = 0 ; for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; success && iter != mHeaderEntryQueue.end(); ++iter) { (*iter)->mIndex = mNumEntries++ ; - success = check_write(apr_file, (void*)*iter, sizeof(HeaderEntryInfo)); + success = check_write(&apr_file, (void*)*iter, sizeof(HeaderEntryInfo)); } mNumEntries = mHeaderEntryQueue.size() ; @@ -560,7 +562,7 @@ void LLVOCache::writeCacheHeader() for(S32 i = mNumEntries ; success && i < MAX_NUM_OBJECT_ENTRIES ; i++) { //fill the cache with the default entry. - success = check_write(apr_file, entry, sizeof(HeaderEntryInfo)) ; + success = check_write(&apr_file, entry, sizeof(HeaderEntryInfo)) ; } delete entry ; @@ -577,10 +579,10 @@ void LLVOCache::writeCacheHeader() BOOL LLVOCache::updateEntry(const HeaderEntryInfo* entry) { - LLAPRFile apr_file(mHeaderFileName, APR_WRITE|APR_BINARY); - apr_file.seek(APR_SET, entry->mIndex * sizeof(HeaderEntryInfo) + sizeof(HeaderMetaInfo)); + LLAPRFile apr_file(mHeaderFileName, APR_WRITE|APR_BINARY, mLocalAPRFilePoolp); + apr_file.seek(APR_SET, entry->mIndex * sizeof(HeaderEntryInfo) + sizeof(HeaderMetaInfo)) ; - return check_write(apr_file, (void*)entry, sizeof(HeaderEntryInfo)) ; + return check_write(&apr_file, (void*)entry, sizeof(HeaderEntryInfo)) ; } void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map) @@ -603,10 +605,10 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca { std::string filename; getObjectCacheFilename(handle, filename); - LLAPRFile apr_file(filename, APR_READ|APR_BINARY); + LLAPRFile apr_file(filename, APR_READ|APR_BINARY, mLocalAPRFilePoolp); LLUUID cache_id ; - success = check_read(apr_file, cache_id.mData, UUID_BYTES) ; + success = check_read(&apr_file, cache_id.mData, UUID_BYTES) ; if(success) { @@ -619,11 +621,11 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca if(success) { S32 num_entries; - success = check_read(apr_file, &num_entries, sizeof(S32)) ; + success = check_read(&apr_file, &num_entries, sizeof(S32)) ; for (S32 i = 0; success && i < num_entries; i++) { - LLVOCacheEntry* entry = new LLVOCacheEntry(apr_file); + LLVOCacheEntry* entry = new LLVOCacheEntry(&apr_file); if (!entry->getLocalID()) { llwarns << "Aborting cache file load for " << filename << ", cache file corruption!" << llendl; @@ -722,19 +724,19 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry: { std::string filename; getObjectCacheFilename(handle, filename); - LLAPRFile apr_file(filename, APR_CREATE|APR_WRITE|APR_BINARY); + LLAPRFile apr_file(filename, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp); - success = check_write(apr_file, (void*)id.mData, UUID_BYTES) ; + success = check_write(&apr_file, (void*)id.mData, UUID_BYTES) ; if(success) { S32 num_entries = cache_entry_map.size() ; - success = check_write(apr_file, &num_entries, sizeof(S32)); + success = check_write(&apr_file, &num_entries, sizeof(S32)); for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); success && iter != cache_entry_map.end(); ++iter) { - success = iter->second->writeToFile(apr_file) ; + success = iter->second->writeToFile(&apr_file) ; } } } diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h index 76456b9e98..14e3b4c793 100644 --- a/indra/newview/llvocache.h +++ b/indra/newview/llvocache.h @@ -41,7 +41,7 @@ class LLVOCacheEntry { public: LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp); - LLVOCacheEntry(LLAPRFile& apr_file); + LLVOCacheEntry(LLAPRFile* apr_file); LLVOCacheEntry(); ~LLVOCacheEntry(); @@ -51,7 +51,7 @@ public: S32 getCRCChangeCount() const { return mCRCChangeCount; } void dump() const; - BOOL writeToFile(LLAPRFile& apr_file) const; + BOOL writeToFile(LLAPRFile* apr_file) const; void assignCRC(U32 crc, LLDataPackerBinaryBuffer &dp); LLDataPackerBinaryBuffer *getDP(U32 crc); void recordHit(); @@ -142,6 +142,7 @@ private: U32 mNumEntries; std::string mHeaderFileName ; std::string mObjectCacheDirName; + LLVolatileAPRPool* mLocalAPRFilePoolp ; header_entry_queue_t mHeaderEntryQueue; handle_entry_map_t mHandleEntryMap; diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 828207ce1a..08e242af8e 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -961,7 +961,7 @@ void LLVivoxVoiceClient::stateMachine() if(!mSocket) { - mSocket = LLSocket::create(LLSocket::STREAM_TCP); + mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); } mConnected = mSocket->blockingConnect(mDaemonHost); diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp index d982ca5020..1694126802 100644 --- a/indra/newview/llwatchdog.cpp +++ b/indra/newview/llwatchdog.cpp @@ -178,8 +178,8 @@ void LLWatchdog::init(killer_event_callback func) mKillerCallback = func; if(!mSuspectsAccessMutex && !mTimer) { - mSuspectsAccessMutex = new LLMutex; - mTimer = new LLWatchdogTimerThread; + mSuspectsAccessMutex = new LLMutex(NULL); + mTimer = new LLWatchdogTimerThread(); mTimer->setSleepTime(WATCHDOG_SLEEP_TIME_USEC / 1000); mLastClockCount = LLTimer::getTotalTime(); diff --git a/indra/newview/tests/llworldmap_test.cpp b/indra/newview/tests/llworldmap_test.cpp index 102294959a..acc6e814bc 100644 --- a/indra/newview/tests/llworldmap_test.cpp +++ b/indra/newview/tests/llworldmap_test.cpp @@ -27,6 +27,7 @@ // Dependencies #include "linden_common.h" +#include "llapr.h" #include "llsingleton.h" #include "lltrans.h" #include "lluistring.h" diff --git a/indra/test/lltemplatemessagebuilder_tut.cpp b/indra/test/lltemplatemessagebuilder_tut.cpp index 532f26ee60..09beb53869 100644 --- a/indra/test/lltemplatemessagebuilder_tut.cpp +++ b/indra/test/lltemplatemessagebuilder_tut.cpp @@ -29,6 +29,7 @@ #include "linden_common.h" #include "lltut.h" +#include "llapr.h" #include "llmessagetemplate.h" #include "llquaternion.h" #include "lltemplatemessagebuilder.h" @@ -52,6 +53,7 @@ namespace tut static bool init = false; if(! init) { + ll_init_apr(); const F32 circuit_heartbeat_interval=5; const F32 circuit_timeout=100; diff --git a/indra/test/message_tut.cpp b/indra/test/message_tut.cpp index 9a6ccd4d68..d971b33475 100644 --- a/indra/test/message_tut.cpp +++ b/indra/test/message_tut.cpp @@ -29,6 +29,7 @@ #include "linden_common.h" #include "lltut.h" +#include "llapr.h" #include "llmessageconfig.h" #include "llsdserialize.h" #include "llversionserver.h" @@ -61,6 +62,7 @@ namespace tut static bool init = false; if(!init) { + ll_init_apr(); //init_prehash_data(); init = true; } diff --git a/indra/test/test.cpp b/indra/test/test.cpp index 45e8aef99a..ffdb0cb976 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -37,8 +37,8 @@ #include "linden_common.h" #include "llerrorcontrol.h" #include "lltut.h" -#include "llaprpool.h" +#include "apr_pools.h" #include "apr_getopt.h" // the CTYPE_WORKAROUND is needed for linux dev stations that don't @@ -349,12 +349,17 @@ int main(int argc, char **argv) ctype_workaround(); #endif - LLAPRPool pool; - pool.create(); + apr_initialize(); + apr_pool_t* pool = NULL; + if(APR_SUCCESS != apr_pool_create(&pool, NULL)) + { + std::cerr << "Unable to initialize pool" << std::endl; + return 1; + } apr_getopt_t* os = NULL; - if(APR_SUCCESS != apr_getopt_init(&os, pool(), argc, argv)) + if(APR_SUCCESS != apr_getopt_init(&os, pool, argc, argv)) { - std::cerr << "Unable to initialize the arguments for parsing by apr_getopt()." << std::endl; + std::cerr << "Unable to pool" << std::endl; return 1; } @@ -472,6 +477,8 @@ int main(int argc, char **argv) s.close(); } + apr_terminate(); + int retval = (success ? 0 : 1); return retval; diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp index fd46626ff1..4a2272032b 100644 --- a/indra/test_apps/llplugintest/llmediaplugintest.cpp +++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp @@ -27,6 +27,7 @@ #include "linden_common.h" #include "indra_constants.h" +#include "llapr.h" #include "llerrorcontrol.h" #include @@ -185,6 +186,9 @@ LLMediaPluginTest::LLMediaPluginTest( int app_window, int window_width, int wind std::cout << "Unable to read bookmarks from file: " << bookmarks_filename << std::endl; }; + // initialize linden lab APR module + ll_init_apr(); + // Set up llerror logging { LLError::initForApplication("."); diff --git a/indra/viewer_components/updater/llupdateinstaller.cpp b/indra/viewer_components/updater/llupdateinstaller.cpp index 6aa87d1be6..d450c068ad 100644 --- a/indra/viewer_components/updater/llupdateinstaller.cpp +++ b/indra/viewer_components/updater/llupdateinstaller.cpp @@ -26,7 +26,6 @@ #include "linden_common.h" #include #include "llapr.h" -#include "llscopedvolatileaprpool.h" #include "llprocesslauncher.h" #include "llupdateinstaller.h" #include "lldir.h" @@ -46,8 +45,7 @@ namespace { { std::string scriptFile = gDirUtilp->getBaseFileName(path); std::string newPath = gDirUtilp->getExpandedFilename(LL_PATH_TEMP, scriptFile); - LLScopedVolatileAPRPool pool; - apr_status_t status = apr_file_copy(path.c_str(), newPath.c_str(), APR_FILE_SOURCE_PERMS, pool); + apr_status_t status = apr_file_copy(path.c_str(), newPath.c_str(), APR_FILE_SOURCE_PERMS, gAPRPoolp); if(status != APR_SUCCESS) throw RelocateError(); return newPath; -- cgit v1.3 From 17194cab5db3a956d9768f89238e63bc30b0a9a6 Mon Sep 17 00:00:00 2001 From: Leslie Linden Date: Wed, 26 Oct 2011 09:55:57 -0700 Subject: Removed text spam about range of spatial partition, per davep. --- indra/llmath/lloctree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index e5ca47da69..3c1ae45d68 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -681,7 +681,7 @@ public: if (lt != 0x7) { - OCT_ERRS << "!!! ELEMENT EXCEEDS RANGE OF SPATIAL PARTITION !!!" << llendl; + //OCT_ERRS << "!!! ELEMENT EXCEEDS RANGE OF SPATIAL PARTITION !!!" << llendl; return false; } -- cgit v1.3 From db7924681d629f48f939e7d4cc55d588aa93c344 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 8 Nov 2011 17:46:43 -0600 Subject: SH-24114 Remove unused vectorization code (outdated/unused with SSE2 requirement and llvetor4a et al) --- indra/llmath/CMakeLists.txt | 4 - indra/llmath/llv4math.h | 141 ----------------- indra/llmath/llv4matrix3.h | 220 --------------------------- indra/llmath/llv4matrix4.h | 249 ------------------------------- indra/llmath/llv4vector3.h | 80 ---------- indra/newview/CMakeLists.txt | 17 --- indra/newview/app_settings/settings.xml | 44 ------ indra/newview/llappviewer.cpp | 38 ----- indra/newview/llviewercontrol.cpp | 10 -- indra/newview/llviewerjointmesh.cpp | 171 +-------------------- indra/newview/llviewerjointmesh.h | 19 +-- indra/newview/llviewerjointmesh_sse.cpp | 114 -------------- indra/newview/llviewerjointmesh_sse2.cpp | 121 --------------- indra/newview/llviewerjointmesh_vec.cpp | 97 ------------ indra/newview/llviewermenu.cpp | 21 --- 15 files changed, 6 insertions(+), 1340 deletions(-) delete mode 100644 indra/llmath/llv4math.h delete mode 100644 indra/llmath/llv4matrix3.h delete mode 100644 indra/llmath/llv4matrix4.h delete mode 100644 indra/llmath/llv4vector3.h delete mode 100644 indra/newview/llviewerjointmesh_sse.cpp delete mode 100644 indra/newview/llviewerjointmesh_sse2.cpp delete mode 100644 indra/newview/llviewerjointmesh_vec.cpp (limited to 'indra/llmath') diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index cd100cdf9f..b5e59c1ca3 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -75,10 +75,6 @@ set(llmath_HEADER_FILES llvector4a.h llvector4a.inl llvector4logical.h - llv4math.h - llv4matrix3.h - llv4matrix4.h - llv4vector3.h llvolume.h llvolumemgr.h llvolumeoctree.h diff --git a/indra/llmath/llv4math.h b/indra/llmath/llv4math.h deleted file mode 100644 index 5f403ba526..0000000000 --- a/indra/llmath/llv4math.h +++ /dev/null @@ -1,141 +0,0 @@ -/** - * @file llv4math.h - * @brief LLV4* class header file - vector processor enabled math - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLV4MATH_H -#define LL_LLV4MATH_H - -// *NOTE: We do not support SSE acceleration on Windows builds. -// Our minimum specification for the viewer includes 1 GHz Athlon processors, -// which covers the Athlon Thunderbird series that does not support SSE. -// -// Our header files include statements like this -// const F32 HAVOK_TIMESTEP = 1.f / 45.f; -// This creates "globals" that are included in each .obj file. If a single -// .cpp file has SSE code generation turned on (eg, llviewerjointmesh_sse.cpp) -// these globals will be initialized using SSE instructions. This causes SL -// to crash before main() on processors without SSE. Untangling all these -// headers/variables is too much work for the small performance gains of -// vectorization. -// -// Therefore we only support vectorization on builds where the everything is -// built with SSE or Altivec. See https://jira.secondlife.com/browse/VWR-1610 -// and https://jira.lindenlab.com/browse/SL-47720 for details. -// -// Sorry the code is such a mess. JC - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// LLV4MATH - GNUC -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -#if LL_GNUC && __GNUC__ >= 4 && __SSE__ - -#define LL_VECTORIZE 1 - -#if LL_DARWIN - -#include -#include -typedef vFloat V4F32; - -#else - -#include -typedef float V4F32 __attribute__((vector_size(16))); - -#endif - -#endif -#if LL_GNUC - -#define LL_LLV4MATH_ALIGN_PREFIX -#define LL_LLV4MATH_ALIGN_POSTFIX __attribute__((aligned(16))) - -#endif - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// LLV4MATH - MSVC -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -// Only vectorize if the entire Windows build uses SSE. -// _M_IX86_FP is set when SSE code generation is turned on, and I have -// confirmed this in VS2003, VS2003 SP1, and VS2005. JC -#if LL_MSVC && _M_IX86_FP - -#define LL_VECTORIZE 1 - -#include - -typedef __m128 V4F32; - -#endif -#if LL_MSVC - -#define LL_LLV4MATH_ALIGN_PREFIX __declspec(align(16)) -#define LL_LLV4MATH_ALIGN_POSTFIX - -#endif - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// LLV4MATH - default - no vectorization -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -#if !LL_VECTORIZE - -#define LL_VECTORIZE 0 - -struct V4F32 { F32 __pad__[4]; }; - -inline F32 llv4lerp(F32 a, F32 b, F32 w) { return ( b - a ) * w + a; } - -#endif - -#ifndef LL_LLV4MATH_ALIGN_PREFIX -# define LL_LLV4MATH_ALIGN_PREFIX -#endif -#ifndef LL_LLV4MATH_ALIGN_POSTFIX -# define LL_LLV4MATH_ALIGN_POSTFIX -#endif - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// LLV4MATH -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - - -#define LLV4_NUM_AXIS 4 - -class LLV4Vector3; -class LLV4Matrix3; -class LLV4Matrix4; - -#endif diff --git a/indra/llmath/llv4matrix3.h b/indra/llmath/llv4matrix3.h deleted file mode 100644 index 270f5d7dae..0000000000 --- a/indra/llmath/llv4matrix3.h +++ /dev/null @@ -1,220 +0,0 @@ -/** - * @file llviewerjointmesh.cpp - * @brief LLV4* class header file - vector processor enabled math - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLV4MATRIX3_H -#define LL_LLV4MATRIX3_H - -#include "llv4math.h" -#include "llv4vector3.h" -#include "m3math.h" // for operator LLMatrix3() - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// LLV4Matrix3 -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -LL_LLV4MATH_ALIGN_PREFIX - -class LLV4Matrix3 -{ -public: - union { - F32 mMatrix[LLV4_NUM_AXIS][LLV4_NUM_AXIS]; - V4F32 mV[LLV4_NUM_AXIS]; - }; - - void lerp(const LLV4Matrix3 &a, const LLV4Matrix3 &b, const F32 &w); - void multiply(const LLVector3 &a, LLVector3& out) const; - void multiply(const LLVector4 &a, LLV4Vector3& out) const; - void multiply(const LLVector3 &a, LLV4Vector3& out) const; - - const LLV4Matrix3& transpose(); - const LLV4Matrix3& operator=(const LLMatrix3& a); - - operator LLMatrix3() const { return (reinterpret_cast(const_cast(&mMatrix[0][0])))->getMat3(); } - - friend LLVector3 operator*(const LLVector3& a, const LLV4Matrix3& b); -} - -LL_LLV4MATH_ALIGN_POSTFIX; - - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// LLV4Matrix3 - SSE -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -#if LL_VECTORIZE - -inline void LLV4Matrix3::lerp(const LLV4Matrix3 &a, const LLV4Matrix3 &b, const F32 &w) -{ - __m128 vw = _mm_set1_ps(w); - mV[VX] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VX], a.mV[VX]), vw), a.mV[VX]); // ( b - a ) * w + a - mV[VY] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VY], a.mV[VY]), vw), a.mV[VY]); - mV[VZ] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VZ], a.mV[VZ]), vw), a.mV[VZ]); -} - -inline void LLV4Matrix3::multiply(const LLVector3 &a, LLVector3& o) const -{ - LLV4Vector3 j; - j.v = _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX]); // ( ax * vx ) + ... - j.v = _mm_add_ps(j.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY])); - j.v = _mm_add_ps(j.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ])); - o.setVec(j.mV); -} - -inline void LLV4Matrix3::multiply(const LLVector4 &a, LLV4Vector3& o) const -{ - o.v = _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX]); // ( ax * vx ) + ... - o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY])); - o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ])); -} - -inline void LLV4Matrix3::multiply(const LLVector3 &a, LLV4Vector3& o) const -{ - o.v = _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX]); // ( ax * vx ) + ... - o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY])); - o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ])); -} - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// LLV4Matrix3 -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -#else - -inline void LLV4Matrix3::lerp(const LLV4Matrix3 &a, const LLV4Matrix3 &b, const F32 &w) -{ - mMatrix[VX][VX] = llv4lerp(a.mMatrix[VX][VX], b.mMatrix[VX][VX], w); - mMatrix[VX][VY] = llv4lerp(a.mMatrix[VX][VY], b.mMatrix[VX][VY], w); - mMatrix[VX][VZ] = llv4lerp(a.mMatrix[VX][VZ], b.mMatrix[VX][VZ], w); - - mMatrix[VY][VX] = llv4lerp(a.mMatrix[VY][VX], b.mMatrix[VY][VX], w); - mMatrix[VY][VY] = llv4lerp(a.mMatrix[VY][VY], b.mMatrix[VY][VY], w); - mMatrix[VY][VZ] = llv4lerp(a.mMatrix[VY][VZ], b.mMatrix[VY][VZ], w); - - mMatrix[VZ][VX] = llv4lerp(a.mMatrix[VZ][VX], b.mMatrix[VZ][VX], w); - mMatrix[VZ][VY] = llv4lerp(a.mMatrix[VZ][VY], b.mMatrix[VZ][VY], w); - mMatrix[VZ][VZ] = llv4lerp(a.mMatrix[VZ][VZ], b.mMatrix[VZ][VZ], w); -} - -inline void LLV4Matrix3::multiply(const LLVector3 &a, LLVector3& o) const -{ - o.setVec( a.mV[VX] * mMatrix[VX][VX] + - a.mV[VY] * mMatrix[VY][VX] + - a.mV[VZ] * mMatrix[VZ][VX], - - a.mV[VX] * mMatrix[VX][VY] + - a.mV[VY] * mMatrix[VY][VY] + - a.mV[VZ] * mMatrix[VZ][VY], - - a.mV[VX] * mMatrix[VX][VZ] + - a.mV[VY] * mMatrix[VY][VZ] + - a.mV[VZ] * mMatrix[VZ][VZ]); -} - -inline void LLV4Matrix3::multiply(const LLVector4 &a, LLV4Vector3& o) const -{ - o.setVec( a.mV[VX] * mMatrix[VX][VX] + - a.mV[VY] * mMatrix[VY][VX] + - a.mV[VZ] * mMatrix[VZ][VX], - - a.mV[VX] * mMatrix[VX][VY] + - a.mV[VY] * mMatrix[VY][VY] + - a.mV[VZ] * mMatrix[VZ][VY], - - a.mV[VX] * mMatrix[VX][VZ] + - a.mV[VY] * mMatrix[VY][VZ] + - a.mV[VZ] * mMatrix[VZ][VZ]); -} - -inline void LLV4Matrix3::multiply(const LLVector3 &a, LLV4Vector3& o) const -{ - o.setVec( a.mV[VX] * mMatrix[VX][VX] + - a.mV[VY] * mMatrix[VY][VX] + - a.mV[VZ] * mMatrix[VZ][VX], - - a.mV[VX] * mMatrix[VX][VY] + - a.mV[VY] * mMatrix[VY][VY] + - a.mV[VZ] * mMatrix[VZ][VY], - - a.mV[VX] * mMatrix[VX][VZ] + - a.mV[VY] * mMatrix[VY][VZ] + - a.mV[VZ] * mMatrix[VZ][VZ]); -} - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// LLV4Matrix3 -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -#endif - -inline const LLV4Matrix3& LLV4Matrix3::transpose() -{ -#if LL_VECTORIZE && defined(_MM_TRANSPOSE4_PS) - _MM_TRANSPOSE4_PS(mV[VX], mV[VY], mV[VZ], mV[VW]); - return *this; -#else - F32 temp; - temp = mMatrix[VX][VY]; mMatrix[VX][VY] = mMatrix[VY][VX]; mMatrix[VY][VX] = temp; - temp = mMatrix[VX][VZ]; mMatrix[VX][VZ] = mMatrix[VZ][VX]; mMatrix[VZ][VX] = temp; - temp = mMatrix[VY][VZ]; mMatrix[VY][VZ] = mMatrix[VZ][VY]; mMatrix[VZ][VY] = temp; -#endif - return *this; -} - -inline const LLV4Matrix3& LLV4Matrix3::operator=(const LLMatrix3& a) -{ - memcpy(mMatrix[VX], a.mMatrix[VX], sizeof(F32) * 3 ); - memcpy(mMatrix[VY], a.mMatrix[VY], sizeof(F32) * 3 ); - memcpy(mMatrix[VZ], a.mMatrix[VZ], sizeof(F32) * 3 ); - return *this; -} - -inline LLVector3 operator*(const LLVector3& a, const LLV4Matrix3& b) -{ - return LLVector3( - a.mV[VX] * b.mMatrix[VX][VX] + - a.mV[VY] * b.mMatrix[VY][VX] + - a.mV[VZ] * b.mMatrix[VZ][VX], - - a.mV[VX] * b.mMatrix[VX][VY] + - a.mV[VY] * b.mMatrix[VY][VY] + - a.mV[VZ] * b.mMatrix[VZ][VY], - - a.mV[VX] * b.mMatrix[VX][VZ] + - a.mV[VY] * b.mMatrix[VY][VZ] + - a.mV[VZ] * b.mMatrix[VZ][VZ] ); -} - -#endif diff --git a/indra/llmath/llv4matrix4.h b/indra/llmath/llv4matrix4.h deleted file mode 100644 index 2eb49d9294..0000000000 --- a/indra/llmath/llv4matrix4.h +++ /dev/null @@ -1,249 +0,0 @@ -/** - * @file llviewerjointmesh.cpp - * @brief LLV4* class header file - vector processor enabled math - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLV4MATRIX4_H -#define LL_LLV4MATRIX4_H - -#include "llv4math.h" -#include "llv4matrix3.h" // just for operator LLV4Matrix3() -#include "llv4vector3.h" - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// LLV4Matrix4 -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -LL_LLV4MATH_ALIGN_PREFIX - -class LLV4Matrix4 -{ -public: - union { - F32 mMatrix[LLV4_NUM_AXIS][LLV4_NUM_AXIS]; - V4F32 mV[LLV4_NUM_AXIS]; - }; - - void lerp(const LLV4Matrix4 &a, const LLV4Matrix4 &b, const F32 &w); - void multiply(const LLVector3 &a, LLVector3& o) const; - void multiply(const LLVector3 &a, LLV4Vector3& o) const; - - const LLV4Matrix4& transpose(); - const LLV4Matrix4& translate(const LLVector3 &vec); - const LLV4Matrix4& translate(const LLV4Vector3 &vec); - const LLV4Matrix4& operator=(const LLMatrix4& a); - - operator LLMatrix4() const { return *(reinterpret_cast(const_cast(&mMatrix[0][0]))); } - operator LLV4Matrix3() const { return *(reinterpret_cast(const_cast(&mMatrix[0][0]))); } - - friend LLVector3 operator*(const LLVector3 &a, const LLV4Matrix4 &b); -} - -LL_LLV4MATH_ALIGN_POSTFIX; - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// LLV4Matrix4 - SSE -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -#if LL_VECTORIZE - -inline void LLV4Matrix4::lerp(const LLV4Matrix4 &a, const LLV4Matrix4 &b, const F32 &w) -{ - __m128 vw = _mm_set1_ps(w); - mV[VX] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VX], a.mV[VX]), vw), a.mV[VX]); // ( b - a ) * w + a - mV[VY] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VY], a.mV[VY]), vw), a.mV[VY]); - mV[VZ] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VZ], a.mV[VZ]), vw), a.mV[VZ]); - mV[VW] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VW], a.mV[VW]), vw), a.mV[VW]); -} - -inline void LLV4Matrix4::multiply(const LLVector3 &a, LLVector3& o) const -{ - LLV4Vector3 j; - j.v = _mm_add_ps(mV[VW], _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX])); // ( ax * vx ) + vw - j.v = _mm_add_ps(j.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY])); - j.v = _mm_add_ps(j.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ])); - o.setVec(j.mV); -} - -inline void LLV4Matrix4::multiply(const LLVector3 &a, LLV4Vector3& o) const -{ - o.v = _mm_add_ps(mV[VW], _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX])); // ( ax * vx ) + vw - o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY])); - o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ])); -} - -inline const LLV4Matrix4& LLV4Matrix4::translate(const LLV4Vector3 &vec) -{ - mV[VW] = _mm_add_ps(mV[VW], vec.v); - return (*this); -} - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// LLV4Matrix4 -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -#else - -inline void LLV4Matrix4::lerp(const LLV4Matrix4 &a, const LLV4Matrix4 &b, const F32 &w) -{ - mMatrix[VX][VX] = llv4lerp(a.mMatrix[VX][VX], b.mMatrix[VX][VX], w); - mMatrix[VX][VY] = llv4lerp(a.mMatrix[VX][VY], b.mMatrix[VX][VY], w); - mMatrix[VX][VZ] = llv4lerp(a.mMatrix[VX][VZ], b.mMatrix[VX][VZ], w); - - mMatrix[VY][VX] = llv4lerp(a.mMatrix[VY][VX], b.mMatrix[VY][VX], w); - mMatrix[VY][VY] = llv4lerp(a.mMatrix[VY][VY], b.mMatrix[VY][VY], w); - mMatrix[VY][VZ] = llv4lerp(a.mMatrix[VY][VZ], b.mMatrix[VY][VZ], w); - - mMatrix[VZ][VX] = llv4lerp(a.mMatrix[VZ][VX], b.mMatrix[VZ][VX], w); - mMatrix[VZ][VY] = llv4lerp(a.mMatrix[VZ][VY], b.mMatrix[VZ][VY], w); - mMatrix[VZ][VZ] = llv4lerp(a.mMatrix[VZ][VZ], b.mMatrix[VZ][VZ], w); - - mMatrix[VW][VX] = llv4lerp(a.mMatrix[VW][VX], b.mMatrix[VW][VX], w); - mMatrix[VW][VY] = llv4lerp(a.mMatrix[VW][VY], b.mMatrix[VW][VY], w); - mMatrix[VW][VZ] = llv4lerp(a.mMatrix[VW][VZ], b.mMatrix[VW][VZ], w); -} - -inline void LLV4Matrix4::multiply(const LLVector3 &a, LLVector3& o) const -{ - o.setVec( a.mV[VX] * mMatrix[VX][VX] + - a.mV[VY] * mMatrix[VY][VX] + - a.mV[VZ] * mMatrix[VZ][VX] + - mMatrix[VW][VX], - - a.mV[VX] * mMatrix[VX][VY] + - a.mV[VY] * mMatrix[VY][VY] + - a.mV[VZ] * mMatrix[VZ][VY] + - mMatrix[VW][VY], - - a.mV[VX] * mMatrix[VX][VZ] + - a.mV[VY] * mMatrix[VY][VZ] + - a.mV[VZ] * mMatrix[VZ][VZ] + - mMatrix[VW][VZ]); -} - -inline void LLV4Matrix4::multiply(const LLVector3 &a, LLV4Vector3& o) const -{ - o.setVec( a.mV[VX] * mMatrix[VX][VX] + - a.mV[VY] * mMatrix[VY][VX] + - a.mV[VZ] * mMatrix[VZ][VX] + - mMatrix[VW][VX], - - a.mV[VX] * mMatrix[VX][VY] + - a.mV[VY] * mMatrix[VY][VY] + - a.mV[VZ] * mMatrix[VZ][VY] + - mMatrix[VW][VY], - - a.mV[VX] * mMatrix[VX][VZ] + - a.mV[VY] * mMatrix[VY][VZ] + - a.mV[VZ] * mMatrix[VZ][VZ] + - mMatrix[VW][VZ]); -} - -inline const LLV4Matrix4& LLV4Matrix4::translate(const LLV4Vector3 &vec) -{ - mMatrix[3][0] += vec.mV[0]; - mMatrix[3][1] += vec.mV[1]; - mMatrix[3][2] += vec.mV[2]; - return (*this); -} - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// LLV4Matrix4 -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -#endif - -inline const LLV4Matrix4& LLV4Matrix4::operator=(const LLMatrix4& a) -{ - memcpy(mMatrix, a.mMatrix, sizeof(F32) * 16 ); - return *this; -} - -inline const LLV4Matrix4& LLV4Matrix4::transpose() -{ -#if LL_VECTORIZE && defined(_MM_TRANSPOSE4_PS) - _MM_TRANSPOSE4_PS(mV[VX], mV[VY], mV[VZ], mV[VW]); -#else - LLV4Matrix4 mat; - mat.mMatrix[0][0] = mMatrix[0][0]; - mat.mMatrix[1][0] = mMatrix[0][1]; - mat.mMatrix[2][0] = mMatrix[0][2]; - mat.mMatrix[3][0] = mMatrix[0][3]; - - mat.mMatrix[0][1] = mMatrix[1][0]; - mat.mMatrix[1][1] = mMatrix[1][1]; - mat.mMatrix[2][1] = mMatrix[1][2]; - mat.mMatrix[3][1] = mMatrix[1][3]; - - mat.mMatrix[0][2] = mMatrix[2][0]; - mat.mMatrix[1][2] = mMatrix[2][1]; - mat.mMatrix[2][2] = mMatrix[2][2]; - mat.mMatrix[3][2] = mMatrix[2][3]; - - mat.mMatrix[0][3] = mMatrix[3][0]; - mat.mMatrix[1][3] = mMatrix[3][1]; - mat.mMatrix[2][3] = mMatrix[3][2]; - mat.mMatrix[3][3] = mMatrix[3][3]; - - *this = mat; -#endif - return *this; -} - -inline const LLV4Matrix4& LLV4Matrix4::translate(const LLVector3 &vec) -{ - mMatrix[3][0] += vec.mV[0]; - mMatrix[3][1] += vec.mV[1]; - mMatrix[3][2] += vec.mV[2]; - return (*this); -} - -inline LLVector3 operator*(const LLVector3 &a, const LLV4Matrix4 &b) -{ - return LLVector3(a.mV[VX] * b.mMatrix[VX][VX] + - a.mV[VY] * b.mMatrix[VY][VX] + - a.mV[VZ] * b.mMatrix[VZ][VX] + - b.mMatrix[VW][VX], - - a.mV[VX] * b.mMatrix[VX][VY] + - a.mV[VY] * b.mMatrix[VY][VY] + - a.mV[VZ] * b.mMatrix[VZ][VY] + - b.mMatrix[VW][VY], - - a.mV[VX] * b.mMatrix[VX][VZ] + - a.mV[VY] * b.mMatrix[VY][VZ] + - a.mV[VZ] * b.mMatrix[VZ][VZ] + - b.mMatrix[VW][VZ]); -} - - -#endif diff --git a/indra/llmath/llv4vector3.h b/indra/llmath/llv4vector3.h deleted file mode 100644 index a340d53f5a..0000000000 --- a/indra/llmath/llv4vector3.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @file llviewerjointmesh.cpp - * @brief LLV4* class header file - vector processor enabled math - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLV4VECTOR3_H -#define LL_LLV4VECTOR3_H - -#include "llv4math.h" - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// LLV4Vector3 -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -LL_LLV4MATH_ALIGN_PREFIX - -class LLV4Vector3 -{ -public: - union { - F32 mV[LLV4_NUM_AXIS]; - V4F32 v; - }; - - enum { - ALIGNMENT = 16 - }; - - void setVec(F32 x, F32 y, F32 z); - void setVec(F32 a); -} - -LL_LLV4MATH_ALIGN_POSTFIX; - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// LLV4Vector3 -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -inline void LLV4Vector3::setVec(F32 x, F32 y, F32 z) -{ - mV[VX] = x; - mV[VY] = y; - mV[VZ] = z; -} - -inline void LLV4Vector3::setVec(F32 a) -{ -#if LL_VECTORIZE - v = _mm_set1_ps(a); -#else - setVec(a, a, a); -#endif -} - -#endif diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index fa74804314..0467a93dfe 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -540,9 +540,6 @@ set(viewer_SOURCE_FILES llviewerjoint.cpp llviewerjointattachment.cpp llviewerjointmesh.cpp - llviewerjointmesh_sse.cpp - llviewerjointmesh_sse2.cpp - llviewerjointmesh_vec.cpp llviewerjoystick.cpp llviewerkeyboard.cpp llviewerlayer.cpp @@ -624,20 +621,6 @@ set(viewer_SOURCE_FILES set(VIEWER_BINARY_NAME "secondlife-bin" CACHE STRING "The name of the viewer executable to create.") -if (LINUX) - # We can't set these flags for Darwin, because they get passed to - # the PPC compiler. Ugh. - - set_source_files_properties( - llviewerjointmesh_sse.cpp - PROPERTIES COMPILE_FLAGS "-msse -mfpmath=sse" - ) - set_source_files_properties( - llviewerjointmesh_sse2.cpp - PROPERTIES COMPILE_FLAGS "-msse2 -mfpmath=sse" - ) -endif (LINUX) - set(viewer_HEADER_FILES CMakeLists.txt ViewerInstall.cmake diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index d057323e51..d07efa6a37 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -12202,50 +12202,6 @@ Value 1 - VectorizeEnable - - Comment - Enable general vector operations and data alignment. - Persist - 1 - Type - Boolean - Value - 0 - - VectorizePerfTest - - Comment - Test SSE/vectorization performance and choose fastest version. - Persist - 1 - Type - Boolean - Value - 1 - - VectorizeProcessor - - Comment - 0=Compiler Default, 1=SSE, 2=SSE2, autodetected - Persist - 0 - Type - U32 - Value - 0 - - VectorizeSkin - - Comment - Enable vector operations for avatar skinning. - Persist - 1 - Type - Boolean - Value - 1 - VelocityInterpolate Comment diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index dfb677dc2c..bab99e8a54 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -558,42 +558,6 @@ static void settings_modify() gDebugGL = gSavedSettings.getBOOL("RenderDebugGL") || gDebugSession; gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline"); gAuditTexture = gSavedSettings.getBOOL("AuditTexture"); -#if LL_VECTORIZE - if (gSysCPU.hasAltivec()) - { - gSavedSettings.setBOOL("VectorizeEnable", TRUE ); - gSavedSettings.setU32("VectorizeProcessor", 0 ); - } - else - if (gSysCPU.hasSSE2()) - { - gSavedSettings.setBOOL("VectorizeEnable", TRUE ); - gSavedSettings.setU32("VectorizeProcessor", 2 ); - } - else - if (gSysCPU.hasSSE()) - { - gSavedSettings.setBOOL("VectorizeEnable", TRUE ); - gSavedSettings.setU32("VectorizeProcessor", 1 ); - } - else - { - // Don't bother testing or running if CPU doesn't support it. JC - gSavedSettings.setBOOL("VectorizePerfTest", FALSE ); - gSavedSettings.setBOOL("VectorizeEnable", FALSE ); - gSavedSettings.setU32("VectorizeProcessor", 0 ); - gSavedSettings.setBOOL("VectorizeSkin", FALSE); - } -#else - // This build target doesn't support SSE, don't test/run. - gSavedSettings.setBOOL("VectorizePerfTest", FALSE ); - gSavedSettings.setBOOL("VectorizeEnable", FALSE ); - gSavedSettings.setU32("VectorizeProcessor", 0 ); - gSavedSettings.setBOOL("VectorizeSkin", FALSE); - - // disable fullscreen mode, unsupported - //gSavedSettings.setBOOL("WindowFullScreen", FALSE); -#endif } class LLFastTimerLogThread : public LLThread @@ -877,8 +841,6 @@ bool LLAppViewer::init() LLAgent::parseTeleportMessages("teleport_strings.xml"); - LLViewerJointMesh::updateVectorize(); - // load MIME type -> media impl mappings std::string mime_types_name; #if LL_DARWIN diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 03d765eaee..73e4d11d7b 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -452,12 +452,6 @@ bool handleEffectColorChanged(const LLSD& newvalue) return true; } -bool handleVectorizeChanged(const LLSD& newvalue) -{ - LLViewerJointMesh::updateVectorize(); - return true; -} - bool handleHighResSnapshotChanged(const LLSD& newvalue) { // High Res Snapshot active, must uncheck RenderUIInSnapshot @@ -692,10 +686,6 @@ void settings_setup_listeners() gSavedSettings.getControl("UserLogFile")->getSignal()->connect(boost::bind(&handleLogFileChanged, _2)); gSavedSettings.getControl("RenderHideGroupTitle")->getSignal()->connect(boost::bind(handleHideGroupTitleChanged, _2)); gSavedSettings.getControl("HighResSnapshot")->getSignal()->connect(boost::bind(handleHighResSnapshotChanged, _2)); - gSavedSettings.getControl("VectorizePerfTest")->getSignal()->connect(boost::bind(&handleVectorizeChanged, _2)); - gSavedSettings.getControl("VectorizeEnable")->getSignal()->connect(boost::bind(&handleVectorizeChanged, _2)); - gSavedSettings.getControl("VectorizeProcessor")->getSignal()->connect(boost::bind(&handleVectorizeChanged, _2)); - gSavedSettings.getControl("VectorizeSkin")->getSignal()->connect(boost::bind(&handleVectorizeChanged, _2)); gSavedSettings.getControl("EnableVoiceChat")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); gSavedSettings.getControl("PTTCurrentlyEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); gSavedSettings.getControl("PushToTalkButton")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index 3e20abecb7..b18323bed0 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -766,7 +766,7 @@ BOOL LLViewerJointMesh::updateLOD(F32 pixel_area, BOOL activate) } // static -void LLViewerJointMesh::updateGeometryOriginal(LLFace *mFace, LLPolyMesh *mMesh) +void LLViewerJointMesh::updateGeometry(LLFace *mFace, LLPolyMesh *mMesh) { LLStrider o_vertices; LLStrider o_normals; @@ -832,50 +832,6 @@ static F64 sUpdateGeometryRunAvgOn[10]; static U32 sUpdateGeometryRunCount = 0 ; static U32 sUpdateGeometryCalls = 0 ; static U32 sUpdateGeometryLastProcessor = 0 ; -static BOOL sVectorizePerfTest = FALSE; -static U32 sVectorizeProcessor = 0; - -//static -void (*LLViewerJointMesh::sUpdateGeometryFunc)(LLFace* face, LLPolyMesh* mesh); - -//static -void LLViewerJointMesh::updateVectorize() -{ - sVectorizePerfTest = gSavedSettings.getBOOL("VectorizePerfTest"); - sVectorizeProcessor = gSavedSettings.getU32("VectorizeProcessor"); - BOOL vectorizeEnable = gSavedSettings.getBOOL("VectorizeEnable"); - BOOL vectorizeSkin = gSavedSettings.getBOOL("VectorizeSkin"); - - std::string vp; - switch(sVectorizeProcessor) - { - case 2: vp = "SSE2"; break; // *TODO: replace the magic #s - case 1: vp = "SSE"; break; - default: vp = "COMPILER DEFAULT"; break; - } - LL_INFOS("AppInit") << "Vectorization : " << ( vectorizeEnable ? "ENABLED" : "DISABLED" ) << LL_ENDL ; - LL_INFOS("AppInit") << "Vector Processor : " << vp << LL_ENDL ; - LL_INFOS("AppInit") << "Vectorized Skinning : " << ( vectorizeSkin ? "ENABLED" : "DISABLED" ) << LL_ENDL ; - if(vectorizeEnable && vectorizeSkin) - { - switch(sVectorizeProcessor) - { - case 2: - sUpdateGeometryFunc = &updateGeometrySSE2; - break; - case 1: - sUpdateGeometryFunc = &updateGeometrySSE; - break; - default: - sUpdateGeometryFunc = &updateGeometryVectorized; - break; - } - } - else - { - sUpdateGeometryFunc = &updateGeometryOriginal; - } -} void LLViewerJointMesh::updateJointGeometry() { @@ -889,129 +845,8 @@ void LLViewerJointMesh::updateJointGeometry() return; } - if (!sVectorizePerfTest) - { - // Once we've measured performance, just run the specified - // code version. - if(sUpdateGeometryFunc == updateGeometryOriginal) - uploadJointMatrices(); - sUpdateGeometryFunc(mFace, mMesh); - } - else - { - // At startup, measure the amount of time in skinning and choose - // the fastest one. - LLTimer ug_timer ; - - if (sUpdateGeometryCallPointer) - { - if(sUpdateGeometryFunc == updateGeometryOriginal) - uploadJointMatrices(); - // call accelerated version for this processor - sUpdateGeometryFunc(mFace, mMesh); - } - else - { - uploadJointMatrices(); - updateGeometryOriginal(mFace, mMesh); - } - - sUpdateGeometryElapsedTime += ug_timer.getElapsedTimeF64(); - ++sUpdateGeometryCalls; - if(0 != (sUpdateGeometryCalls & UPDATE_GEOMETRY_CALL_OVERFLOW)) - { - F64 time_since_app_start = ug_timer.getElapsedSeconds(); - if(sUpdateGeometryGlobalTime == 0.0 - || sUpdateGeometryLastProcessor != sVectorizeProcessor) - { - sUpdateGeometryGlobalTime = time_since_app_start; - sUpdateGeometryElapsedTime = 0; - sUpdateGeometryCalls = 0; - sUpdateGeometryRunCount = 0; - sUpdateGeometryLastProcessor = sVectorizeProcessor; - sUpdateGeometryCallPointer = false; - return; - } - F64 percent_time_in_function = - ( sUpdateGeometryElapsedTime * 100.0 ) / ( time_since_app_start - sUpdateGeometryGlobalTime ) ; - sUpdateGeometryGlobalTime = time_since_app_start; - if (!sUpdateGeometryCallPointer) - { - // First set of run data is with vectorization off. - sUpdateGeometryCallPointer = true; - llinfos << "profile (avg of " << sUpdateGeometryCalls << " samples) = " - << "vectorize off " << percent_time_in_function - << "% of time with " - << (sUpdateGeometryElapsedTime / (F64)sUpdateGeometryCalls) - << " seconds per call " - << llendl; - sUpdateGeometryRunAvgOff[sUpdateGeometryRunCount] = percent_time_in_function; - sUpdateGeometryElapsedTimeOff += sUpdateGeometryElapsedTime; - sUpdateGeometryCalls = 0; - } - else - { - // Second set of run data is with vectorization on. - sUpdateGeometryCallPointer = false; - llinfos << "profile (avg of " << sUpdateGeometryCalls << " samples) = " - << "VEC on " << percent_time_in_function - << "% of time with " - << (sUpdateGeometryElapsedTime / (F64)sUpdateGeometryCalls) - << " seconds per call " - << llendl; - sUpdateGeometryRunAvgOn[sUpdateGeometryRunCount] = percent_time_in_function ; - sUpdateGeometryElapsedTimeOn += sUpdateGeometryElapsedTime; - - sUpdateGeometryCalls = 0; - sUpdateGeometryRunCount++; - F64 a = 0.0, b = 0.0; - for(U32 i = 0; i 0.0) - { - llinfos << "Vectorization improves avatar skinning performance, " - << "keeping on for future runs." - << llendl; - gSavedSettings.setBOOL("VectorizeSkin", TRUE); - } - else - { - // SIMD decreases performance, fall back to original code - llinfos << "Vectorization decreases avatar skinning performance, " - << "switching back to original code." - << llendl; - - gSavedSettings.setBOOL("VectorizeSkin", FALSE); - } - } - } - sUpdateGeometryElapsedTime = 0.0f; - } - } + uploadJointMatrices(); + updateGeometry(mFace, mMesh); } void LLViewerJointMesh::dump() diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h index cab1205d61..0191f0cae8 100644 --- a/indra/newview/llviewerjointmesh.h +++ b/indra/newview/llviewerjointmesh.h @@ -143,23 +143,10 @@ public: /*virtual*/ BOOL isAnimatable() const { return FALSE; } - static void updateVectorize(); // Update globals when settings variables change - private: - // Avatar vertex skinning is a significant performance issue on computers - // with avatar vertex programs turned off (for example, most Macs). We - // therefore have custom versions that use SIMD instructions. - // - // These functions require compiler options for SSE2, SSE, or neither, and - // hence are contained in separate individual .cpp files. JC - static void updateGeometryOriginal(LLFace* face, LLPolyMesh* mesh); - // generic vector code, used for Altivec - static void updateGeometryVectorized(LLFace* face, LLPolyMesh* mesh); - static void updateGeometrySSE(LLFace* face, LLPolyMesh* mesh); - static void updateGeometrySSE2(LLFace* face, LLPolyMesh* mesh); - - // Use a fuction pointer to indicate which version we are running. - static void (*sUpdateGeometryFunc)(LLFace* face, LLPolyMesh* mesh); + + //copy mesh into given face's vertex buffer, applying current animation pose + static void updateGeometry(LLFace* face, LLPolyMesh* mesh); private: // Allocate skin data diff --git a/indra/newview/llviewerjointmesh_sse.cpp b/indra/newview/llviewerjointmesh_sse.cpp deleted file mode 100644 index 00ed47e091..0000000000 --- a/indra/newview/llviewerjointmesh_sse.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/** - * @file llviewerjointmesh_sse.cpp - * @brief SSE vectorized joint skinning code, only used when video card does - * not support avatar vertex programs. - * - * *NOTE: Disabled on Windows builds. See llv4math.h for details. - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -//----------------------------------------------------------------------------- -// Header Files -//----------------------------------------------------------------------------- - -#include "llviewerprecompiledheaders.h" - -#include "llviewerjointmesh.h" - -// project includes -#include "llface.h" -#include "llpolymesh.h" - -// library includes -#include "lldarray.h" -#include "llv4math.h" // for LL_VECTORIZE -#include "llv4matrix3.h" -#include "llv4matrix4.h" -#include "v3math.h" - - -#if LL_VECTORIZE - -inline void matrix_translate(LLV4Matrix4& m, const LLMatrix4* w, const LLVector3& j) -{ - m.mV[VX] = _mm_loadu_ps(w->mMatrix[VX]); - m.mV[VY] = _mm_loadu_ps(w->mMatrix[VY]); - m.mV[VZ] = _mm_loadu_ps(w->mMatrix[VZ]); - m.mV[VW] = _mm_loadu_ps(w->mMatrix[VW]); - m.mV[VW] = _mm_add_ps(m.mV[VW], _mm_mul_ps(_mm_set1_ps(j.mV[VX]), m.mV[VX])); // ( ax * vx ) + vw - m.mV[VW] = _mm_add_ps(m.mV[VW], _mm_mul_ps(_mm_set1_ps(j.mV[VY]), m.mV[VY])); - m.mV[VW] = _mm_add_ps(m.mV[VW], _mm_mul_ps(_mm_set1_ps(j.mV[VZ]), m.mV[VZ])); -} - -// static -void LLViewerJointMesh::updateGeometrySSE(LLFace *face, LLPolyMesh *mesh) -{ - // This cannot be a file-level static because it will be initialized - // before main() using SSE code, which will crash on non-SSE processors. - static LLV4Matrix4 sJointMat[32]; - LLDynamicArray& joint_data = mesh->getReferenceMesh()->mJointRenderData; - - //upload joint pivots/matrices - for(S32 j = 0, jend = joint_data.count(); j < jend ; ++j ) - { - matrix_translate(sJointMat[j], joint_data[j]->mWorldMatrix, - joint_data[j]->mSkinJoint ? - joint_data[j]->mSkinJoint->mRootToJointSkinOffset - : joint_data[j+1]->mSkinJoint->mRootToParentJointSkinOffset); - } - - F32 weight = F32_MAX; - LLV4Matrix4 blend_mat; - - LLStrider o_vertices; - LLStrider o_normals; - - LLVertexBuffer *buffer = face->getVertexBuffer(); - buffer->getVertexStrider(o_vertices, mesh->mFaceVertexOffset); - buffer->getNormalStrider(o_normals, mesh->mFaceVertexOffset); - - const F32* weights = mesh->getWeights(); - const LLVector3* coords = (const LLVector3*)mesh->getCoords(); - const LLVector3* normals = (const LLVector3*)mesh->getNormals(); - for (U32 index = 0, index_end = mesh->getNumVertices(); index < index_end; ++index) - { - if( weight != weights[index]) - { - S32 joint = llfloor(weight = weights[index]); - blend_mat.lerp(sJointMat[joint], sJointMat[joint+1], weight - joint); - } - blend_mat.multiply(coords[index], o_vertices[index]); - ((LLV4Matrix3)blend_mat).multiply(normals[index], o_normals[index]); - } - - buffer->flush(); -} - -#else - -void LLViewerJointMesh::updateGeometrySSE(LLFace *face, LLPolyMesh *mesh) -{ - LLViewerJointMesh::updateGeometryVectorized(face, mesh); -} - -#endif diff --git a/indra/newview/llviewerjointmesh_sse2.cpp b/indra/newview/llviewerjointmesh_sse2.cpp deleted file mode 100644 index c2296dd569..0000000000 --- a/indra/newview/llviewerjointmesh_sse2.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/** - * @file llviewerjointmesh_sse2.cpp - * @brief SSE vectorized joint skinning code, only used when video card does - * not support avatar vertex programs. - * - * *NOTE: Disabled on Windows builds. See llv4math.h for details. - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -// Visual Studio required settings for this file: -// Precompiled Headers OFF -// Code Generation: SSE2 - -//----------------------------------------------------------------------------- -// Header Files -//----------------------------------------------------------------------------- - -#include "llviewerprecompiledheaders.h" - -#include "llviewerjointmesh.h" - -// project includes -#include "llface.h" -#include "llpolymesh.h" - -// library includes -#include "lldarray.h" -#include "llstrider.h" -#include "llv4math.h" // for LL_VECTORIZE -#include "llv4matrix3.h" -#include "llv4matrix4.h" -#include "m4math.h" -#include "v3math.h" - - -#if LL_VECTORIZE - - -inline void matrix_translate(LLV4Matrix4& m, const LLMatrix4* w, const LLVector3& j) -{ - m.mV[VX] = _mm_loadu_ps(w->mMatrix[VX]); - m.mV[VY] = _mm_loadu_ps(w->mMatrix[VY]); - m.mV[VZ] = _mm_loadu_ps(w->mMatrix[VZ]); - m.mV[VW] = _mm_loadu_ps(w->mMatrix[VW]); - m.mV[VW] = _mm_add_ps(m.mV[VW], _mm_mul_ps(_mm_set1_ps(j.mV[VX]), m.mV[VX])); // ( ax * vx ) + vw - m.mV[VW] = _mm_add_ps(m.mV[VW], _mm_mul_ps(_mm_set1_ps(j.mV[VY]), m.mV[VY])); - m.mV[VW] = _mm_add_ps(m.mV[VW], _mm_mul_ps(_mm_set1_ps(j.mV[VZ]), m.mV[VZ])); -} - -// static -void LLViewerJointMesh::updateGeometrySSE2(LLFace *face, LLPolyMesh *mesh) -{ - // This cannot be a file-level static because it will be initialized - // before main() using SSE code, which will crash on non-SSE processors. - static LLV4Matrix4 sJointMat[32]; - LLDynamicArray& joint_data = mesh->getReferenceMesh()->mJointRenderData; - - //upload joint pivots/matrices - for(S32 j = 0, jend = joint_data.count(); j < jend ; ++j ) - { - matrix_translate(sJointMat[j], joint_data[j]->mWorldMatrix, - joint_data[j]->mSkinJoint ? - joint_data[j]->mSkinJoint->mRootToJointSkinOffset - : joint_data[j+1]->mSkinJoint->mRootToParentJointSkinOffset); - } - - F32 weight = F32_MAX; - LLV4Matrix4 blend_mat; - - LLStrider o_vertices; - LLStrider o_normals; - - LLVertexBuffer *buffer = face->getVertexBuffer(); - buffer->getVertexStrider(o_vertices, mesh->mFaceVertexOffset); - buffer->getNormalStrider(o_normals, mesh->mFaceVertexOffset); - - const F32* weights = mesh->getWeights(); - const LLVector3* coords = (const LLVector3*)mesh->getCoords(); - const LLVector3* normals = (const LLVector3*)mesh->getNormals(); - for (U32 index = 0, index_end = mesh->getNumVertices(); index < index_end; ++index) - { - if( weight != weights[index]) - { - S32 joint = llfloor(weight = weights[index]); - blend_mat.lerp(sJointMat[joint], sJointMat[joint+1], weight - joint); - } - blend_mat.multiply(coords[index], o_vertices[index]); - ((LLV4Matrix3)blend_mat).multiply(normals[index], o_normals[index]); - } - - //setBuffer(0) called in LLVOAvatar::renderSkinned -} - -#else - -void LLViewerJointMesh::updateGeometrySSE2(LLFace *face, LLPolyMesh *mesh) -{ - LLViewerJointMesh::updateGeometryVectorized(face, mesh); -} - -#endif diff --git a/indra/newview/llviewerjointmesh_vec.cpp b/indra/newview/llviewerjointmesh_vec.cpp deleted file mode 100644 index a8713b6f05..0000000000 --- a/indra/newview/llviewerjointmesh_vec.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/** - * @file llviewerjointmesh_vec.cpp - * @brief Compiler-generated vectorized joint skinning code, works well on - * Altivec processors (PowerPC Mac) - * - * *NOTE: See llv4math.h for notes on SSE/Altivec vector code. - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -//----------------------------------------------------------------------------- -// Header Files -//----------------------------------------------------------------------------- -#include "llviewerprecompiledheaders.h" - -#include "llviewerjointmesh.h" - -#include "llface.h" -#include "llpolymesh.h" -#include "llv4math.h" -#include "llv4matrix3.h" -#include "llv4matrix4.h" - -// Generic vectorized code, uses compiler defaults, works well for Altivec -// on PowerPC. - -// static -void LLViewerJointMesh::updateGeometryVectorized(LLFace *face, LLPolyMesh *mesh) -{ -#if 0 - static LLV4Matrix4 sJointMat[32]; - LLDynamicArray& joint_data = mesh->getReferenceMesh()->mJointRenderData; - S32 j, joint_num, joint_end = joint_data.count(); - LLV4Vector3 pivot; - - //upload joint pivots/matrices - for(j = joint_num = 0; joint_num < joint_end ; ++joint_num ) - { - LLSkinJoint *sj; - const LLMatrix4 * wm = joint_data[joint_num]->mWorldMatrix; - if (NULL == (sj = joint_data[joint_num]->mSkinJoint)) - { - sj = joint_data[++joint_num]->mSkinJoint; - ((LLV4Matrix3)(sJointMat[j] = *wm)).multiply(sj->mRootToParentJointSkinOffset, pivot); - sJointMat[j++].translate(pivot); - wm = joint_data[joint_num]->mWorldMatrix; - } - ((LLV4Matrix3)(sJointMat[j] = *wm)).multiply(sj->mRootToJointSkinOffset, pivot); - sJointMat[j++].translate(pivot); - } - - F32 weight = F32_MAX; - LLV4Matrix4 blend_mat; - - LLStrider o_vertices; - LLStrider o_normals; - - LLVertexBuffer *buffer = face->mVertexBuffer; - buffer->getVertexStrider(o_vertices, mesh->mFaceVertexOffset); - buffer->getNormalStrider(o_normals, mesh->mFaceVertexOffset); - - const F32* weights = mesh->getWeights(); - const LLVector3* coords = mesh->getCoords(); - const LLVector3* normals = mesh->getNormals(); - for (U32 index = 0, index_end = mesh->getNumVertices(); index < index_end; ++index) - { - if( weight != weights[index]) - { - S32 joint = llfloor(weight = weights[index]); - blend_mat.lerp(sJointMat[joint], sJointMat[joint+1], weight - joint); - } - blend_mat.multiply(coords[index], o_vertices[index]); - ((LLV4Matrix3)blend_mat).multiply(normals[index], o_normals[index]); - } - - buffer->flush(); -#endif -} diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 22d95563d8..9fbc28a5e1 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -1038,26 +1038,6 @@ class LLAdvancedCheckRandomizeFramerate : public view_listener_t } }; -void run_vectorize_perf_test(void *) -{ - gSavedSettings.setBOOL("VectorizePerfTest", TRUE); -} - - -//////////////////////////////// -// RUN Vectorized Perform Test// -//////////////////////////////// - - -class LLAdvancedVectorizePerfTest : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - run_vectorize_perf_test(NULL); - return true; - } -}; - /////////////////////////// //// PERIODIC SLOW FRAME // /////////////////////////// @@ -8117,7 +8097,6 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedCheckRandomizeFramerate(), "Advanced.CheckRandomizeFramerate"); view_listener_t::addMenu(new LLAdvancedTogglePeriodicSlowFrame(), "Advanced.TogglePeriodicSlowFrame"); view_listener_t::addMenu(new LLAdvancedCheckPeriodicSlowFrame(), "Advanced.CheckPeriodicSlowFrame"); - view_listener_t::addMenu(new LLAdvancedVectorizePerfTest(), "Advanced.VectorizePerfTest"); view_listener_t::addMenu(new LLAdvancedToggleFrameTest(), "Advanced.ToggleFrameTest"); view_listener_t::addMenu(new LLAdvancedCheckFrameTest(), "Advanced.CheckFrameTest"); view_listener_t::addMenu(new LLAdvancedHandleAttachedLightParticles(), "Advanced.HandleAttachedLightParticles"); -- cgit v1.3 From 76bd8cee1120ac531d56b9897b135e9c1af1bb16 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 10 Nov 2011 14:48:48 -0600 Subject: SH-2644 Fix debug display that shows selection triangle count and streaming cost --- indra/llmath/llvolume.cpp | 14 ++++++++++++-- indra/llmath/llvolume.h | 2 +- indra/newview/llselectmgr.cpp | 4 ++-- indra/newview/llselectmgr.h | 2 +- indra/newview/llviewerobject.cpp | 4 ++-- indra/newview/llviewerobject.h | 4 ++-- indra/newview/llviewerwindow.cpp | 11 +++++++---- indra/newview/llvovolume.cpp | 4 ++-- indra/newview/llvovolume.h | 2 +- 9 files changed, 30 insertions(+), 17 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 1a95f9cd46..da0fa32963 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4305,15 +4305,25 @@ S32 LLVolume::getNumTriangleIndices() const } -S32 LLVolume::getNumTriangles() const +S32 LLVolume::getNumTriangles(S32* vcount) const { U32 triangle_count = 0; + U32 vertex_count = 0; for (S32 i = 0; i < getNumVolumeFaces(); ++i) { - triangle_count += getVolumeFace(i).mNumIndices/3; + const LLVolumeFace& face = getVolumeFace(i); + triangle_count += face.mNumIndices/3; + + vertex_count += face.mNumVertices; } + + if (vcount) + { + *vcount = vertex_count; + } + return triangle_count; } diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index f0e59a3c00..afd1ec5eed 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -990,7 +990,7 @@ public: S32 getNumTriangleIndices() const; static void getLoDTriangleCounts(const LLVolumeParams& params, S32* counts); - S32 getNumTriangles() const; + S32 getNumTriangles(S32* vcount = NULL) const; void generateSilhouetteVertices(std::vector &vertices, std::vector &normals, diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 2971ee710a..830a7778ac 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -6524,7 +6524,7 @@ F32 LLObjectSelection::getSelectedObjectStreamingCost(S32* total_bytes, S32* vis return cost; } -U32 LLObjectSelection::getSelectedObjectTriangleCount() +U32 LLObjectSelection::getSelectedObjectTriangleCount(S32* vcount) { U32 count = 0; for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) @@ -6534,7 +6534,7 @@ U32 LLObjectSelection::getSelectedObjectTriangleCount() if (object) { - count += object->getTriangleCount(); + count += object->getTriangleCount(vcount); } } diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 166616e13e..87ada5ac6b 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -286,7 +286,7 @@ public: S32 getSelectedObjectRenderCost(); F32 getSelectedObjectStreamingCost(S32* total_bytes = NULL, S32* visible_bytes = NULL); - U32 getSelectedObjectTriangleCount(); + U32 getSelectedObjectTriangleCount(S32* vcount = NULL); S32 getTECount(); S32 getRootObjectCount(); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index d81e67bfe2..b8772971aa 100755 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -3219,12 +3219,12 @@ F32 LLViewerObject::getLinksetPhysicsCost() return mLinksetPhysicsCost; } -F32 LLViewerObject::getStreamingCost(S32* bytes, S32* visible_bytes) +F32 LLViewerObject::getStreamingCost(S32* bytes, S32* visible_bytes, F32* unscaled_value) const { return 0.f; } -U32 LLViewerObject::getTriangleCount() +U32 LLViewerObject::getTriangleCount(S32* vcount) const { return 0; } diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index a77725c1ca..c8152e1539 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -340,8 +340,8 @@ public: virtual void setScale(const LLVector3 &scale, BOOL damped = FALSE); - virtual F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL); - virtual U32 getTriangleCount(); + virtual F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL, F32* unscaled_value = NULL) const; + virtual U32 getTriangleCount(S32* vcount = NULL) const; virtual U32 getHighLODTriangleCount(); void setObjectCost(F32 cost); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 55834f5d99..8af83246da 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -489,6 +489,7 @@ public: { F32 cost = 0.f; S32 count = 0; + S32 vcount = 0; S32 object_count = 0; S32 total_bytes = 0; S32 visible_bytes = 0; @@ -510,7 +511,9 @@ public: S32 bytes = 0; S32 visible = 0; cost += object->getStreamingCost(&bytes, &visible); - count += object->getTriangleCount(); + S32 vt = 0; + count += object->getTriangleCount(&vt); + vcount += vt; total_bytes += bytes; visible_bytes += visible; } @@ -521,15 +524,15 @@ public: { label = "Selection"; cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectStreamingCost(&total_bytes, &visible_bytes); - count = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectTriangleCount(); + count = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectTriangleCount(&vcount); object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); } addText(xpos,ypos, llformat("%s streaming cost: %.1f", label, cost)); ypos += y_inc; - addText(xpos, ypos, llformat(" %.3f KTris, %.1f/%.1f KB, %d objects", - count/1000.f, visible_bytes/1024.f, total_bytes/1024.f, object_count)); + addText(xpos, ypos, llformat(" %.3f KTris, %.3f KVerts, %.1f/%.1f KB, %d objects", + count/1000.f, vcount/1000.f, visible_bytes/1024.f, total_bytes/1024.f, object_count)); ypos += y_inc; } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index b75a0a799a..827c5b9cb5 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3266,13 +3266,13 @@ void LLVOVolume::updateRenderComplexity() mRenderComplexity_current = 0; } -U32 LLVOVolume::getTriangleCount() const +U32 LLVOVolume::getTriangleCount(S32* vcount) const { U32 count = 0; LLVolume* volume = getVolume(); if (volume) { - count = volume->getNumTriangles(); + count = volume->getNumTriangles(vcount); } return count; diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index b6347526ee..64457975f8 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -133,7 +133,7 @@ public: U32 getRenderCost(texture_cost_t &textures) const; /*virtual*/ F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL, F32* unscaled_value = NULL) const; - /*virtual*/ U32 getTriangleCount() const; + /*virtual*/ U32 getTriangleCount(S32* vcount = NULL) const; /*virtual*/ U32 getHighLODTriangleCount(); /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face = -1, // which face to check, -1 = ALL_SIDES -- cgit v1.3 From c0b4ec6fe72d703191b28749cfd30262d131b245 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 16 Dec 2011 17:43:30 -0600 Subject: SH-2694 Fix for FPS drop when mousing over flexi objects (don't use an octree for flexi raycast) --- indra/llmath/lloctree.h | 36 ++++++++------- indra/llmath/llvolume.cpp | 85 +++++++++++++++++++++++++++++++----- indra/newview/llspatialpartition.cpp | 26 ++++++----- 3 files changed, 111 insertions(+), 36 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 3c1ae45d68..1b11e83b4a 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -80,8 +80,8 @@ public: typedef LLOctreeTraveler oct_traveler; typedef LLTreeTraveler tree_traveler; typedef typename std::set > element_list; - typedef typename std::set >::iterator element_iter; - typedef typename std::set >::const_iterator const_element_iter; + typedef typename element_list::iterator element_iter; + typedef typename element_list::const_iterator const_element_iter; typedef typename std::vector*>::iterator tree_listener_iter; typedef typename std::vector* > child_list; typedef LLTreeNode BaseType; @@ -114,6 +114,8 @@ public: mOctant = ((oct_node*) mParent)->getOctant(mCenter); } + mElementCount = 0; + clearChildren(); } @@ -219,11 +221,11 @@ public: void accept(oct_traveler* visitor) { visitor->visit(this); } virtual bool isLeaf() const { return mChild.empty(); } - U32 getElementCount() const { return mData.size(); } + U32 getElementCount() const { return mElementCount; } element_list& getData() { return mData; } const element_list& getData() const { return mData; } - U32 getChildCount() const { return mChild.size(); } + U32 getChildCount() const { return mChildCount; } oct_node* getChild(U32 index) { return mChild[index]; } const oct_node* getChild(U32 index) const { return mChild[index]; } child_list& getChildren() { return mChild; } @@ -300,17 +302,13 @@ public: if ((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius()) || (data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity))) { //it belongs here -#if LL_OCTREE_PARANOIA_CHECK //if this is a redundant insertion, error out (should never happen) - if (mData.find(data) != mData.end()) - { - llwarns << "Redundant octree insertion detected. " << data << llendl; - return false; - } -#endif + llassert(mData.find(data) == mData.end()); mData.insert(data); BaseType::insert(data); + + mElementCount = mData.size(); return true; } else @@ -346,6 +344,8 @@ public: { mData.insert(data); BaseType::insert(data); + + mElementCount = mData.size(); return true; } @@ -399,6 +399,7 @@ public: if (mData.find(data) != mData.end()) { //we have data mData.erase(data); + mElementCount = mData.size(); notifyRemoval(data); checkAlive(); return true; @@ -436,6 +437,7 @@ public: if (mData.find(data) != mData.end()) { mData.erase(data); + mElementCount = mData.size(); notifyRemoval(data); llwarns << "FOUND!" << llendl; checkAlive(); @@ -452,7 +454,7 @@ public: void clearChildren() { mChild.clear(); - + mChildCount = 0; U32* foo = (U32*) mChildMap; foo[0] = foo[1] = 0xFFFFFFFF; } @@ -512,9 +514,10 @@ public: } #endif - mChildMap[child->getOctant()] = (U8) mChild.size(); + mChildMap[child->getOctant()] = mChildCount; mChild.push_back(child); + ++mChildCount; child->setParent(this); if (!silent) @@ -534,21 +537,20 @@ public: oct_listener* listener = getOctListener(i); listener->handleChildRemoval(this, getChild(index)); } - - if (destroy) { mChild[index]->destroy(); delete mChild[index]; } mChild.erase(mChild.begin() + index); + --mChildCount; //rebuild child map U32* foo = (U32*) mChildMap; foo[0] = foo[1] = 0xFFFFFFFF; - for (U32 i = 0; i < mChild.size(); ++i) + for (U32 i = 0; i < mChildCount; ++i) { mChildMap[mChild[i]->getOctant()] = i; } @@ -601,8 +603,10 @@ protected: child_list mChild; U8 mChildMap[8]; + U32 mChildCount; element_list mData; + U32 mElementCount; }; diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index da0fa32963..0c6cf1dfae 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4617,18 +4617,83 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en genBinormals(i); } - if (!face.mOctree) - { - face.createOctree(); - } - - //LLVector4a* p = (LLVector4a*) face.mPositions; + if (isUnique()) + { //don't bother with an octree for flexi volumes + U32 tri_count = face.mNumIndices/3; + + for (U32 j = 0; j < tri_count; ++j) + { + U16 idx0 = face.mIndices[j*3+0]; + U16 idx1 = face.mIndices[j*3+1]; + U16 idx2 = face.mIndices[j*3+2]; - LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, bi_normal); - intersect.traverse(face.mOctree); - if (intersect.mHitFace) + const LLVector4a& v0 = face.mPositions[idx0]; + const LLVector4a& v1 = face.mPositions[idx1]; + const LLVector4a& v2 = face.mPositions[idx2]; + + F32 a,b,t; + + if (LLTriangleRayIntersect(v0, v1, v2, + start, dir, a, b, t)) + { + if ((t >= 0.f) && // if hit is after start + (t <= 1.f) && // and before end + (t < closest_t)) // and this hit is closer + { + closest_t = t; + hit_face = i; + + if (intersection != NULL) + { + LLVector4a intersect = dir; + intersect.mul(closest_t); + intersect.add(start); + intersection->set(intersect.getF32ptr()); + } + + + if (tex_coord != NULL) + { + LLVector2* tc = (LLVector2*) face.mTexCoords; + *tex_coord = ((1.f - a - b) * tc[idx0] + + a * tc[idx1] + + b * tc[idx2]); + + } + + if (normal!= NULL) + { + LLVector4* norm = (LLVector4*) face.mNormals; + + *normal = ((1.f - a - b) * LLVector3(norm[idx0]) + + a * LLVector3(norm[idx1]) + + b * LLVector3(norm[idx2])); + } + + if (bi_normal != NULL) + { + LLVector4* binormal = (LLVector4*) face.mBinormals; + *bi_normal = ((1.f - a - b) * LLVector3(binormal[idx0]) + + a * LLVector3(binormal[idx1]) + + b * LLVector3(binormal[idx2])); + } + } + } + } + } + else { - hit_face = i; + if (!face.mOctree) + { + face.createOctree(); + } + + LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, bi_normal); + intersect.traverse(face.mOctree); + if (intersect.mHitFace) + { + hit_face = i; + } } } } diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index fb107a302a..900f126049 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -3775,11 +3775,7 @@ void renderRaycast(LLDrawable* drawablep) for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) { const LLVolumeFace& face = volume->getVolumeFace(i); - if (!face.mOctree) - { - ((LLVolumeFace*) &face)->createOctree(); - } - + gGL.pushMatrix(); gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]); gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix); @@ -3802,9 +3798,6 @@ void renderRaycast(LLDrawable* drawablep) LLVector4a dir; dir.setSub(enda, starta); - F32 t = 1.f; - - LLRenderOctreeRaycast render(starta, dir, &t); gGL.flush(); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); @@ -3816,8 +3809,21 @@ void renderRaycast(LLDrawable* drawablep) gGL.syncMatrices(); glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices); } - - render.traverse(face.mOctree); + + if (!volume->isUnique()) + { + F32 t = 1.f; + + if (!face.mOctree) + { + ((LLVolumeFace*) &face)->createOctree(); + } + + LLRenderOctreeRaycast render(starta, dir, &t); + + render.traverse(face.mOctree); + } + gGL.popMatrix(); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } -- cgit v1.3 From 18e7f1bffd875bb933212367f0d62dfc4da871b9 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 20 Jan 2012 16:42:57 -0600 Subject: SH-2889 Add visual auto-muting controls --- indra/llmath/llvolume.cpp | 3 + indra/llmath/llvolume.h | 2 + indra/newview/app_settings/settings.xml | 22 +++++++ indra/newview/lldrawable.cpp | 10 ++++ indra/newview/llspatialpartition.cpp | 15 ++++- indra/newview/llspatialpartition.h | 18 ++++-- indra/newview/llviewermenu.cpp | 4 ++ indra/newview/llvoavatar.cpp | 20 ++++++- indra/newview/llvoavatar.h | 5 ++ indra/newview/llvovolume.cpp | 70 +++++++++++++++++++--- indra/newview/pipeline.cpp | 2 +- indra/newview/pipeline.h | 57 +++++++++--------- indra/newview/skins/default/xui/en/menu_viewer.xml | 10 ++++ 13 files changed, 193 insertions(+), 45 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 0c6cf1dfae..761fc171c4 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2078,6 +2078,7 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge mFaceMask = 0x0; mDetail = detail; mSculptLevel = -2; + mSurfaceArea = 1.f; //only calculated for sculpts, defaults to 1 for all other prims mIsMeshAssetLoaded = FALSE; mLODScaleBias.setVec(1,1,1); mHullPoints = NULL; @@ -3144,6 +3145,8 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, { F32 area = sculptGetSurfaceArea(); + mSurfaceArea = area; + const F32 SCULPT_MAX_AREA = 384.f; if (area < SCULPT_MIN_AREA || area > SCULPT_MAX_AREA) diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index afd1ec5eed..76cf9de613 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -963,6 +963,7 @@ public: S32 getNumFaces() const; S32 getNumVolumeFaces() const { return mVolumeFaces.size(); } F32 getDetail() const { return mDetail; } + F32 getSurfaceArea() const { return mSurfaceArea; } const LLVolumeParams& getParams() const { return mParams; } LLVolumeParams getCopyOfParams() const { return mParams; } const LLProfile& getProfile() const { return *mProfilep; } @@ -1065,6 +1066,7 @@ public: BOOL mUnique; F32 mDetail; S32 mSculptLevel; + F32 mSurfaceArea; //unscaled surface area BOOL mIsMeshAssetLoaded; LLVolumeParams mParams; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 1ea623791d..3acc8a2446 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9024,6 +9024,28 @@ Value 1 + RenderAutoMuteByteLimit + + Comment + Maximum bytes of attachments before an avatar is automatically visually muted (0 for no limit). + Persist + 1 + Type + U32 + Value + 0 + + RenderAutoMuteSurfaceAreaLimit + + Comment + Maximum surface area of attachments before an avatar is automatically visually muted (0 for no limit). + Persist + 1 + Type + F32 + Value + 0 + RenderUseShaderLOD Comment diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index debac9dcbf..21b21c152a 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -1077,6 +1077,7 @@ BOOL LLDrawable::isVisible() const LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask) : LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB) { + mBridge = this; mDrawable = root; root->setSpatialBridge(this); @@ -1105,6 +1106,15 @@ LLSpatialBridge::~LLSpatialBridge() { group->mSpatialPartition->remove(this, group); } + + //delete octree here so listeners will still be able to access bridge specific state + destroyTree(); +} + +void LLSpatialBridge::destroyTree() +{ + delete mOctree; + mOctree = NULL; } void LLSpatialBridge::updateSpatialExtents() diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 4aa5f32d8a..5d196a465f 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -1187,6 +1187,8 @@ void LLSpatialGroup::clearOcclusionState(U32 state, S32 mode) LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : mState(0), + mGeometryBytes(0), + mSurfaceArea(0.f), mBuilt(0.f), mOctreeNode(node), mSpatialPartition(part), @@ -1412,6 +1414,17 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node) } } + //clean up avatar attachment stats + LLSpatialBridge* bridge = mSpatialPartition->asBridge(); + if (bridge) + { + if (bridge->mAvatar.notNull()) + { + bridge->mAvatar->mAttachmentGeometryBytes -= mGeometryBytes; + bridge->mAvatar->mAttachmentSurfaceArea -= mSurfaceArea; + } + } + clearDrawMap(); mVertexBuffer = NULL; mBufferMap.clear(); @@ -1767,7 +1780,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) //============================================== LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage) -: mRenderByGroup(render_by_group) +: mRenderByGroup(render_by_group), mBridge(NULL) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); mOcclusionEnabled = TRUE; diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 899547ae4d..6c14ecf452 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -405,6 +405,9 @@ public: bridge_list_t mBridgeList; buffer_map_t mBufferMap; //used by volume buffers to attempt to reuse vertex buffers + U32 mGeometryBytes; //used by volumes to track how many bytes of geometry data are in this node + F32 mSurfaceArea; //used by volumes to track estimated surface area of geometry in this node + F32 mBuilt; OctreeNode* mOctreeNode; LLSpatialPartition* mSpatialPartition; @@ -474,8 +477,8 @@ public: BOOL isVisible(const LLVector3& v); bool isHUDPartition() ; - virtual LLSpatialBridge* asBridge() { return NULL; } - virtual BOOL isBridge() { return asBridge() != NULL; } + LLSpatialBridge* asBridge() { return mBridge; } + BOOL isBridge() { return asBridge() != NULL; } void renderPhysicsShapes(); void renderDebug(); @@ -487,6 +490,9 @@ public: public: LLSpatialGroup::OctreeNode* mOctree; + LLSpatialBridge* mBridge; // NULL for non-LLSpatialBridge instances, otherwise, mBridge == this + // use a pointer instead of making "isBridge" and "asBridge" virtual so it's safe + // to call asBridge() from the destructor BOOL mOcclusionEnabled; // if TRUE, occlusion culling is performed BOOL mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane U32 mBufferUsage; @@ -511,8 +517,9 @@ public: LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask); - virtual BOOL isSpatialBridge() const { return TRUE; } + void destroyTree(); + virtual BOOL isSpatialBridge() const { return TRUE; } virtual void updateSpatialExtents(); virtual void updateBinRadius(); virtual void setVisible(LLCamera& camera_in, std::vector* results = NULL, BOOL for_select = FALSE); @@ -523,11 +530,12 @@ public: virtual void shiftPos(const LLVector4a& vec); virtual void cleanupReferences(); virtual LLSpatialPartition* asPartition() { return this; } - virtual LLSpatialBridge* asBridge() { return this; } - + virtual LLCamera transformCamera(LLCamera& camera); LLDrawable* mDrawable; + LLPointer mAvatar; + }; class LLCullResult diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 0104d35e53..e6619e3e08 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -947,6 +947,10 @@ U32 info_display_from_string(std::string info_display) { return LLPipeline::RENDER_DEBUG_COMPOSITION; } + else if ("attachment bytes" == info_display) + { + return LLPipeline::RENDER_DEBUG_ATTACHMENT_BYTES; + } else if ("glow" == info_display) { return LLPipeline::RENDER_DEBUG_GLOW; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 68637a7ed9..bc7f5a9744 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -651,6 +651,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, LLViewerObject(id, pcode, regionp), mIsDummy(FALSE), mSpecialRenderMode(0), + mAttachmentGeometryBytes(0), + mAttachmentSurfaceArea(0.f), mTurning(FALSE), mPelvisToFoot(0.f), mLastSkeletonSerialNum( 0 ), @@ -3363,6 +3365,16 @@ void LLVOAvatar::slamPosition() mRoot.updateWorldMatrixChildren(); } +bool LLVOAvatar::isVisuallyMuted() +{ + static LLCachedControl max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit"); + static LLCachedControl max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit"); + + return LLMuteList::getInstance()->isMuted(getID()) || + (mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) || + (mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f); +} + //------------------------------------------------------------------------ // updateCharacter() // called on both your avatar and other avatars @@ -3429,8 +3441,9 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) size.setSub(ext[1],ext[0]); F32 mag = size.getLength3().getF32()*0.5f; + F32 impostor_area = 256.f*512.f*(8.125f - LLVOAvatar::sLODFactor*8.f); - if (LLMuteList::getInstance()->isMuted(getID())) + if (isVisuallyMuted()) { // muted avatars update at 16 hz mUpdatePeriod = 16; } @@ -8333,6 +8346,11 @@ void LLVOAvatar::idleUpdateRenderCost() static std::set all_textures; + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_ATTACHMENT_BYTES)) + { //set debug text to attachment geometry bytes here so render cost will override + setDebugText(llformat("%.1f KB, %.2f m^2", mAttachmentGeometryBytes/1024.f, mAttachmentSurfaceArea)); + } + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME)) { return; diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 59796370ae..4cd61cecf9 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -380,6 +380,8 @@ private: public: U32 renderImpostor(LLColor4U color = LLColor4U(255,255,255,255), S32 diffuse_channel = 0); + bool isVisuallyMuted(); + U32 renderRigid(); U32 renderSkinned(EAvatarRenderPass pass); F32 getLastSkinTime() { return mLastSkinTime; } @@ -391,6 +393,9 @@ public: static void restoreGL(); BOOL mIsDummy; // for special views S32 mSpecialRenderMode; // special lighting + U32 mAttachmentGeometryBytes; //number of bytes in attached geometry + F32 mAttachmentSurfaceArea; //estimated surface area of attachments + private: bool shouldAlphaMask(); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index e68fd2697a..7492a06784 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4097,6 +4097,32 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB); + LLVOAvatar* pAvatarVO = NULL; + + LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); + if (bridge) + { + if (bridge->mAvatar.isNull()) + { + LLViewerObject* vobj = bridge->mDrawable->getVObj(); + if (vobj) + { + bridge->mAvatar = vobj->getAvatar(); + } + } + + pAvatarVO = bridge->mAvatar; + } + + if (pAvatarVO) + { + pAvatarVO->mAttachmentGeometryBytes -= group->mGeometryBytes; + pAvatarVO->mAttachmentSurfaceArea -= group->mSurfaceArea; + } + + group->mGeometryBytes = 0; + group->mSurfaceArea = 0; + group->clearDrawMap(); mFaceList.clear(); @@ -4133,12 +4159,24 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) LLVOVolume* vobj = drawablep->getVOVolume(); + if (!vobj) + { + continue; + } + if (vobj->isMesh() && (vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled())) { continue; } + LLVolume* volume = vobj->getVolume(); + if (volume) + { + const LLVector3& scale = vobj->getScale(); + group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]); + } + llassert_always(vobj); vobj->updateTextureVirtualSize(true); vobj->preRebuild(); @@ -4183,7 +4221,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) //Determine if we've received skininfo that contains an //alternate bind matrix - if it does then apply the translational component //to the joints of the avatar. - LLVOAvatar* pAvatarVO = vobj->getAvatar(); bool pelvisGotSet = false; if ( pAvatarVO ) @@ -4253,13 +4290,16 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (type == LLDrawPool::POOL_ALPHA) { - if (te->getFullbright()) + if (te->getColor().mV[3] > 0.f) { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA); - } - else - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA); + if (te->getFullbright()) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA); + } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA); + } } } else if (te->getShiny()) @@ -4392,8 +4432,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } else { - drawablep->setState(LLDrawable::HAS_ALPHA); - alpha_faces.push_back(facep); + if (te->getColor().mV[3] > 0.f) + { + drawablep->setState(LLDrawable::HAS_ALPHA); + alpha_faces.push_back(facep); + } } } else @@ -4510,6 +4553,12 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } mFaceList.clear(); + + if (pAvatarVO) + { + pAvatarVO->mAttachmentGeometryBytes += group->mGeometryBytes; + pAvatarVO->mAttachmentSurfaceArea += group->mSurfaceArea; + } } static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM("Volume Geometry"); @@ -4838,6 +4887,9 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } } + group->mGeometryBytes += buffer->getSize() + buffer->getIndicesSize(); + + buffer_map[mask][*face_iter].push_back(buffer); //add face geometry diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 737c5b51a2..df8f8793d1 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -9420,7 +9420,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) assertInitialized(); - BOOL muted = LLMuteList::getInstance()->isMuted(avatar->getID()); + bool muted = avatar->isVisuallyMuted(); pushRenderTypeMask(); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 2815d736e4..9c78048c46 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -432,34 +432,35 @@ public: enum LLRenderDebugMask { - RENDER_DEBUG_COMPOSITION = 0x0000001, - RENDER_DEBUG_VERIFY = 0x0000002, - RENDER_DEBUG_BBOXES = 0x0000004, - RENDER_DEBUG_OCTREE = 0x0000008, - RENDER_DEBUG_WIND_VECTORS = 0x0000010, - RENDER_DEBUG_OCCLUSION = 0x0000020, - RENDER_DEBUG_POINTS = 0x0000040, - RENDER_DEBUG_TEXTURE_PRIORITY = 0x0000080, - RENDER_DEBUG_TEXTURE_AREA = 0x0000100, - RENDER_DEBUG_FACE_AREA = 0x0000200, - RENDER_DEBUG_PARTICLES = 0x0000400, - RENDER_DEBUG_GLOW = 0x0000800, - RENDER_DEBUG_TEXTURE_ANIM = 0x0001000, - RENDER_DEBUG_LIGHTS = 0x0002000, - RENDER_DEBUG_BATCH_SIZE = 0x0004000, - RENDER_DEBUG_ALPHA_BINS = 0x0008000, - RENDER_DEBUG_RAYCAST = 0x0010000, - RENDER_DEBUG_SHAME = 0x0020000, - RENDER_DEBUG_SHADOW_FRUSTA = 0x0040000, - RENDER_DEBUG_SCULPTED = 0x0080000, - RENDER_DEBUG_AVATAR_VOLUME = 0x0100000, - RENDER_DEBUG_BUILD_QUEUE = 0x0200000, - RENDER_DEBUG_AGENT_TARGET = 0x0400000, - RENDER_DEBUG_UPDATE_TYPE = 0x0800000, - RENDER_DEBUG_PHYSICS_SHAPES = 0x1000000, - RENDER_DEBUG_NORMALS = 0x2000000, - RENDER_DEBUG_LOD_INFO = 0x4000000, - RENDER_DEBUG_RENDER_COMPLEXITY = 0x8000000 + RENDER_DEBUG_COMPOSITION = 0x00000001, + RENDER_DEBUG_VERIFY = 0x00000002, + RENDER_DEBUG_BBOXES = 0x00000004, + RENDER_DEBUG_OCTREE = 0x00000008, + RENDER_DEBUG_WIND_VECTORS = 0x00000010, + RENDER_DEBUG_OCCLUSION = 0x00000020, + RENDER_DEBUG_POINTS = 0x00000040, + RENDER_DEBUG_TEXTURE_PRIORITY = 0x00000080, + RENDER_DEBUG_TEXTURE_AREA = 0x00000100, + RENDER_DEBUG_FACE_AREA = 0x00000200, + RENDER_DEBUG_PARTICLES = 0x00000400, + RENDER_DEBUG_GLOW = 0x00000800, + RENDER_DEBUG_TEXTURE_ANIM = 0x00001000, + RENDER_DEBUG_LIGHTS = 0x00002000, + RENDER_DEBUG_BATCH_SIZE = 0x00004000, + RENDER_DEBUG_ALPHA_BINS = 0x00008000, + RENDER_DEBUG_RAYCAST = 0x00010000, + RENDER_DEBUG_SHAME = 0x00020000, + RENDER_DEBUG_SHADOW_FRUSTA = 0x00040000, + RENDER_DEBUG_SCULPTED = 0x00080000, + RENDER_DEBUG_AVATAR_VOLUME = 0x00100000, + RENDER_DEBUG_BUILD_QUEUE = 0x00200000, + RENDER_DEBUG_AGENT_TARGET = 0x00400000, + RENDER_DEBUG_UPDATE_TYPE = 0x00800000, + RENDER_DEBUG_PHYSICS_SHAPES = 0x01000000, + RENDER_DEBUG_NORMALS = 0x02000000, + RENDER_DEBUG_LOD_INFO = 0x04000000, + RENDER_DEBUG_RENDER_COMPLEXITY = 0x08000000, + RENDER_DEBUG_ATTACHMENT_BYTES = 0x10000000, }; public: diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index ec2dd10248..b3a0c3379d 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2499,6 +2499,16 @@ + + + +