From 4f8186b17e3fa79be189f50d5bcd7385a5c7fbd1 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Tue, 2 Aug 2011 16:21:44 -0500 Subject: [PATCH 01/10] Debug symbols for llcommon.dll on windows. --- indra/newview/CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index b095c90d4..7109b8169 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1613,6 +1613,13 @@ endif (LL_TESTS) if (WINDOWS) get_target_property(BUILT_LLCOMMON llcommon LOCATION) + + set_target_properties(llcommon + PROPERTIES + LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT" + LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\"" + ) + add_custom_command( TARGET ${VIEWER_BINARY_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} From 2c489d77412877827bbf02d379b3c4e45a134eaf Mon Sep 17 00:00:00 2001 From: Shyotl Date: Thu, 4 Aug 2011 01:38:56 -0500 Subject: [PATCH 02/10] Cleaned up polymesh (mesh vectors/normals size match VBO vectors/normals size to allow memcpy). Prep for vbo testing. --- indra/newview/llpolymesh.cpp | 82 +++---- indra/newview/llpolymesh.h | 12 +- indra/newview/llpolymorph.cpp | 65 +++--- indra/newview/llviewerjointmesh.cpp | 279 +++++++++-------------- indra/newview/llviewerjointmesh_sse.cpp | 8 +- indra/newview/llviewerjointmesh_sse2.cpp | 8 +- indra/newview/llviewerjointmesh_vec.cpp | 8 +- indra/newview/llvovolume.cpp | 35 ++- indra/newview/llvovolume.h | 4 +- indra/newview/pipeline.cpp | 11 +- 10 files changed, 235 insertions(+), 277 deletions(-) diff --git a/indra/newview/llpolymesh.cpp b/indra/newview/llpolymesh.cpp index 7c433cb43..180c3dd2e 100644 --- a/indra/newview/llpolymesh.cpp +++ b/indra/newview/llpolymesh.cpp @@ -769,29 +769,23 @@ LLPolyMesh::LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_ } else { -#if 1 // Allocate memory without initializing every vector + // Allocate memory without initializing every vector // NOTE: This makes asusmptions about the size of LLVector[234] int nverts = mSharedData->mNumVertices; - int nfloats = nverts * (3*5 + 2 + 4); - mVertexData = new F32[nfloats]; + int nfloats = nverts * (2*4 + 3*3 + 2 + 4); + //use 16 byte aligned vertex data to make LLPolyMesh SSE friendly + mVertexData = (F32*) ll_aligned_malloc_16(nfloats*4); int offset = 0; - mCoords = (LLVector3*)(mVertexData + offset); offset += 3*nverts; - mNormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; - mScaledNormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; - mBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; + mCoords = (LLVector4*)(mVertexData + offset); offset += 4*nverts; + mNormals = (LLVector4*)(mVertexData + offset); offset += 4*nverts; + mClothingWeights = (LLVector4*)(mVertexData + offset); offset += 4*nverts; + mTexCoords = (LLVector2*)(mVertexData + offset); offset += 2*nverts; + + // these members don't need to be 16-byte aligned, but the first one might be + // read during an aligned memcpy of mTexCoords + mScaledNormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; + mBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; mScaledBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; - mTexCoords = (LLVector2*)(mVertexData + offset); offset += 2*nverts; - mClothingWeights = (LLVector4*)(mVertexData + offset); offset += 4*nverts; -#else - mCoords = new LLVector3[mSharedData->mNumVertices]; - mNormals = new LLVector3[mSharedData->mNumVertices]; - mScaledNormals = new LLVector3[mSharedData->mNumVertices]; - mBinormals = new LLVector3[mSharedData->mNumVertices]; - mScaledBinormals = new LLVector3[mSharedData->mNumVertices]; - mTexCoords = new LLVector2[mSharedData->mNumVertices]; - mClothingWeights = new LLVector4[mSharedData->mNumVertices]; - memset(mClothingWeights, 0, sizeof(LLVector4) * mSharedData->mNumVertices); -#endif initializeForMorph(); } } @@ -806,19 +800,11 @@ LLPolyMesh::~LLPolyMesh() for (i = 0; i < mJointRenderData.count(); i++) { delete mJointRenderData[i]; - mJointRenderData[i] = NULL; - } -#if 0 // These are now allocated as one big uninitialized chunk - delete [] mCoords; - delete [] mNormals; - delete [] mScaledNormals; - delete [] mBinormals; - delete [] mScaledBinormals; - delete [] mClothingWeights; - delete [] mTexCoords; -#else - delete [] mVertexData; -#endif + mJointRenderData[i] = NULL; + } + + ll_aligned_free_16(mVertexData); + } @@ -1242,7 +1228,7 @@ BOOL LLPolyMesh::saveOBJ(LLFILE *fp) int nfaces = mSharedData->mNumFaces; int i; - LLVector3* coords = getWritableCoords(); + LLVector4* coords = getWritableCoords(); for ( i=0; igetMesh(mSharedData); if (mesh) { - LLVector3 *mesh_coords = mesh->getWritableCoords(); - LLVector3 *mesh_normals = mesh->getWritableNormals(); + LLVector4 *mesh_coords = mesh->getWritableCoords(); + LLVector4 *mesh_normals = mesh->getWritableNormals(); LLVector3 *mesh_binormals = mesh->getWritableBinormals(); LLVector2 *mesh_tex_coords = mesh->getWritableTexCoords(); LLVector3 *mesh_scaled_normals = mesh->getScaledNormals(); @@ -1509,10 +1495,10 @@ BOOL LLPolyMesh::setSharedFromCurrent() mesh_coords[vert_index] -= delta_coords[vert_index]; mesh_tex_coords[vert_index] -= delta_tex_coords[vert_index]; - mesh_scaled_normals[vert_index] -= delta_normals[vert_index]; + mesh_scaled_normals[vert_index] -= LLVector3(delta_normals[vert_index]); LLVector3 normalized_normal = mesh_scaled_normals[vert_index]; normalized_normal.normVec(); - mesh_normals[vert_index] = normalized_normal; + mesh_normals[vert_index] = LLVector4(normalized_normal); mesh_scaled_binormals[vert_index] -= delta_binormals[vert_index]; LLVector3 tangent = mesh_scaled_binormals[vert_index] % normalized_normal; @@ -1616,7 +1602,7 @@ void LLPolyMesh::dumpDiagInfo(void*) //----------------------------------------------------------------------------- // getWritableCoords() //----------------------------------------------------------------------------- -LLVector3 *LLPolyMesh::getWritableCoords() +LLVector4 *LLPolyMesh::getWritableCoords() { return mCoords; } @@ -1624,7 +1610,7 @@ LLVector3 *LLPolyMesh::getWritableCoords() //----------------------------------------------------------------------------- // getWritableNormals() //----------------------------------------------------------------------------- -LLVector3 *LLPolyMesh::getWritableNormals() +LLVector4 *LLPolyMesh::getWritableNormals() { return mNormals; } @@ -1679,8 +1665,12 @@ void LLPolyMesh::initializeForMorph() if (!mSharedData) return; - memcpy(mCoords, mSharedData->mBaseCoords, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ - memcpy(mNormals, mSharedData->mBaseNormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ + for (U32 i = 0; i < (U32)mSharedData->mNumVertices; ++i) + { + mCoords[i] = LLVector4(mSharedData->mBaseCoords[i]); + mNormals[i] = LLVector4(mSharedData->mBaseNormals[i]); + } + memcpy(mScaledNormals, mSharedData->mBaseNormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ memcpy(mBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ memcpy(mScaledBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ diff --git a/indra/newview/llpolymesh.h b/indra/newview/llpolymesh.h index 15c284a1a..a91d88c71 100644 --- a/indra/newview/llpolymesh.h +++ b/indra/newview/llpolymesh.h @@ -240,15 +240,15 @@ public: } // Get coords - const LLVector3 *getCoords() const{ + const LLVector4 *getCoords() const{ return mCoords; } // non const version - LLVector3 *getWritableCoords(); + LLVector4 *getWritableCoords(); // Get normals - const LLVector3 *getNormals() const{ + const LLVector4 *getNormals() const{ return mNormals; } @@ -270,7 +270,7 @@ public: } // intermediate morphed normals and output normals - LLVector3 *getWritableNormals(); + LLVector4 *getWritableNormals(); LLVector3 *getScaledNormals(); LLVector3 *getWritableBinormals(); @@ -368,11 +368,11 @@ protected: // Single array of floats for allocation / deletion F32 *mVertexData; // deformed vertices (resulting from application of morph targets) - LLVector3 *mCoords; + LLVector4 *mCoords; // deformed normals (resulting from application of morph targets) LLVector3 *mScaledNormals; // output normals (after normalization) - LLVector3 *mNormals; + LLVector4 *mNormals; // deformed binormals (resulting from application of morph targets) LLVector3 *mScaledBinormals; // output binormals (after normalization) diff --git a/indra/newview/llpolymorph.cpp b/indra/newview/llpolymorph.cpp index 4cf59a209..9b2a7b4a5 100644 --- a/indra/newview/llpolymorph.cpp +++ b/indra/newview/llpolymorph.cpp @@ -282,16 +282,16 @@ BOOL LLPolyMorphData::saveOBJ(LLFILE *fp) LLPolyMesh mesh(mMesh, NULL); - LLVector3 *coords = mesh.getWritableCoords(); - LLVector3 *normals = mesh.getWritableNormals(); + LLVector4 *coords = mesh.getWritableCoords(); + LLVector4 *normals = mesh.getWritableNormals(); LLVector2 *tex_coords = mesh.getWritableTexCoords(); for(U32 vert_index_morph = 0; vert_index_morph < mNumIndices; vert_index_morph++) { S32 vert_index_mesh = mVertexIndices[vert_index_morph]; - coords[vert_index_mesh] += mCoords[vert_index_morph]; - normals[vert_index_mesh] += mNormals[vert_index_morph]; + coords[vert_index_mesh] += LLVector4(mCoords[vert_index_morph]); + normals[vert_index_mesh] += LLVector4(mNormals[vert_index_morph]); normals[vert_index_mesh].normVec(); tex_coords[vert_index_mesh] += mTexCoords[vert_index_morph]; } @@ -307,8 +307,8 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) if (!morph) return FALSE; - LLVector3 *morph_coords = morph->getWritableCoords(); - LLVector3 *morph_normals = morph->getWritableNormals(); + LLVector4 *morph_coords = morph->getWritableCoords(); + LLVector4 *morph_normals = morph->getWritableNormals(); LLVector3 *morph_binormals = morph->getWritableBinormals(); LLVector2 *morph_tex_coords = morph->getWritableTexCoords(); @@ -318,8 +318,8 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) LLPolyMesh delta(mMesh, NULL); U32 nverts = delta.getNumVertices(); - LLVector3 *delta_coords = delta.getWritableCoords(); - LLVector3 *delta_normals = delta.getWritableNormals(); + LLVector4 *delta_coords = delta.getWritableCoords(); + LLVector4 *delta_normals = delta.getWritableNormals(); LLVector3 *delta_binormals = delta.getWritableBinormals(); LLVector2 *delta_tex_coords = delta.getWritableTexCoords(); @@ -380,8 +380,8 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) { new_vertex_indices[morph_index] = vert_index; - new_coords[morph_index] = delta_coords[vert_index]; - new_normals[morph_index] = delta_normals[vert_index]; + new_coords[morph_index] = LLVector3(delta_coords[vert_index]); + new_normals[morph_index] = LLVector3(delta_normals[vert_index]); new_binormals[morph_index] = delta_binormals[vert_index]; new_tex_coords[morph_index] = delta_tex_coords[vert_index]; @@ -417,8 +417,8 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) { vert_index = mVertexIndices[morph_index]; - delta_coords[vert_index] -= mCoords[morph_index]; - delta_normals[vert_index] -= mNormals[morph_index]; + delta_coords[vert_index] -= LLVector4(mCoords[morph_index]); + delta_normals[vert_index] -= LLVector4(mNormals[morph_index]); delta_binormals[vert_index] -= mBinormals[morph_index]; delta_tex_coords[vert_index] -= mTexCoords[morph_index]; } @@ -456,8 +456,8 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) continue; } - LLVector3 *mesh_coords = mesh->getWritableCoords(); - LLVector3 *mesh_normals = mesh->getWritableNormals(); + LLVector4 *mesh_coords = mesh->getWritableCoords(); + LLVector4 *mesh_normals = mesh->getWritableNormals(); LLVector3 *mesh_binormals = mesh->getWritableBinormals(); LLVector2 *mesh_tex_coords = mesh->getWritableTexCoords(); LLVector3 *mesh_scaled_normals = mesh->getScaledNormals(); @@ -468,10 +468,10 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) mesh_coords[vert_index] += delta_coords[vert_index] * weight; mesh_tex_coords[vert_index] += delta_tex_coords[vert_index] * weight; - mesh_scaled_normals[vert_index] += delta_normals[vert_index] * weight * NORMAL_SOFTEN_FACTOR; + mesh_scaled_normals[vert_index] += LLVector3(delta_normals[vert_index] * weight * NORMAL_SOFTEN_FACTOR); LLVector3 normalized_normal = mesh_scaled_normals[vert_index]; normalized_normal.normVec(); - mesh_normals[vert_index] = normalized_normal; + mesh_normals[vert_index] = LLVector4(normalized_normal); mesh_scaled_binormals[vert_index] += delta_binormals[vert_index] * weight * NORMAL_SOFTEN_FACTOR; LLVector3 tangent = mesh_scaled_binormals[vert_index] % normalized_normal; @@ -797,10 +797,10 @@ void LLPolyMorphTarget::apply( ESex avatar_sex ) if (delta_weight != 0.f) { llassert(!mMesh->isLOD()); - LLVector3 *coords = mMesh->getWritableCoords(); + LLVector4 *coords = mMesh->getWritableCoords(); LLVector3 *scaled_normals = mMesh->getScaledNormals(); - LLVector3 *normals = mMesh->getWritableNormals(); + LLVector4 *normals = mMesh->getWritableNormals(); LLVector3 *scaled_binormals = mMesh->getScaledBinormals(); LLVector3 *binormals = mMesh->getWritableBinormals(); @@ -820,7 +820,8 @@ void LLPolyMorphTarget::apply( ESex avatar_sex ) maskWeight = maskWeightArray[vert_index_morph]; } - coords[vert_index_mesh] += mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight; + coords[vert_index_mesh] += LLVector4(mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight); + if (getInfo()->mIsClothingMorph && clothing_weights) { LLVector3 clothing_offset = mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight; @@ -835,7 +836,7 @@ void LLPolyMorphTarget::apply( ESex avatar_sex ) scaled_normals[vert_index_mesh] += mMorphData->mNormals[vert_index_morph] * delta_weight * maskWeight * NORMAL_SOFTEN_FACTOR; LLVector3 normalized_normal = scaled_normals[vert_index_mesh]; normalized_normal.normVec(); - normals[vert_index_mesh] = normalized_normal; + normals[vert_index_mesh] = LLVector4(normalized_normal); // calculate new binormals scaled_binormals[vert_index_mesh] += mMorphData->mBinormals[vert_index_morph] * delta_weight * maskWeight * NORMAL_SOFTEN_FACTOR; @@ -906,31 +907,31 @@ BOOL LLPolyMorphTarget::undoMask(BOOL delete_mask) F32 *mask_weights = mVertMask->getMorphMaskWeights(); - LLVector3 *coords = mMesh->getWritableCoords(); + LLVector4 *coords = mMesh->getWritableCoords(); LLVector3 *scaled_normals = mMesh->getScaledNormals(); LLVector3 *scaled_binormals = mMesh->getScaledBinormals(); LLVector2 *tex_coords = mMesh->getWritableTexCoords(); for(U32 vert = 0; vert < mMorphData->mNumIndices; vert++) { - F32 mask_weight = 1.f; - if (mask_weights) - { - mask_weight = mask_weights[vert]; - } + F32 mask_weight = 1.f; + if (mask_weights) + { + mask_weight = mask_weights[vert]; + } - F32 last_mask_weight = mLastWeight * mask_weight; + F32 lastMaskWeight = mLastWeight * mask_weights[vert]; S32 out_vert = mMorphData->mVertexIndices[vert]; // remove effect of existing masked morph - coords[out_vert] -= mMorphData->mCoords[vert] * last_mask_weight; - scaled_normals[out_vert] -= mMorphData->mNormals[vert] * last_mask_weight * NORMAL_SOFTEN_FACTOR; - scaled_binormals[out_vert] -= mMorphData->mBinormals[vert] * last_mask_weight * NORMAL_SOFTEN_FACTOR; - tex_coords[out_vert] -= mMorphData->mTexCoords[vert] * last_mask_weight; + coords[out_vert] -= LLVector4(mMorphData->mCoords[vert]) * lastMaskWeight; + scaled_normals[out_vert] -= mMorphData->mNormals[vert] * lastMaskWeight * NORMAL_SOFTEN_FACTOR; + scaled_binormals[out_vert] -= mMorphData->mBinormals[vert] * lastMaskWeight * NORMAL_SOFTEN_FACTOR; + tex_coords[out_vert] -= mMorphData->mTexCoords[vert] * lastMaskWeight; if (clothing_weights) { - LLVector3 clothing_offset = mMorphData->mCoords[vert] * last_mask_weight; + LLVector3 clothing_offset = mMorphData->mCoords[vert] * lastMaskWeight; LLVector4* clothing_weight = &clothing_weights[out_vert]; clothing_weight->mV[VX] -= clothing_offset.mV[VX]; clothing_weight->mV[VY] -= clothing_offset.mV[VY]; diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index 36e9b71f6..762218711 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -61,6 +61,7 @@ #include "v4math.h" #include "m3math.h" #include "m4math.h" +#include "llmatrix4a.h" #if !LL_DARWIN && !LL_LINUX && !LL_SOLARIS extern PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB; @@ -382,6 +383,7 @@ const S32 NUM_AXES = 3; // pivot parent 0-n -- child = n+1 static LLMatrix4 gJointMatUnaligned[32]; +static LLMatrix4a gJointMatAligned[32]; static LLMatrix3 gJointRotUnaligned[32]; static LLVector4 gJointPivot[32]; @@ -467,6 +469,14 @@ void LLViewerJointMesh::uploadJointMatrices() glUniform4fvARB(gAvatarMatrixParam, 45, mat); stop_glerror(); } + else + { + //load gJointMatUnaligned into gJointMatAligned + for (joint_num = 0; joint_num < reference_mesh->mJointRenderData.count(); ++joint_num) + { + gJointMatAligned[joint_num].loadu(gJointMatUnaligned[joint_num]); + } + } } //-------------------------------------------------------------------- @@ -516,6 +526,8 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) U32 triangle_count = 0; + S32 diffuse_channel = LLDrawPoolAvatar::sDiffuseChannel; + stop_glerror(); //---------------------------------------------------------------- @@ -531,7 +543,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) stop_glerror(); - LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), gRenderForSelect ? 0.0f : mShiny && !(mFace->getPool()->getVertexShaderLevel() > 0)); + LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), (mFace->getPool()->getVertexShaderLevel() > 0 && !gRenderForSelect) ? 0.f : mShiny); //---------------------------------------------------------------- // setup current texture @@ -541,7 +553,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) LLTexUnit::eTextureAddressMode old_mode = LLTexUnit::TAM_WRAP; if (mTestImageName) { - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTestImageName); + gGL.getTexUnit(diffuse_channel)->bindManual(LLTexUnit::TT_TEXTURE, mTestImageName); if (mIsTransparent) { @@ -550,14 +562,14 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) else { glColor4f(0.7f, 0.6f, 0.3f, 1.f); - gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_LERP_TEX_ALPHA, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); + gGL.getTexUnit(diffuse_channel)->setTextureColorBlend(LLTexUnit::TBO_LERP_TEX_ALPHA, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); } } else if( !is_dummy && mLayerSet ) { if( mLayerSet->hasComposite() ) { - gGL.getTexUnit(0)->bind(mLayerSet->getComposite()); + gGL.getTexUnit(diffuse_channel)->bind(mLayerSet->getComposite()); } else { @@ -567,7 +579,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) { llwarns << "Layerset without composite" << llendl; } - gGL.getTexUnit(0)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT)); + gGL.getTexUnit(diffuse_channel)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT)); } } else @@ -577,24 +589,25 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) { old_mode = mTexture->getAddressMode(); } - gGL.getTexUnit(0)->bind(mTexture); - gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + gGL.getTexUnit(diffuse_channel)->bind(mTexture); + gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + } else { - gGL.getTexUnit(0)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR)); + gGL.getTexUnit(diffuse_channel)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR)); } if (gRenderForSelect) { if (isTransparent()) { - gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR); - gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_CONST_ALPHA); + gGL.getTexUnit(diffuse_channel)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR); + gGL.getTexUnit(diffuse_channel)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_CONST_ALPHA); } else { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); } } @@ -631,13 +644,13 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) if (mTestImageName) { - gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); + gGL.getTexUnit(diffuse_channel)->setTextureBlendType(LLTexUnit::TB_MULT); } if (mTexture.notNull() && !is_dummy) { - gGL.getTexUnit(0)->bind(mTexture.get()); - gGL.getTexUnit(0)->setTextureAddressMode(old_mode); + gGL.getTexUnit(diffuse_channel)->bind(mTexture); + gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(old_mode); } return triangle_count; @@ -648,6 +661,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) //----------------------------------------------------------------------------- void LLViewerJointMesh::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area) { + num_vertices = (num_vertices + 0x3) & ~0x3; // Do a pre-alloc pass to determine sizes of data. if (mMesh && mValid) { @@ -676,6 +690,16 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w return; } + LLDrawPool *poolp = mFace->getPool(); + BOOL hardware_skinning = (poolp && poolp->getVertexShaderLevel() > 0) ? TRUE : FALSE; + + if (!hardware_skinning && terse_update) + { //no need to do terse updates if we're doing software vertex skinning + // since mMesh is being copied into mVertexBuffer every frame + return; + } + + LLStrider verticesp; LLStrider normalsp; LLStrider tex_coordsp; @@ -686,111 +710,64 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w // Copy data into the faces from the polymesh data. if (mMesh && mValid) { - if (mMesh->getNumVertices()) + const U32 num_verts = mMesh->getNumVertices(); + + if (num_verts) { - stop_glerror(); face->getGeometryAvatar(verticesp, normalsp, tex_coordsp, vertex_weightsp, clothing_weightsp); - stop_glerror(); face->getVertexBuffer()->getIndexStrider(indicesp); - stop_glerror(); verticesp += mMesh->mFaceVertexOffset; - tex_coordsp += mMesh->mFaceVertexOffset; normalsp += mMesh->mFaceVertexOffset; - vertex_weightsp += mMesh->mFaceVertexOffset; - clothing_weightsp += mMesh->mFaceVertexOffset; - - const U32* __restrict coords = (U32*) mMesh->getCoords(); - const U32* __restrict tex_coords = (U32*) mMesh->getTexCoords(); - const U32* __restrict normals = (U32*) mMesh->getNormals(); - const U32* __restrict weights = (U32*) mMesh->getWeights(); - const U32* __restrict cloth_weights = (U32*) mMesh->getClothingWeights(); - - const U32 num_verts = mMesh->getNumVertices(); - - U32 i = 0; - - const U32 skip = verticesp.getSkip()/sizeof(U32); - - U32* __restrict v = (U32*) verticesp.get(); - U32* __restrict n = (U32*) normalsp.get(); - if (terse_update) + //F32* v = (F32*) verticesp.get(); + //F32* n = (F32*) normalsp.get(); + + //U32 words = num_verts*4; + + //LLVector4a::memcpyNonAliased16(v, (F32*) mMesh->getCoords(), words*sizeof(F32)); + verticesp.assignArray((U8*)mMesh->getCoords(), sizeof(mMesh->getCoords()[0]), num_verts); + //LLVector4a::memcpyNonAliased16(n, (F32*) mMesh->getNormals(), words*sizeof(F32)); + normalsp.assignArray((U8*)mMesh->getNormals(), sizeof(mMesh->getNormals()[0]), num_verts); + + + if (!terse_update) { - for (S32 i = num_verts; i > 0; --i) - { - //morph target application only, only update positions and normals - v[0] = coords[0]; - v[1] = coords[1]; - v[2] = coords[2]; - coords += 3; - v += skip; - } + vertex_weightsp += mMesh->mFaceVertexOffset; + clothing_weightsp += mMesh->mFaceVertexOffset; + tex_coordsp += mMesh->mFaceVertexOffset; + + //F32* tc = (F32*) tex_coordsp.get(); + //F32* vw = (F32*) vertex_weightsp.get(); + //F32* cw = (F32*) clothing_weightsp.get(); - for (S32 i = num_verts; i > 0; --i) - { - n[0] = normals[0]; - n[1] = normals[1]; - n[2] = normals[2]; - normals += 3; - n += skip; - } + //LLVector4a::memcpyNonAliased16(tc, (F32*) mMesh->getTexCoords(), num_verts*2*sizeof(F32)); + tex_coordsp.assignArray((U8*)mMesh->getTexCoords(), sizeof(mMesh->getTexCoords()[0]), num_verts); + //LLVector4a::memcpyNonAliased16(vw, (F32*) mMesh->getWeights(), num_verts*sizeof(F32)); + vertex_weightsp.assignArray((U8*)mMesh->getWeights(), sizeof(mMesh->getWeights()[0]), num_verts); + //LLVector4a::memcpyNonAliased16(cw, (F32*) mMesh->getClothingWeights(), num_verts*4*sizeof(F32)); + clothing_weightsp.assignArray((U8*)mMesh->getClothingWeights(), sizeof(mMesh->getClothingWeights()[0]), num_verts); } - else - { - U32* __restrict tc = (U32*) tex_coordsp.get(); - U32* __restrict vw = (U32*) vertex_weightsp.get(); - U32* __restrict cw = (U32*) clothing_weightsp.get(); - - do - { - v[0] = *(coords++); - v[1] = *(coords++); - v[2] = *(coords++); - v += skip; - - tc[0] = *(tex_coords++); - tc[1] = *(tex_coords++); - tc += skip; - - n[0] = *(normals++); - n[1] = *(normals++); - n[2] = *(normals++); - n += skip; - - vw[0] = *(weights++); - vw += skip; - - cw[0] = *(cloth_weights++); - cw[1] = *(cloth_weights++); - cw[2] = *(cloth_weights++); - cw[3] = *(cloth_weights++); - cw += skip; - } - while (++i < num_verts); - - const U32 idx_count = mMesh->getNumFaces()*3; + const U32 idx_count = mMesh->getNumFaces()*3; indicesp += mMesh->mFaceIndexOffset; - U16* __restrict idx = indicesp.get(); - S32* __restrict src_idx = (S32*) mMesh->getFaces(); + U16* __restrict idx = indicesp.get(); + S32* __restrict src_idx = (S32*) mMesh->getFaces(); - i = 0; + const S32 offset = (S32) mMesh->mFaceVertexOffset; - const S32 offset = (S32) mMesh->mFaceVertexOffset; - - do - { - *(idx++) = *(src_idx++)+offset; - } - while (++i < idx_count); + for (S32 i = 0; i < (S32)idx_count; ++i) + { + *(idx++) = *(src_idx++)+offset; } } } } + + //----------------------------------------------------------------------------- // updateLOD() //----------------------------------------------------------------------------- @@ -812,85 +789,45 @@ void LLViewerJointMesh::updateGeometryOriginal(LLFace *mFace, LLPolyMesh *mMesh) buffer->getVertexStrider(o_vertices, 0); buffer->getNormalStrider(o_normals, 0); - F32 last_weight = F32_MAX; - LLMatrix4 gBlendMat; - LLMatrix3 gBlendRotMat; + F32* __restrict vert = o_vertices[0].mV; + F32* __restrict norm = o_normals[0].mV; + + const F32* __restrict weights = mMesh->getWeights(); + const LLVector4a* __restrict coords = (LLVector4a*) mMesh->getCoords(); + const LLVector4a* __restrict normals = (LLVector4a*) mMesh->getNormals(); + + U32 offset = mMesh->mFaceVertexOffset*4; + vert += offset; + norm += offset; - const F32* weights = mMesh->getWeights(); - const LLVector3* coords = mMesh->getCoords(); - const LLVector3* normals = mMesh->getNormals(); for (U32 index = 0; index < mMesh->getNumVertices(); index++) { - U32 bidx = index + mMesh->mFaceVertexOffset; - - // blend by first matrix - F32 w = weights[index]; - - // Maybe we don't have to change gBlendMat. - // Profiles of a single-avatar scene on a Mac show this to be a very - // common case. JC - if (w == last_weight) + // equivalent to joint = floorf(weights[index]); + S32 joint = _mm_cvtt_ss2si(_mm_load_ss(weights+index)); + F32 w = weights[index] - joint; + + LLMatrix4a gBlendMat; + + if (w != 0.f) { - o_vertices[bidx] = coords[index] * gBlendMat; - o_normals[bidx] = normals[index] * gBlendRotMat; - continue; + // blend between matrices and apply + gBlendMat.setLerp(gJointMatAligned[joint+0], + gJointMatAligned[joint+1], w); + + LLVector4a res; + gBlendMat.affineTransform(coords[index], res); + res.store4a(vert+index*4); + gBlendMat.rotate(normals[index], res); + res.store4a(norm+index*4); } - - last_weight = w; - - S32 joint = llfloor(w); - w -= joint; - - // No lerp required in this case. - if (w == 1.0f) - { - gBlendMat = gJointMatUnaligned[joint+1]; - o_vertices[bidx] = coords[index] * gBlendMat; - gBlendRotMat = gJointRotUnaligned[joint+1]; - o_normals[bidx] = normals[index] * gBlendRotMat; - continue; + else + { // No lerp required in this case. + LLVector4a res; + gJointMatAligned[joint].affineTransform(coords[index], res); + res.store4a(vert+index*4); + gJointMatAligned[joint].rotate(normals[index], res); + res.store4a(norm+index*4); } - - // Try to keep all the accesses to the matrix data as close - // together as possible. This function is a hot spot on the - // Mac. JC - LLMatrix4 &m0 = gJointMatUnaligned[joint+1]; - LLMatrix4 &m1 = gJointMatUnaligned[joint+0]; - - gBlendMat.mMatrix[VX][VX] = lerp(m1.mMatrix[VX][VX], m0.mMatrix[VX][VX], w); - gBlendMat.mMatrix[VX][VY] = lerp(m1.mMatrix[VX][VY], m0.mMatrix[VX][VY], w); - gBlendMat.mMatrix[VX][VZ] = lerp(m1.mMatrix[VX][VZ], m0.mMatrix[VX][VZ], w); - - gBlendMat.mMatrix[VY][VX] = lerp(m1.mMatrix[VY][VX], m0.mMatrix[VY][VX], w); - gBlendMat.mMatrix[VY][VY] = lerp(m1.mMatrix[VY][VY], m0.mMatrix[VY][VY], w); - gBlendMat.mMatrix[VY][VZ] = lerp(m1.mMatrix[VY][VZ], m0.mMatrix[VY][VZ], w); - - gBlendMat.mMatrix[VZ][VX] = lerp(m1.mMatrix[VZ][VX], m0.mMatrix[VZ][VX], w); - gBlendMat.mMatrix[VZ][VY] = lerp(m1.mMatrix[VZ][VY], m0.mMatrix[VZ][VY], w); - gBlendMat.mMatrix[VZ][VZ] = lerp(m1.mMatrix[VZ][VZ], m0.mMatrix[VZ][VZ], w); - - gBlendMat.mMatrix[VW][VX] = lerp(m1.mMatrix[VW][VX], m0.mMatrix[VW][VX], w); - gBlendMat.mMatrix[VW][VY] = lerp(m1.mMatrix[VW][VY], m0.mMatrix[VW][VY], w); - gBlendMat.mMatrix[VW][VZ] = lerp(m1.mMatrix[VW][VZ], m0.mMatrix[VW][VZ], w); - - o_vertices[bidx] = coords[index] * gBlendMat; - - LLMatrix3 &n0 = gJointRotUnaligned[joint+1]; - LLMatrix3 &n1 = gJointRotUnaligned[joint+0]; - - gBlendRotMat.mMatrix[VX][VX] = lerp(n1.mMatrix[VX][VX], n0.mMatrix[VX][VX], w); - gBlendRotMat.mMatrix[VX][VY] = lerp(n1.mMatrix[VX][VY], n0.mMatrix[VX][VY], w); - gBlendRotMat.mMatrix[VX][VZ] = lerp(n1.mMatrix[VX][VZ], n0.mMatrix[VX][VZ], w); - - gBlendRotMat.mMatrix[VY][VX] = lerp(n1.mMatrix[VY][VX], n0.mMatrix[VY][VX], w); - gBlendRotMat.mMatrix[VY][VY] = lerp(n1.mMatrix[VY][VY], n0.mMatrix[VY][VY], w); - gBlendRotMat.mMatrix[VY][VZ] = lerp(n1.mMatrix[VY][VZ], n0.mMatrix[VY][VZ], w); - - gBlendRotMat.mMatrix[VZ][VX] = lerp(n1.mMatrix[VZ][VX], n0.mMatrix[VZ][VX], w); - gBlendRotMat.mMatrix[VZ][VY] = lerp(n1.mMatrix[VZ][VY], n0.mMatrix[VZ][VY], w); - gBlendRotMat.mMatrix[VZ][VZ] = lerp(n1.mMatrix[VZ][VZ], n0.mMatrix[VZ][VZ], w); - - o_normals[bidx] = normals[index] * gBlendRotMat; } buffer->setBuffer(0); diff --git a/indra/newview/llviewerjointmesh_sse.cpp b/indra/newview/llviewerjointmesh_sse.cpp index 2f2635246..36d6bd61a 100644 --- a/indra/newview/llviewerjointmesh_sse.cpp +++ b/indra/newview/llviewerjointmesh_sse.cpp @@ -94,8 +94,8 @@ void LLViewerJointMesh::updateGeometrySSE(LLFace *face, LLPolyMesh *mesh) buffer->getNormalStrider(o_normals, mesh->mFaceVertexOffset); const F32* weights = mesh->getWeights(); - const LLVector3* coords = mesh->getCoords(); - const LLVector3* normals = mesh->getNormals(); + const LLVector4* coords = mesh->getCoords(); + const LLVector4* normals = mesh->getNormals(); for (U32 index = 0, index_end = mesh->getNumVertices(); index < index_end; ++index) { if( weight != weights[index]) @@ -103,8 +103,8 @@ void LLViewerJointMesh::updateGeometrySSE(LLFace *face, LLPolyMesh *mesh) 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]); + blend_mat.multiply((const LLVector3)coords[index], o_vertices[index]); + ((LLV4Matrix3)blend_mat).multiply((const LLVector3)normals[index], o_normals[index]); } buffer->setBuffer(0); diff --git a/indra/newview/llviewerjointmesh_sse2.cpp b/indra/newview/llviewerjointmesh_sse2.cpp index bfd8bb69b..5bcdb6224 100644 --- a/indra/newview/llviewerjointmesh_sse2.cpp +++ b/indra/newview/llviewerjointmesh_sse2.cpp @@ -101,8 +101,8 @@ void LLViewerJointMesh::updateGeometrySSE2(LLFace *face, LLPolyMesh *mesh) buffer->getNormalStrider(o_normals, mesh->mFaceVertexOffset); const F32* weights = mesh->getWeights(); - const LLVector3* coords = mesh->getCoords(); - const LLVector3* normals = mesh->getNormals(); + const LLVector4* coords = mesh->getCoords(); + const LLVector4* normals = mesh->getNormals(); for (U32 index = 0, index_end = mesh->getNumVertices(); index < index_end; ++index) { if( weight != weights[index]) @@ -110,8 +110,8 @@ void LLViewerJointMesh::updateGeometrySSE2(LLFace *face, LLPolyMesh *mesh) 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]); + blend_mat.multiply((const LLVector3)coords[index], o_vertices[index]); + ((LLV4Matrix3)blend_mat).multiply((const LLVector3)normals[index], o_normals[index]); } buffer->setBuffer(0); diff --git a/indra/newview/llviewerjointmesh_vec.cpp b/indra/newview/llviewerjointmesh_vec.cpp index 91b97b07d..6a7bb587b 100644 --- a/indra/newview/llviewerjointmesh_vec.cpp +++ b/indra/newview/llviewerjointmesh_vec.cpp @@ -84,8 +84,8 @@ void LLViewerJointMesh::updateGeometryVectorized(LLFace *face, LLPolyMesh *mesh) buffer->getNormalStrider(o_normals, mesh->mFaceVertexOffset); const F32* weights = mesh->getWeights(); - const LLVector3* coords = mesh->getCoords(); - const LLVector3* normals = mesh->getNormals(); + const LLVector4* coords = mesh->getCoords(); + const LLVector4* normals = mesh->getNormals(); for (U32 index = 0, index_end = mesh->getNumVertices(); index < index_end; ++index) { if( weight != weights[index]) @@ -93,8 +93,8 @@ void LLViewerJointMesh::updateGeometryVectorized(LLFace *face, LLPolyMesh *mesh) 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]); + blend_mat.multiply((const LLVector3)coords[index], o_vertices[index]); + ((LLV4Matrix3)blend_mat).multiply((const LLVector3)normals[index], o_normals[index]); } buffer->setBuffer(0); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index b5ca840ca..d86205019 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2207,6 +2207,33 @@ const LLMatrix4 LLVOVolume::getRenderMatrix() const return mDrawable->getWorldMatrix(); } +#if MESH_ENABLED +F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes) +{ + F32 radius = getScale().length()*0.5f; + + if (isMesh()) + { + LLSD& header = gMeshRepo.getMeshHeader(getVolume()->getParams().getSculptID()); + + return LLMeshRepository::getStreamingCost(header, radius, bytes, visible_bytes, mLOD); + } + else + { + LLVolume* volume = getVolume(); + S32 counts[4]; + LLVolume::getLoDTriangleCounts(volume->getParams(), counts); + + LLSD header; + header["lowest_lod"]["size"] = counts[0] * 10; + header["low_lod"]["size"] = counts[1] * 10; + header["medium_lod"]["size"] = counts[2] * 10; + header["high_lod"]["size"] = counts[3] * 10; + + return LLMeshRepository::getStreamingCost(header, radius); + } +} +#endif //MESH_ENABLED U32 LLVOVolume::getTriangleCount() { @@ -3403,6 +3430,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) { + llassert(group); static int warningsCount = 20; if (group && group->isState(LLSpatialGroup::MESH_DIRTY) && !group->isState(LLSpatialGroup::GEOM_DIRTY)) { @@ -3414,15 +3442,16 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) { LLDrawable* drawablep = *drawable_iter; - if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) + if (drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) { continue; } - if (drawablep->isState(LLDrawable::REBUILD_ALL)) + if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) ) { LLVOVolume* vobj = drawablep->getVOVolume(); vobj->preRebuild(); + LLVolume* volume = vobj->getVolume(); for (S32 i = 0; i < drawablep->getNumFaces(); ++i) { @@ -3489,6 +3518,8 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); } + + llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO)); } struct CompareBatchBreakerModified diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 3c2d5fba9..0e91880dc 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -132,7 +132,9 @@ public: const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; } /*virtual*/ const LLMatrix4 getRenderMatrix() const; - +#if MESH_ENABLED + /*virtual*/ F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL); +#endif //MESH_ENABLED /*virtual*/ U32 getTriangleCount(); /*virtual*/ U32 getHighLODTriangleCount(); /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 38cd00028..8103ebefb 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -7905,17 +7905,15 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gPipeline.pushRenderTypeMask(); gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::RENDER_TYPE_WL_CLOUDS, LLPipeline::END_RENDER_TYPES); + static LLCullResult result; updateCull(camera, result); stateSort(camera, result); - andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, - LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS, - LLPipeline::RENDER_TYPE_WL_CLOUDS, - LLPipeline::RENDER_TYPE_WL_SKY, - LLPipeline::END_RENDER_TYPES); renderGeom(camera, TRUE); + gPipeline.popRenderTypeMask(); } @@ -7925,7 +7923,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gPipeline.pushRenderTypeMask(); if (detail < 4) { - clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES); + clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS, END_RENDER_TYPES); if (detail < 3) { clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); @@ -7940,7 +7938,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLPipeline::RENDER_TYPE_VOIDWATER, LLPipeline::RENDER_TYPE_GROUND, LLPipeline::RENDER_TYPE_SKY, - LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS, LLPipeline::RENDER_TYPE_WL_CLOUDS, LLPipeline::END_RENDER_TYPES); static const LLCachedControl skip_distortion_updates("SkipReflectOcclusionUpdates",false); From b75a28ec15888a241888f2f5e6146a35ffa434b3 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Fri, 5 Aug 2011 01:18:27 -0500 Subject: [PATCH 03/10] Cleanup. Applied http://hg.secondlife.com/mesh-development/changeset/3031f266784a --- indra/llcommon/llstrider.h | 66 ++++++++++++++++++++++++++---- indra/llprimitive/llmodel.cpp | 13 ++++++ indra/llprimitive/llmodel.h | 23 +++++------ indra/llrender/llvertexbuffer.cpp | 11 ++--- indra/llrender/llvertexbuffer.h | 2 - indra/newview/llmeshrepository.cpp | 3 +- indra/newview/llvovolume.cpp | 14 +++---- 7 files changed, 92 insertions(+), 40 deletions(-) diff --git a/indra/llcommon/llstrider.h b/indra/llcommon/llstrider.h index 444820c67..2afaacf3b 100644 --- a/indra/llcommon/llstrider.h +++ b/indra/llcommon/llstrider.h @@ -42,13 +42,15 @@ template class LLStrider U8* mBytep; }; U32 mSkip; + U32 mTypeSize; public: - LLStrider() { mObjectp = NULL; mSkip = sizeof(Object); } + LLStrider() { mObjectp = NULL; mTypeSize = mSkip = sizeof(Object); } ~LLStrider() { } const LLStrider& operator = (Object *first) { mObjectp = first; return *this;} void setStride (S32 skipBytes) { mSkip = (skipBytes ? skipBytes : sizeof(Object));} + void setTypeSize (S32 typeBytes){ mTypeSize = (typeBytes ? typeBytes : sizeof(Object)); } void skip(const U32 index) { mBytep += mSkip*index;} U32 getSkip() const { return mSkip; } @@ -58,18 +60,68 @@ public: Object* operator ++(int) { Object* old = mObjectp; mBytep += mSkip; return old; } Object* operator +=(int i) { mBytep += mSkip*i; return mObjectp; } Object& operator[](U32 index) { return *(Object*)(mBytep + (mSkip * index)); } - void assignArray(U8* buff, size_t elem_size, size_t elem_count) + void assignArray(U8* __restrict source, const size_t elem_size, const size_t elem_count) { llassert_always(sizeof(Object) <= elem_size); - if(sizeof(Object) == mSkip && sizeof(Object) == elem_size) //No stride. No difference in element size. - LLVector4a::memcpyNonAliased16((F32*) mBytep, (F32*) buff, elem_size * elem_count); + + U8* __restrict dest = mBytep; //refer to dest instead of mBytep to benefit from __restrict hint + const U32 bytes = elem_size * elem_count; //total bytes to copy from source to dest + + //stride == sizeof(element) implies entire buffer is unstrided and thus memcpy-able, provided source buffer elements match in size. + //Because LLStrider is often passed an LLVector3 even if the reprensentation is LLVector4 in the vertex buffer, mTypeSize is set to + //the TRUE vbo datatype size via VertexBufferStrider::get + if(mTypeSize == mSkip && mTypeSize == elem_size) + { + if(bytes >= sizeof(LLVector4) * 4) //Should be able to pull at least 3 16byte blocks from this. Smaller isn't really beneficial. + { + U8* __restrict aligned_source = LL_NEXT_ALIGNED_ADDRESS(source); + U8* __restrict aligned_dest = LL_NEXT_ALIGNED_ADDRESS(dest); + const U32 source_offset = aligned_source - source; //Offset to first aligned location in source buffer. + const U32 dest_offset = aligned_dest - dest; //Offset to first aligned location in dest buffer. + llassert_always(source_offset < 16); + llassert_always(dest_offset < 16); + if(source_offset == dest_offset) //delta to aligned location matches between source and destination! _mm_*_ps should be viable. + { + const U32 end_offset = (bytes - source_offset) % sizeof(LLVector4); //buffers may not neatly end on a 16byte alignment boundary. + const U32 aligned_bytes = bytes - source_offset - end_offset; //how many bytes to copy from aligned start to aligned end. + + llassert_always(aligned_bytes > 0); + + if(source_offset) //memcpy up to the aligned location if needed + memcpy(dest,source,source_offset); + LLVector4a::memcpyNonAliased16((F32*) aligned_dest, (F32*) aligned_source, aligned_bytes); + if(end_offset) //memcpy to the very end if needed. + memcpy(aligned_dest+aligned_bytes,aligned_source+aligned_bytes,end_offset); + } + else //buffers non-uniformly offset from aligned location. Using _mm_*u_ps. + { + U32 end = bytes/sizeof(LLVector4); //sizeof(LLVector4) = 16 bytes = 128 bits + + llassert_always(end > 0); + + __m128* dst = (__m128*) dest; + __m128* src = (__m128*) source; + + for (U32 i = 0; i < end; i++) //copy 128bit chunks + { + __m128 res = _mm_loadu_ps((F32*)&src[i]); + _mm_storeu_ps((F32*)&dst[i], res); + } + end*=16;//Convert to real byte offset + if(end < bytes) //just memcopy the rest + memcpy(dest+end,source+end,bytes-end); + } + } + else //Too small. just do a simple memcpy. + memcpy(dest,source,bytes); + } else { for(U32 i=0;ifirst, pos ) ) + { + return iterPos->second; + } + } + + //2. Otherwise we'll use the older implementation weight_map::iterator iter = mSkinWeights.find(pos); if (iter != mSkinWeights.end()) diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index fe37d3420..58975e55b 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -223,20 +223,17 @@ public: }; - struct JointPositionalCompare + //Are the doubles the same w/in epsilon specified tolerance + bool areEqual( double a, double b ) { - //Are the doubles the same w/in epsilon specified tolerance - bool areEqual( double a, double b ) - { - const float epsilon = 1e-5f; - return (abs((int)(a - b)) < epsilon) && (a < b); - } - //Make sure that we return false for any values that are within the tolerance for equivalence - bool operator() ( const LLVector3& a, const LLVector3& b ) - { - return ( areEqual( a[0],b[0]) && areEqual( a[1],b[1] ) && areEqual( a[2],b[2]) ) ? false : true; - } - }; + const float epsilon = 1e-5f; + return (fabs((a - b)) < epsilon) ? true : false ; + } + //Make sure that we return false for any values that are within the tolerance for equivalence + bool jointPositionalLookup( const LLVector3& a, const LLVector3& b ) + { + return ( areEqual( a[0],b[0]) && areEqual( a[1],b[1] ) && areEqual( a[2],b[2]) ) ? true : false; + } //copy of position array for this model -- mPosition[idx].mV[X,Y,Z] std::vector mPosition; diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index e0c469544..301a3f056 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -1192,12 +1192,14 @@ template struct VertexBufferStrider strider = (T*)(ptr + index*sizeof(T)); strider.setStride(0); + strider.setTypeSize(0); return TRUE; } else if (vbo.hasDataType(type)) { S32 stride = vbo.getStride(); volatile U8* ptr = vbo.mapVertexBuffer(type); + S32 size = LLVertexBuffer::sTypeSize[type]; if (ptr == NULL) { @@ -1207,6 +1209,7 @@ template struct VertexBufferStrider strider = (T*)(ptr + vbo.getOffset(type) + index*stride); strider.setStride(stride); + strider.setTypeSize(size); return TRUE; } else @@ -1575,11 +1578,3 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const llglassertok(); } -void LLVertexBuffer::markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count) -{ - // TODO: use GL_APPLE_flush_buffer_range here - /*if (useVBOs() && !mFilthy) - { - - }*/ -} diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index f59f92518..fef966151 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -213,8 +213,6 @@ public: void setStride(S32 type, S32 new_stride); - void markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count); - void draw(U32 mode, U32 count, U32 indices_offset) const; void drawArrays(U32 mode, U32 offset, U32 count) const; void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index c67249ebf..86500e297 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -3180,7 +3180,8 @@ void LLPhysicsDecomp::doDecompositionSingleHull() return; #endif //!MESH_IMPORT #if MESH_IMPORT - + LLConvexDecomposition* decomp = LLConvexDecomposition::getInstance(); + if (decomp == NULL) { //stub. do nothing. diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index d86205019..3c040c5dd 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3678,12 +3678,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: U32 te_idx = facep->getTEOffset(); - if (facep->getGeometryVolume(*volume, te_idx, - vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset)) - { - buffer->markDirty(facep->getGeomIndex(), facep->getGeomCount(), - facep->getIndicesStart(), facep->getIndicesCount()); - } + facep->getGeometryVolume(*volume, te_idx, + vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset); } } @@ -3709,9 +3705,9 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: // can we safely treat this as an alpha mask? if (facep->canRenderAsMask()) { - const LLDrawable* drawablep = facep->getDrawable(); - const LLVOVolume* vobj = drawablep ? drawablep->getVOVolume() : NULL; - if (te->getFullbright() || (vobj && vobj->isHUDAttachment())) + //const LLDrawable* drawablep = facep->getDrawable(); + //const LLVOVolume* vobj = drawablep ? drawablep->getVOVolume() : NULL; + if (te->getFullbright() /*|| (vobj && vobj->isHUDAttachment())*/) { registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); } From 9cc398e939fdc0ce2e08b3e6f4f20accc3f020e4 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Fri, 5 Aug 2011 02:55:13 -0500 Subject: [PATCH 04/10] Occlusion now using LLVertexbuffer class. --- indra/newview/llspatialpartition.cpp | 256 ++++++++++----------------- indra/newview/llspatialpartition.h | 7 +- indra/newview/llvovolume.cpp | 4 +- 3 files changed, 98 insertions(+), 169 deletions(-) diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index abc281e0e..96db56418 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -115,23 +115,6 @@ void sg_assert(BOOL expr) #endif } -#if LL_DEBUG -void validate_drawable(LLDrawable* drawablep) -{ - F64 rad = drawablep->getBinRadius(); - const LLVector3* ext = drawablep->getSpatialExtents(); - - if (rad < 0 || rad > 4096 || - (ext[1]-ext[0]).magVec() > 4096) - { - llwarns << "Invalid drawable found in octree." << llendl; - } -} -#else -#define validate_drawable(x) -#endif - - S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad) { return AABBSphereIntersectR2(min, max, origin, rad*rad); @@ -277,38 +260,70 @@ U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center) void LLSpatialGroup::buildOcclusion() { - if (!mOcclusionVerts) + if (mOcclusionVerts.isNull()) { - mOcclusionVerts = new F32[8*3]; - } - LLVector3 bounds[2]; - bounds[0].set(mBounds[0].getF32ptr()); - bounds[1].set(mBounds[1].getF32ptr()); - LLVector3 r = bounds[1] + LLVector3(SG_OCCLUSION_FUDGE, SG_OCCLUSION_FUDGE, SG_OCCLUSION_FUDGE); - - for (U32 k = 0; k < 3; k++) - { - r.mV[k] = llmin(bounds[1].mV[k]+0.25f, r.mV[k]); - } - - F32* v = mOcclusionVerts; - F32* c = bounds[0].mV; - F32* s = r.mV; + mOcclusionVerts = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, + LLVertexBuffer::sUseStreamDraw ? mBufferUsage : 0); //if GL has a hard time with VBOs, don't use them for occlusion culling. + mOcclusionVerts->allocateBuffer(8, 64, true); - //vertex positions are encoded so the 3 bits of their vertex index - //correspond to their axis facing, with bit position 3,2,1 matching - //axis facing x,y,z, bit set meaning positive facing, bit clear - //meaning negative facing - v[0] = c[0]-s[0]; v[1] = c[1]-s[1]; v[2] = c[2]-s[2]; // 0 - 0000 - v[3] = c[0]-s[0]; v[4] = c[1]-s[1]; v[5] = c[2]+s[2]; // 1 - 0001 - v[6] = c[0]-s[0]; v[7] = c[1]+s[1]; v[8] = c[2]-s[2]; // 2 - 0010 - v[9] = c[0]-s[0]; v[10] = c[1]+s[1]; v[11] = c[2]+s[2]; // 3 - 0011 - - v[12] = c[0]+s[0]; v[13] = c[1]-s[1]; v[14] = c[2]-s[2]; // 4 - 0100 - v[15] = c[0]+s[0]; v[16] = c[1]-s[1]; v[17] = c[2]+s[2]; // 5 - 0101 - v[18] = c[0]+s[0]; v[19] = c[1]+s[1]; v[20] = c[2]-s[2]; // 6 - 0110 - v[21] = c[0]+s[0]; v[22] = c[1]+s[1]; v[23] = c[2]+s[2]; // 7 - 0111 + LLStrider idx; + mOcclusionVerts->getIndexStrider(idx); + for (U32 i = 0; i < 64; i++) + { + *idx++ = sOcclusionIndices[i]; + } + } + + LLVector4a fudge; + fudge.splat(SG_OCCLUSION_FUDGE); + + LLVector4a r; + r.setAdd(mBounds[1], fudge); + + LLStrider pos; + + { + //LLFastTimer t(LLFastTimer::FTM_BUILD_OCCLUSION); + mOcclusionVerts->getVertexStrider(pos); + } + + { + LLVector4a* v = (LLVector4a*) pos.get(); + + const LLVector4a& c = mBounds[0]; + const LLVector4a& s = r; + + static const LLVector4a octant[] = + { + LLVector4a(-1.f, -1.f, -1.f), + LLVector4a(-1.f, -1.f, 1.f), + LLVector4a(-1.f, 1.f, -1.f), + LLVector4a(-1.f, 1.f, 1.f), + + LLVector4a(1.f, -1.f, -1.f), + LLVector4a(1.f, -1.f, 1.f), + LLVector4a(1.f, 1.f, -1.f), + LLVector4a(1.f, 1.f, 1.f), + }; + + //vertex positions are encoded so the 3 bits of their vertex index + //correspond to their axis facing, with bit position 3,2,1 matching + //axis facing x,y,z, bit set meaning positive facing, bit clear + //meaning negative facing + + for (S32 i = 0; i < 8; ++i) + { + LLVector4a p; + p.setMul(s, octant[i]); + p.add(c); + v[i] = p; + } + } + + { + mOcclusionVerts->setBuffer(0); + } clearState(LLSpatialGroup::OCCLUSION_DIRTY); } @@ -374,7 +389,6 @@ LLSpatialGroup::~LLSpatialGroup() } } - delete [] mOcclusionVerts; mOcclusionVerts = NULL; LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); @@ -469,52 +483,6 @@ void LLSpatialGroup::checkStates() #endif } -void validate_draw_info(LLDrawInfo& params) -{ -#if LL_OCTREE_PARANOIA_CHECK - if (!params.mVertexBuffer) - { - llerrs << "Draw batch has no vertex buffer." << llendl; - } - - //bad range - if (params.mStart >= params.mEnd) - { - llerrs << "Draw batch has invalid range." << llendl; - } - - if (params.mEnd >= (U32) params.mVertexBuffer->getNumVerts()) - { - llerrs << "Draw batch has buffer overrun error." << llendl; - } - - if (params.mOffset + params.mCount > (U32) params.mVertexBuffer->getNumIndices()) - { - llerrs << "Draw batch has index buffer ovverrun error." << llendl; - } - - //bad indices - U16* indicesp = (U16*) params.mVertexBuffer->getIndicesPointer(); - if (indicesp) - { - for (U32 i = params.mOffset; i < params.mOffset+params.mCount; i++) - { - if (indicesp[i] < (U16)params.mStart) - { - llerrs << "Draw batch has vertex buffer index out of range error (index too low). " - << "indicesp["< (U16)params.mEnd) - { - llerrs << "Draw batch has vertex buffer index out of range error (index too high)." - << "indicesp["<updateSpatialExtents(); - validate_drawable(drawablep); OctreeNode* parent = mOctreeNode->getOctParent(); @@ -548,7 +515,6 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) unbound(); setState(OBJECT_DIRTY); //setState(GEOM_DIRTY); - validate_drawable(drawablep); return TRUE; } @@ -566,7 +532,6 @@ BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_oc else { drawablep->setSpatialGroup(this); - validate_drawable(drawablep); setState(OBJECT_DIRTY | GEOM_DIRTY); setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS); gPipeline.markRebuild(this, TRUE); @@ -839,7 +804,7 @@ void LLSpatialGroup::shift(const LLVector4a &offset) gPipeline.markRebuild(this, TRUE); } - if (mOcclusionVerts) + if (mOcclusionVerts.notNull()) { setState(OCCLUSION_DIRTY); } @@ -874,24 +839,16 @@ void LLSpatialGroup::setState(eSpatialState state) // if (LLSpatialPartition::sFreezeState) // return; mState |= state; - - if (state > LLSpatialGroup::STATE_MASK) - { - llerrs << "WTF?" << llendl; - } + + llassert(state <= LLSpatialGroup::STATE_MASK); } void LLSpatialGroup::setState(eSpatialState state, S32 mode) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); -// if (LLSpatialPartition::sFreezeState) -// return; - - if (state > LLSpatialGroup::STATE_MASK) - { - llerrs << "WTF?" << llendl; - } + llassert(state <= LLSpatialGroup::STATE_MASK); + if (mode > STATE_MODE_SINGLE) { if (mode == STATE_MODE_DIFF) @@ -937,25 +894,14 @@ public: void LLSpatialGroup::clearState(eSpatialState state) { -// if (LLSpatialPartition::sFreezeState) -// return; - if (state > LLSpatialGroup::STATE_MASK) - { - llerrs << "WTF?" << llendl; - } + llassert(state <= LLSpatialGroup::STATE_MASK); mState &= ~state; } void LLSpatialGroup::clearState(eSpatialState state, S32 mode) { - -// if (LLSpatialPartition::sFreezeState) -// return; - if (state > LLSpatialGroup::STATE_MASK) - { - llerrs << "WTF?" << llendl; - } + llassert(state <= LLSpatialGroup::STATE_MASK); LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); @@ -980,10 +926,7 @@ void LLSpatialGroup::clearState(eSpatialState state, S32 mode) BOOL LLSpatialGroup::isState(eSpatialState state) const { - if (state > LLSpatialGroup::STATE_MASK) - { - llerrs << "LLSpatialGroup::isState passed invalid state '" << state << "'" << llendl; - } + llassert(state <= LLSpatialGroup::STATE_MASK); return mState & state ? TRUE : FALSE; } @@ -1121,7 +1064,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : mOctreeNode(node), mSpatialPartition(part), mVertexBuffer(NULL), - mBufferUsage(GL_STATIC_DRAW_ARB), + mBufferUsage(part->mBufferUsage), mDistance(0.f), mDepth(0.f), mLastUpdateDistance(-1.f), @@ -1399,7 +1342,6 @@ void LLSpatialGroup::destroyGL() } } - delete [] mOcclusionVerts; mOcclusionVerts = NULL; for (LLSpatialGroup::element_iter i = getData().begin(); i != getData().end(); ++i) @@ -1573,7 +1515,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate(); } - if (!mOcclusionVerts || isState(LLSpatialGroup::OCCLUSION_DIRTY)) + if (mOcclusionVerts.isNull() || isState(LLSpatialGroup::OCCLUSION_DIRTY)) { buildOcclusion(); } @@ -1600,37 +1542,32 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) { //LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS); glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]); - glVertexPointer(3, GL_FLOAT, 0, mOcclusionVerts); + + mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX); + if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER) { LLGLSquashToFarClip squash(glh_get_current_projection(), 1); if (camera->getOrigin().isExactlyZero()) { //origin is invalid, draw entire box - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, sOcclusionIndices); - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, sOcclusionIndices+b111*8); + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8); } else { - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, mBounds[0])); + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); } } else { if (camera->getOrigin().isExactlyZero()) { //origin is invalid, draw entire box - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, sOcclusionIndices); - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, sOcclusionIndices+b111*8); - + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8); } else { - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, mBounds[0])); + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); } } @@ -1689,7 +1626,6 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); drawablep->updateSpatialExtents(); - validate_drawable(drawablep); //keep drawable from being garbage collected LLPointer ptr = drawablep; @@ -1988,11 +1924,8 @@ public: virtual void processGroup(LLSpatialGroup* group) { - if (group->isState(LLSpatialGroup::DIRTY) || group->getData().empty()) - { - llerrs << "WTF?" << llendl; - } - + llassert(!group->isState(LLSpatialGroup::DIRTY) && !group->getData().empty()) + if (mRes < 2) { if (mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]) > 0) @@ -2356,6 +2289,8 @@ void pushVerts(LLSpatialGroup* group, U32 mask) void pushVerts(LLFace* face, U32 mask) { + llassert(face->verify()); + LLVertexBuffer* buffer = face->getVertexBuffer(); if (buffer) @@ -3159,7 +3094,6 @@ public: { renderAgentTarget(avatar); } - } for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) @@ -3550,18 +3484,9 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, mFace(NULL), mDistance(0.f) { - mDebugColor = (rand() << 16) + rand(); - if (mStart >= mVertexBuffer->getRequestedVerts() || - mEnd >= mVertexBuffer->getRequestedVerts()) - { - llerrs << "Invalid draw info vertex range." << llendl; - } + mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset); - if (mOffset >= (U32) mVertexBuffer->getRequestedIndices() || - mOffset + mCount > (U32) mVertexBuffer->getRequestedIndices()) - { - llerrs << "Invalid draw info index range." << llendl; - } + mDebugColor = (rand() << 16) + rand(); } LLDrawInfo::~LLDrawInfo() @@ -3582,6 +3507,11 @@ LLDrawInfo::~LLDrawInfo() } } +void LLDrawInfo::validate() +{ + mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset); +} + LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage) { return new LLVertexBuffer(type_mask, usage); diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index bc11da84d..56e5ca2e5 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -88,6 +88,7 @@ public: BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0); + void validate(); LLVector4a mExtents[2]; @@ -361,9 +362,9 @@ public: F32 mBuilt; OctreeNode* mOctreeNode; LLSpatialPartition* mSpatialPartition; - + LLPointer mVertexBuffer; - F32* mOcclusionVerts; + LLPointer mOcclusionVerts; GLuint mOcclusionQuery[LLViewerCamera::NUM_CAMERAS]; U32 mBufferUsage; @@ -694,8 +695,6 @@ public: virtual void shift(const LLVector4a &offset); }; -void validate_draw_info(LLDrawInfo& params); - extern const F32 SG_BOX_SIDE; extern const F32 SG_BOX_OFFSET; extern const F32 SG_BOX_RAD; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 3c040c5dd..6062461a5 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2942,7 +2942,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_vec[idx]->mCount += facep->getIndicesCount(); draw_vec[idx]->mEnd += facep->getGeomCount(); draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize()); - validate_draw_info(*draw_vec[idx]); + draw_vec[idx]->validate(); update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[0]); update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[1]); } @@ -2966,7 +2966,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, } draw_info->mExtents[0] = facep->mExtents[0]; draw_info->mExtents[1] = facep->mExtents[1]; - validate_draw_info(*draw_info); + draw_info->validate(); } } From 7bcd259821fa0462160ff720a1d13d1202ceb2b5 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Fri, 5 Aug 2011 19:24:17 -0500 Subject: [PATCH 05/10] Added ShyotlRenderVBOStrideMode to toggle between strided and unstrided VBOs. --- indra/llrender/llvertexbuffer.cpp | 143 +++++++++++++++--------- indra/llrender/llvertexbuffer.h | 33 +++--- indra/newview/app_settings/settings.xml | 16 ++- indra/newview/lldrawpoolavatar.cpp | 12 +- indra/newview/llviewercontrol.cpp | 1 + indra/newview/llvosurfacepatch.cpp | 72 ++++++++++-- indra/newview/llvovolume.cpp | 6 +- indra/newview/llvowlsky.cpp | 2 +- indra/newview/pipeline.cpp | 2 + 9 files changed, 197 insertions(+), 90 deletions(-) diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 301a3f056..2837cd6af 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -66,6 +66,7 @@ BOOL LLVertexBuffer::sIBOActive = FALSE; U32 LLVertexBuffer::sAllocatedBytes = 0; BOOL LLVertexBuffer::sMapped = FALSE; BOOL LLVertexBuffer::sUseStreamDraw = TRUE; +U32 LLVertexBuffer::sForceStrideMode = 0; BOOL LLVertexBuffer::sOmitBlank = FALSE; BOOL LLVertexBuffer::sPreferStreamDraw = FALSE; S32 LLVertexBuffer::sWeight4Loc = -1; @@ -263,7 +264,8 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) void LLVertexBuffer::drawArrays(U32 mode, const std::vector& pos, const std::vector& norm) { U32 count = pos.size(); - llassert(norm.size() >= pos.size()); + llassert_always(norm.size() >= pos.size()); + llassert_always(count > 0) ; unbind(); @@ -448,7 +450,7 @@ void LLVertexBuffer::clientCopy(F64 max_time) //---------------------------------------------------------------------------- -LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : +LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage, bool strided) : LLRefCount(), mNumVerts(0), @@ -466,7 +468,9 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mFilthy(FALSE), mEmpty(TRUE), mResized(FALSE), - mDynamicSize(FALSE) + mDynamicSize(FALSE), + mIsStrided(strided), + mStride(0) { LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); if (!sEnableVBOs) @@ -483,20 +487,27 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : { mUsage = GL_STREAM_DRAW_ARB; } - - S32 stride = calcStride(typemask, mOffsets); + + //zero out offsets + for (U32 i = 0; i < TYPE_MAX; i++) + { + mOffsets[i] = 0; + } mTypeMask = typemask; - mStride = stride; + mSize = 0; mAlignedOffset = 0; mAlignedIndexOffset = 0; + + if(sForceStrideMode) + mIsStrided = sForceStrideMode == 1; + sCount++; } -//static -S32 LLVertexBuffer::calcStride(const U32& typemask, S32* offsets) +S32 LLVertexBuffer::calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices) { - S32 stride = 0; + S32 offset = 0; for (S32 i=0; i(src); mAlignedIndexOffset = mMappedIndexData - src; stop_glerror(); @@ -1095,7 +1146,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 access) sMappedCount++; } - return mMappedIndexData ; + return mMappedIndexData + sizeof(U16)*index; } void LLVertexBuffer::unmapBuffer(S32 type) @@ -1182,7 +1233,7 @@ template struct VertexBufferStrider { if (type == LLVertexBuffer::TYPE_INDEX) { - volatile U8* ptr = vbo.mapIndexBuffer(); + volatile U8* ptr = vbo.mapIndexBuffer(index); if (ptr == NULL) { @@ -1190,16 +1241,16 @@ template struct VertexBufferStrider return FALSE; } - strider = (T*)(ptr + index*sizeof(T)); + strider = (T*)ptr; strider.setStride(0); strider.setTypeSize(0); return TRUE; } else if (vbo.hasDataType(type)) { - S32 stride = vbo.getStride(); - volatile U8* ptr = vbo.mapVertexBuffer(type); - S32 size = LLVertexBuffer::sTypeSize[type]; + S32 stride = vbo.getStride(type); + + volatile U8* ptr = vbo.mapVertexBuffer(type,index); if (ptr == NULL) { @@ -1207,9 +1258,11 @@ template struct VertexBufferStrider return FALSE; } - strider = (T*)(ptr + vbo.getOffset(type) + index*stride); + + strider = (T*)ptr; + strider.setStride(stride); - strider.setTypeSize(size); + strider.setTypeSize(LLVertexBuffer::sTypeSize[type]); return TRUE; } else @@ -1272,25 +1325,6 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider& strider, S32 in return VertexBufferStrider::get(*this, strider, index); } -void LLVertexBuffer::setStride(S32 type, S32 new_stride) -{ - LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); - if (mNumVerts) - { - llerrs << "LLVertexBuffer::setOffset called with mNumVerts = " << mNumVerts << llendl; - } - // This code assumes that setStride() will only be called once per VBO per type. - S32 delta = new_stride - sTypeSize[type]; - for (S32 i=type+1; iValue 0 - ResetFocusOnSelfClick + ShyotlRenderVBOStrideMode + + Comment + 0 = Standard behavior +1 = Force strided VBOs +2 = Force unstrided(dense) VBOs + Persist + 1 + Type + U32 + Value + 0 + + + ResetFocusOnSelfClick Comment Setting this to TRUE resets your camera when you left-click your avatar diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 60a831472..b3cd43bc6 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1806,20 +1806,20 @@ void LLVertexBufferAvatar::setupVertexBuffer(U32 data_mask) const { volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData; - glVertexPointer(3,GL_FLOAT, mStride, (void*)(base + 0)); - glNormalPointer(GL_FLOAT, mStride, (void*)(base + mOffsets[TYPE_NORMAL])); - glTexCoordPointer(2,GL_FLOAT, mStride, (void*)(base + mOffsets[TYPE_TEXCOORD0])); + glVertexPointer(3,GL_FLOAT, getStride(TYPE_VERTEX), (void*)(base + 0)); + glNormalPointer(GL_FLOAT, getStride(TYPE_NORMAL), (void*)(base + mOffsets[TYPE_NORMAL])); + glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD0), (void*)(base + mOffsets[TYPE_TEXCOORD0])); - set_vertex_weights(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT], mStride, (F32*)(base + mOffsets[TYPE_WEIGHT])); + set_vertex_weights(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT], getStride(TYPE_WEIGHT), (F32*)(base + mOffsets[TYPE_WEIGHT])); if (sShaderLevel >= LLDrawPoolAvatar::SHADER_LEVEL_BUMP) { - set_binormals(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::BINORMAL], mStride, (LLVector3*)(base + mOffsets[TYPE_BINORMAL])); + set_binormals(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::BINORMAL], getStride(TYPE_BINORMAL), (LLVector3*)(base + mOffsets[TYPE_BINORMAL])); } if (sShaderLevel >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH) { - set_vertex_clothing_weights(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_CLOTHING], mStride, (LLVector4*)(base + mOffsets[TYPE_CLOTHWEIGHT])); + set_vertex_clothing_weights(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_CLOTHING], getStride(TYPE_CLOTHWEIGHT), (LLVector4*)(base + mOffsets[TYPE_CLOTHWEIGHT])); } } else diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index a58d38329..e19923f5a 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -646,6 +646,7 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); //See LL jira VWR-3258 comment section. Implemented by LL in 2.1 -Shyotl gSavedSettings.getControl("ShyotlRenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); + gSavedSettings.getControl("ShyotlRenderVBOStrideMode")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("SianaRenderOmitBlankVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderUseFBO")->getSignal()->connect(boost::bind(&handleRenderUseFBOChanged, _2)); gSavedSettings.getControl("RenderDeferredNoise")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 3d36a99fe..1f0365761 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -64,23 +64,75 @@ public: mTypeMask |= MAP_TEXCOORD2 | MAP_TEXCOORD3; }; - /*// virtual + // virtual void setupVertexBuffer(U32 data_mask) const - { - if (LLDrawPoolTerrain::getDetailMode() == 0 || LLPipeline::sShadowRender) + { + volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData; + + //assume tex coords 2 and 3 are present + U32 type_mask = mTypeMask | MAP_TEXCOORD2 | MAP_TEXCOORD3; + + if ((data_mask & type_mask) != data_mask) { - LLVertexBuffer::setupVertexBuffer(data_mask); + llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl; } - else if (data_mask & LLVertexBuffer::MAP_TEXCOORD1) + + if (data_mask & MAP_NORMAL) { - LLVertexBuffer::setupVertexBuffer(data_mask); + glNormalPointer(GL_FLOAT, getStride(TYPE_NORMAL), (void*)(base + mOffsets[TYPE_NORMAL])); } - else + if (data_mask & MAP_TEXCOORD3) + { //substitute tex coord 0 for tex coord 3 + glClientActiveTextureARB(GL_TEXTURE3_ARB); + glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD0), (void*)(base + mOffsets[TYPE_TEXCOORD0])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } + if (data_mask & MAP_TEXCOORD2) + { //substitute tex coord 0 for tex coord 2 + glClientActiveTextureARB(GL_TEXTURE2_ARB); + glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD0), (void*)(base + mOffsets[TYPE_TEXCOORD0])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } + if (data_mask & MAP_TEXCOORD1) { - LLVertexBuffer::setupVertexBuffer(data_mask); + glClientActiveTextureARB(GL_TEXTURE1_ARB); + glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD1), (void*)(base + mOffsets[TYPE_TEXCOORD1])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); } - llglassertok(); - }*/ + if (data_mask & MAP_BINORMAL) + { + glClientActiveTextureARB(GL_TEXTURE2_ARB); + glTexCoordPointer(3,GL_FLOAT, getStride(TYPE_BINORMAL), (void*)(base + mOffsets[TYPE_BINORMAL])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } + if (data_mask & MAP_TEXCOORD0) + { + glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD0), (void*)(base + mOffsets[TYPE_TEXCOORD0])); + } + if (data_mask & MAP_COLOR) + { + glColorPointer(4, GL_UNSIGNED_BYTE, getStride(TYPE_COLOR), (void*)(base + mOffsets[TYPE_COLOR])); + } + + if (data_mask & MAP_WEIGHT) + { + glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, getStride(TYPE_WEIGHT), (void*)(base + mOffsets[TYPE_WEIGHT])); + } + + if (data_mask & MAP_WEIGHT4 && sWeight4Loc != -1) + { + glVertexAttribPointerARB(sWeight4Loc, 4, GL_FLOAT, FALSE, getStride(TYPE_WEIGHT4), (void*)(base+mOffsets[TYPE_WEIGHT4])); + } + + if (data_mask & MAP_CLOTHWEIGHT) + { + glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE, getStride(TYPE_CLOTHWEIGHT), (void*)(base + mOffsets[TYPE_CLOTHWEIGHT])); + } + if (data_mask & MAP_VERTEX) + { + glVertexPointer(3,GL_FLOAT, getStride(TYPE_VERTEX), (void*)(base + 0)); + } + } }; //============================================================================ diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 6062461a5..5ae0c27ba 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3048,8 +3048,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) static const LLCachedControl render_max_vbo_size("RenderMaxVBOSize", 512); static const LLCachedControl render_max_node_size("RenderMaxNodeSize",8192); - U32 max_vertices = (render_max_vbo_size*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask); - U32 max_total = (render_max_node_size*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask); + U32 max_vertices = (render_max_vbo_size*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); + U32 max_total = (render_max_node_size*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); max_vertices = llmin(max_vertices, (U32) 65535); U32 cur_total = 0; @@ -3552,7 +3552,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: { //calculate maximum number of vertices to store in a single buffer static const LLCachedControl render_max_vbo_size("RenderMaxVBOSize", 512); - U32 max_vertices = (render_max_vbo_size*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask); + U32 max_vertices = (render_max_vbo_size*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); max_vertices = llmin(max_vertices, (U32) 65535); if (!distance_sort) diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index 8d63b069c..92bc8b65f 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -336,7 +336,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) { const U32 max_buffer_bytes = gSavedSettings.getS32("RenderMaxVBOSize")*1024; const U32 data_mask = LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK; - const U32 max_verts = max_buffer_bytes / LLVertexBuffer::calcStride(data_mask); + const U32 max_verts = max_buffer_bytes / LLVertexBuffer::calcVertexSize(data_mask); const U32 total_stacks = getNumStacks(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 8103ebefb..e8376c57e 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -372,6 +372,7 @@ void LLPipeline::init() sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("ShyotlRenderUseStreamVBO"); + LLVertexBuffer::sForceStrideMode = gSavedSettings.getU32("ShyotlRenderVBOStrideMode"); LLVertexBuffer::sOmitBlank = gSavedSettings.getBOOL("SianaRenderOmitBlankVBO"); LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw"); sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights"); @@ -5822,6 +5823,7 @@ void LLPipeline::resetVertexBuffers() { sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("ShyotlRenderUseStreamVBO"); + LLVertexBuffer::sForceStrideMode = gSavedSettings.getU32("ShyotlRenderVBOStrideMode"); LLVertexBuffer::sOmitBlank = gSavedSettings.getBOOL("SianaRenderOmitBlankVBO"); for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) From f9bcbab5f3278bb62b7d2853f369f6312a55bece Mon Sep 17 00:00:00 2001 From: Shyotl Date: Fri, 5 Aug 2011 21:39:43 -0500 Subject: [PATCH 06/10] Win compile fix. Including stdint.h explodes in vc2010, so #if'd it out for windows. --- indra/llcommon/llmemory.h | 2 ++ indra/newview/lltexturefetch.cpp | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 35cee6653..99aec9997 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -35,7 +35,9 @@ #include #include +#if !LL_WINDOWS #include // uintptr_t +#endif #include "llerror.h" diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index d24bff56b..8caf60b02 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1276,9 +1276,9 @@ bool LLTextureFetchWorker::doWork(S32 param) // static const LLCachedControl max_http_requests("HTTPMaxRequests", 32); static const LLCachedControl min_http_requests("HTTPMinRequests", 2); - if((mFetcher->getNumHTTPRequests() > max_http_requests) || + if(((U32)mFetcher->getNumHTTPRequests() > max_http_requests) || ((mFetcher->getTextureBandwidth() > mFetcher->mMaxBandwidth) && - (mFetcher->getNumHTTPRequests() > min_http_requests)) || + ((U32)mFetcher->getNumHTTPRequests() > min_http_requests)) || !sgConnectionThrottle()) { return false ; //wait. From f1759e0a968355df9ce800a42ebb8bc0759839d8 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sat, 6 Aug 2011 02:27:06 -0500 Subject: [PATCH 07/10] Old-code related to sim-quota cleaned up. --- indra/llcommon/CMakeLists.txt | 2 +- ...llaccountingquota.h => llaccountingcost.h} | 24 +- indra/llinventory/llparcel.cpp | 10 - indra/llinventory/llparcel.h | 11 +- indra/newview/CMakeLists.txt | 4 +- indra/newview/llaccountingcostmanager.cpp | 173 +++++++++++ ...otamanager.h => llaccountingcostmanager.h} | 20 +- indra/newview/llaccountingquotamanager.cpp | 281 ------------------ indra/newview/llfloatertools.cpp | 1 - indra/newview/llmeshrepository.cpp | 16 +- indra/newview/llviewerobject.cpp | 6 - indra/newview/llviewerobject.h | 9 - indra/newview/llviewerobjectlist.cpp | 9 - indra/newview/llviewerobjectlist.h | 1 - indra/newview/llviewerregion.cpp | 138 +++++---- 15 files changed, 296 insertions(+), 409 deletions(-) rename indra/llcommon/{llaccountingquota.h => llaccountingcost.h} (85%) create mode 100644 indra/newview/llaccountingcostmanager.cpp rename indra/newview/{llaccountingquotamanager.h => llaccountingcostmanager.h} (76%) delete mode 100644 indra/newview/llaccountingquotamanager.cpp diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index e7ce0fa9d..c72b4d277 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -96,7 +96,7 @@ set(llcommon_HEADER_FILES indra_constants.h linden_common.h linked_lists.h - llaccountingquota.h + llaccountingcost.h llagentconstants.h llavatarname.h llapp.h diff --git a/indra/llcommon/llaccountingquota.h b/indra/llcommon/llaccountingcost.h similarity index 85% rename from indra/llcommon/llaccountingquota.h rename to indra/llcommon/llaccountingcost.h index 140333de0..0ef3b50c6 100644 --- a/indra/llcommon/llaccountingquota.h +++ b/indra/llcommon/llaccountingcost.h @@ -1,5 +1,5 @@ /** - * @file llaccountingquota.h + * @file llaccountingcost.h * @ * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ @@ -58,22 +58,28 @@ struct ParcelQuota F32 mParcelCapacity; }; -struct SelectionQuota +//SelectionQuota atm does not require a id +struct SelectionCost { - SelectionQuota( LLUUID localId, F32 renderCost, F32 physicsCost, F32 networkCost, F32 simulationCost ) - : mLocalId( localId) - , mRenderCost( renderCost ) - , mPhysicsCost( physicsCost ) + SelectionCost( /*LLTransactionID transactionId, */ F32 physicsCost, F32 networkCost, F32 simulationCost ) + //: mTransactionId( transactionId) + : mPhysicsCost( physicsCost ) , mNetworkCost( networkCost ) , mSimulationCost( simulationCost ) { } - SelectionQuota() {} + SelectionCost() + : mPhysicsCost( 0.0f ) + , mNetworkCost( 0.0f ) + , mSimulationCost( 0.0f ) + {} - F32 mRenderCost, mPhysicsCost, mNetworkCost, mSimulationCost; - LLUUID mLocalId; + F32 mPhysicsCost, mNetworkCost, mSimulationCost; + //LLTransactionID mTransactionId; }; +typedef enum { Roots = 0 , Prims } eSelectionType; + #endif diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp index 432cb3e61..c167ef194 100644 --- a/indra/llinventory/llparcel.cpp +++ b/indra/llinventory/llparcel.cpp @@ -1354,13 +1354,3 @@ LLParcel::ECategory category_ui_string_to_category(const std::string& s) // is a distinct option from "None" and "Other" return LLParcel::C_ANY; } - -#if MESH_ENABLED -void LLParcel::updateQuota( const LLUUID& objectId, const ParcelQuota& quota ) -{ - if ( mID == objectId ) - { - mQuota = quota; - } -} -#endif //MESH_ENABLED diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h index 7d92d4b37..7423229f7 100644 --- a/indra/llinventory/llparcel.h +++ b/indra/llinventory/llparcel.h @@ -40,9 +40,6 @@ #include "llpermissions.h" #include "lltimer.h" #include "v3math.h" -#if MESH_ENABLED -#include "llaccountingquota.h" -#endif //MESH_ENABLED // Grid out of which parcels taken is stepped every 4 meters. const F32 PARCEL_GRID_STEP_METERS = 4.f; @@ -602,10 +599,7 @@ public: BOOL getPreviouslyGroupOwned() const { return mPreviouslyGroupOwned; } BOOL getSellWithObjects() const { return (mParcelFlags & PF_SELL_PARCEL_OBJECTS) ? TRUE : FALSE; } -#if MESH_ENABLED - void updateQuota( const LLUUID& objectId, const ParcelQuota& quota ); - const ParcelQuota& getQuota( void ) { return mQuota; } -#endif //MESH_ENABLED + protected: LLUUID mID; LLUUID mOwnerID; @@ -678,9 +672,6 @@ protected: BOOL mRegionPushOverride; BOOL mRegionDenyAnonymousOverride; BOOL mRegionDenyAgeUnverifiedOverride; -#if MESH_ENABLED - ParcelQuota mQuota; -#endif //MESH_ENABLED public: // HACK, make private diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 7109b8169..3062e3b0e 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -100,7 +100,7 @@ set(viewer_SOURCE_FILES jcfloaterareasearch.cpp chatbar_as_cmdline.cpp qtoolalign.cpp - llaccountingquotamanager.cpp + llaccountingcostmanager.cpp llagent.cpp llagentaccess.cpp llagentcamera.cpp @@ -580,7 +580,7 @@ set(viewer_HEADER_FILES lgghunspell_wrapper.h chatbar_as_cmdline.h qtoolalign.h - llaccountingquotamanager.h + llaccountingcostmanager.h llagent.h llagentaccess.h llagentcamera.h diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp new file mode 100644 index 000000000..61a0b6932 --- /dev/null +++ b/indra/newview/llaccountingcostmanager.cpp @@ -0,0 +1,173 @@ +/** + * @file LLAccountingQuotaManager.cpp + * @ Handles the setting and accessing for costs associated with mesh + * + * $LicenseInfo:firstyear=2001&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$ + */ + +#include "llviewerprecompiledheaders.h" +#if MESH_ENABLED +#include "llaccountingcostmanager.h" +#include "llagent.h" +#include "llcurl.h" +#include "llhttpclient.h" + +//=============================================================================== +LLAccountingCostManager::LLAccountingCostManager() +{ +} +//=============================================================================== +class LLAccountingCostResponder : public LLCurl::Responder +{ +public: + LLAccountingCostResponder( const LLSD& objectIDs ) + : mObjectIDs( objectIDs ) + { + } + + void clearPendingRequests ( void ) + { + for ( LLSD::array_iterator iter = mObjectIDs.beginArray(); iter != mObjectIDs.endArray(); ++iter ) + { + LLAccountingCostManager::getInstance()->removePendingObject( iter->asUUID() ); + } + } + + void error( U32 statusNum, const std::string& reason ) + { + llwarns << "Transport error "< 0 ) + { + std::string keystr; + if ( selectionType == Roots ) + { + keystr="selected_roots"; + } + else + if ( selectionType == Prims ) + { + keystr="prim_roots"; + } + else + { + llinfos<<"Invalid selection type "< +class LLAccountingCostManager : public LLSingleton { public: //Ctor - LLAccountingQuotaManager(); + LLAccountingCostManager(); //Store an object that will be eventually fetched - void updateObjectCost( const LLUUID& objectID ); + void addObject( const LLUUID& objectID ); //Request quotas for object list - void fetchQuotas( const std::string& url ); + void fetchCosts( eSelectionType selectionType, const std::string& url ); //Delete a specific object from the pending list - void removePendingObjectQuota( const LLUUID& objectID ); + void removePendingObject( const LLUUID& objectID ); private: - //Set of objects that need to update their cost - std::set mUpdateObjectQuota; - //During fetchQuota we move object into a the pending set to signify that + //Set of objects that will be used to generate a cost + std::set mObjectList; + //During fetchCosts we move object into a the pending set to signify that //a fetch has been instigated. std::set mPendingObjectQuota; typedef std::set::iterator IDIt; }; //=============================================================================== -#endif // LLACCOUNTINGQUOTAMANAGER +#endif // LLACCOUNTINGCOSTMANAGER diff --git a/indra/newview/llaccountingquotamanager.cpp b/indra/newview/llaccountingquotamanager.cpp deleted file mode 100644 index 44d5b7e71..000000000 --- a/indra/newview/llaccountingquotamanager.cpp +++ /dev/null @@ -1,281 +0,0 @@ -/** - * @file LLAccountingQuotaManager.cpp - * @ Handles the setting and accessing for costs associated with mesh - * - * $LicenseInfo:firstyear=2001&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$ - */ - -#include "llviewerprecompiledheaders.h" -#if MESH_ENABLED -#include "llaccountingquotamanager.h" -#include "llagent.h" -#include "llviewerregion.h" -#include "llviewerobject.h" -#include "llviewerobjectlist.h" -#include "llviewerparcelmgr.h" -#include "llparcel.h" - -//=============================================================================== -LLAccountingQuotaManager::LLAccountingQuotaManager() -{ -} -//=============================================================================== -class LLAccountingQuotaResponder : public LLCurl::Responder -{ -public: - LLAccountingQuotaResponder( const LLSD& objectIDs ) - : mObjectIDs( objectIDs ) - { - } - - void clearPendingRequests ( void ) - { - for ( LLSD::array_iterator iter = mObjectIDs.beginArray(); iter != mObjectIDs.endArray(); ++iter ) - { - LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( iter->asUUID() ); - } - } - - void error( U32 statusNum, const std::string& reason ) - { - llwarns << "Transport error "<asUUID(); - - LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( objectID ); - - if ( containsParcel ) - { - //Typically should be one - S32 dataCount = content["parcel"].size(); - for(S32 i = 0; i < dataCount; i++) - { - //prep#todo verify that this is safe, otherwise just add a bool - LLUUID parcelId; - //S32 parcelOwner = 0; - if ( content["parcel"][i].has("parcel_id") ) - { - parcelId = content["parcel"][i]["parcel_id"].asUUID(); - } - - //if ( content["parcel"][i].has("parcel_owner") ) - //{ - // parcelOwner = content["parcel"][i]["parcel_owner"].asInteger(); - //} - - F32 ownerRenderCost = 0; - F32 ownerPhysicsCost = 0; - F32 ownerNetworkCost = 0; - F32 ownerSimulationCost = 0; - - F32 groupRenderCost = 0; - F32 groupPhysicsCost = 0; - F32 groupNetworkCost = 0; - F32 groupSimulationCost = 0; - - F32 otherRenderCost = 0; - F32 otherPhysicsCost = 0; - F32 otherNetworkCost = 0; - F32 otherSimulationCost = 0; - - F32 tempRenderCost = 0; - F32 tempPhysicsCost = 0; - F32 tempNetworkCost = 0; - F32 tempSimulationCost = 0; - - F32 selectedRenderCost = 0; - F32 selectedPhysicsCost = 0; - F32 selectedNetworkCost = 0; - F32 selectedSimulationCost = 0; - - F32 parcelCapacity = 0; - - if ( content["parcel"][i].has("capacity") ) - { - parcelCapacity = content["parcel"][i].has("capacity"); - } - - if ( content["parcel"][i].has("owner") ) - { - ownerRenderCost = content["parcel"][i]["owner"]["rendering"].asReal(); - ownerPhysicsCost = content["parcel"][i]["owner"]["physics"].asReal(); - ownerNetworkCost = content["parcel"][i]["owner"]["streaming"].asReal(); - ownerSimulationCost = content["parcel"][i]["owner"]["simulation"].asReal(); - } - - if ( content["parcel"][i].has("group") ) - { - groupRenderCost = content["parcel"][i]["group"]["rendering"].asReal(); - groupPhysicsCost = content["parcel"][i]["group"]["physics"].asReal(); - groupNetworkCost = content["parcel"][i]["group"]["streaming"].asReal(); - groupSimulationCost = content["parcel"][i]["group"]["simulation"].asReal(); - - } - if ( content["parcel"][i].has("other") ) - { - otherRenderCost = content["parcel"][i]["other"]["rendering"].asReal(); - otherPhysicsCost = content["parcel"][i]["other"]["physics"].asReal(); - otherNetworkCost = content["parcel"][i]["other"]["streaming"].asReal(); - otherSimulationCost = content["parcel"][i]["other"]["simulation"].asReal(); - } - - if ( content["parcel"][i].has("temp") ) - { - tempRenderCost = content["parcel"][i]["total"]["rendering"].asReal(); - tempPhysicsCost = content["parcel"][i]["total"]["physics"].asReal(); - tempNetworkCost = content["parcel"][i]["total"]["streaming"].asReal(); - tempSimulationCost = content["parcel"][i]["total"]["simulation"].asReal(); - } - - if ( content["parcel"][i].has("selected") ) - { - selectedRenderCost = content["parcel"][i]["total"]["rendering"].asReal(); - selectedPhysicsCost = content["parcel"][i]["total"]["physics"].asReal(); - selectedNetworkCost = content["parcel"][i]["total"]["streaming"].asReal(); - selectedSimulationCost = content["parcel"][i]["total"]["simulation"].asReal(); - } - - ParcelQuota parcelQuota( ownerRenderCost, ownerPhysicsCost, ownerNetworkCost, ownerSimulationCost, - groupRenderCost, groupPhysicsCost, groupNetworkCost, groupSimulationCost, - otherRenderCost, otherPhysicsCost, otherNetworkCost, otherSimulationCost, - tempRenderCost, tempPhysicsCost, tempNetworkCost, tempSimulationCost, - selectedRenderCost, selectedPhysicsCost, selectedNetworkCost, selectedSimulationCost, - parcelCapacity ); - //Update the Parcel - LLParcel* pParcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel(); - if ( pParcel ) - { - pParcel->updateQuota( objectID, parcelQuota ); - } - } - } - else - if ( containsSelection ) - { - S32 dataCount = content["selected"].size(); - for(S32 i = 0; i < dataCount; i++) - { - - F32 renderCost = 0; - F32 physicsCost = 0; - F32 networkCost = 0; - F32 simulationCost = 0; - - LLUUID objectId; - - objectId = content["selected"][i]["local_id"].asUUID(); - renderCost = content["selected"][i]["rendering"].asReal(); - physicsCost = content["selected"][i]["physics"].asReal(); - networkCost = content["selected"][i]["streaming"].asReal(); - simulationCost = content["selected"][i]["simulation"].asReal(); - - SelectionQuota selectionQuota( objectId, renderCost, physicsCost, networkCost, simulationCost ); - - //Update the objects - gObjectList.updateQuota( objectId, selectionQuota ); - - } - } - else - { - //Nothing in string - LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( objectID ); - } - } - } - -private: - //List of posted objects - LLSD mObjectIDs; -}; -//=============================================================================== -void LLAccountingQuotaManager::fetchQuotas( const std::string& url ) -{ - // Invoking system must have already determined capability availability - if ( !url.empty() ) - { - LLSD objectList; - U32 objectIndex = 0; - IDIt IDIter = mUpdateObjectQuota.begin(); - IDIt IDIterEnd = mUpdateObjectQuota.end(); - - for ( ; IDIter != IDIterEnd; ++IDIter ) - { - // Check to see if a request for this object has already been made. - if ( mPendingObjectQuota.find( *IDIter ) == mPendingObjectQuota.end() ) - { - mPendingObjectQuota.insert( *IDIter ); - objectList[objectIndex++] = *IDIter; - } - } - - mUpdateObjectQuota.clear(); - - //Post results - if ( objectList.size() > 0 ) - { - LLSD dataToPost = LLSD::emptyMap(); - dataToPost["object_ids"] = objectList; - LLHTTPClient::post( url, dataToPost, new LLAccountingQuotaResponder( objectList )); - } - } - else - { - //url was empty - warn & continue - llwarns<<"Supplied url is empty "<isValid()) { gMeshRepo.mDecompThread->submitRequest(request); - } + has_valid_requests = true ; + } } - - while (!mPhysicsComplete) + + if(has_valid_requests) + { + while (!mPhysicsComplete) { apr_sleep(100); } + } } void LLMeshUploadThread::doWholeModelUpload() diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 57e8b5d18..856a39cb1 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5627,10 +5627,4 @@ public: LLHTTPRegistration gHTTPRegistrationObjectPhysicsProperties("/message/ObjectPhysicsProperties"); - -void LLViewerObject::updateQuota( const SelectionQuota& quota ) -{ - //update quotas - mSelectionQuota = quota; -} #endif //MESH_ENABLED diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index fadecd742..591578d78 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -49,9 +49,6 @@ #include "v3dmath.h" #include "v3math.h" #include "llvertexbuffer.h" -#if MESH_ENABLED -#include "llaccountingquota.h" -#endif //MESH_ENABLED class LLAgent; // TODO: Get rid of this. class LLAudioSource; @@ -657,11 +654,7 @@ protected: void deleteParticleSource(); void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id); -#if MESH_ENABLED public: - void updateQuota( const SelectionQuota& quota ); - const SelectionQuota& getQuota( void ) { return mSelectionQuota; } -#endif //MESH_ENABLED private: void setNameValueList(const std::string& list); // clears nv pairs and then individually adds \n separated NV pairs from \0 terminated string @@ -724,8 +717,6 @@ protected: F32 mPhysicsCost; F32 mLinksetPhysicsCost; - SelectionQuota mSelectionQuota; - bool mCostStale; mutable bool mPhysicsShapeUnknown; #endif //MESH_ENABLED diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 94f532306..ca29e5103 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1422,15 +1422,6 @@ void LLViewerObjectList::onObjectCostFetchFailure(const LLUUID& object_id) mPendingObjectCost.erase(object_id); } -void LLViewerObjectList::updateQuota( const LLUUID& objectId, const SelectionQuota& quota ) -{ - LLViewerObject* pVO = findObject( objectId ); - if ( pVO ) - { - pVO->updateQuota( quota ); - } -} - void LLViewerObjectList::updatePhysicsFlags(const LLViewerObject* object) { mStalePhysicsFlags.insert(object->getID()); diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index c47ace52e..f38daf617 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -112,7 +112,6 @@ public: F32 restitution, F32 gravity_multiplier); - void updateQuota( const LLUUID& objectId, const SelectionQuota& costs ); #endif //MESH_ENABLED void shiftObjects(const LLVector3 &offset); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 0c57c294f..b57aa7720 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -101,6 +101,8 @@ public: { } + void buildCapabilityNames(LLSD& capabilityNames); + // The surfaces and other layers LLSurface* mLandp; @@ -1480,6 +1482,82 @@ void LLViewerRegion::unpackRegionHandshake() msg->sendReliable(host); } + +void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) +{ + //capabilityNames.append("AttachmentResources"); //Script limits (llfloaterscriptlimits.cpp) + //capabilityNames.append("AvatarPickerSearch"); //Display name/SLID lookup (llfloateravatarpicker.cpp) + capabilityNames.append("ChatSessionRequest"); + capabilityNames.append("CopyInventoryFromNotecard"); + capabilityNames.append("DispatchRegionInfo"); + capabilityNames.append("EstateChangeInfo"); + capabilityNames.append("EventQueueGet"); + /*capabilityNames.append("EnvironmentSettings"); + capabilityNames.append("ObjectMedia"); + capabilityNames.append("ObjectMediaNavigate");*/ + + if (false)//gSavedSettings.getBOOL("UseHTTPInventory")) //Caps suffixed with 2 by LL. Don't update until rest of fetch system is updated first. + { + capabilityNames.append("FetchLib"); + capabilityNames.append("FetchLibDescendents"); + capabilityNames.append("FetchInventory"); + capabilityNames.append("FetchInventoryDescendents"); + } + + capabilityNames.append("GetDisplayNames"); + capabilityNames.append("GetTexture"); +#if MESH_ENABLED + capabilityNames.append("GetMesh"); + capabilityNames.append("GetObjectCost"); + capabilityNames.append("GetObjectPhysicsData"); +#endif //MESH_ENABLED + capabilityNames.append("GroupProposalBallot"); + + capabilityNames.append("HomeLocation"); + //capabilityNames.append("LandResources"); //Script limits (llfloaterscriptlimits.cpp) + capabilityNames.append("MapLayer"); + capabilityNames.append("MapLayerGod"); +#if MESH_IMPORT + capabilityNames.append("MeshUploadFlag"); +#endif //MESH_IMPORT + capabilityNames.append("NewFileAgentInventory"); + capabilityNames.append("ParcelPropertiesUpdate"); + capabilityNames.append("ParcelMediaURLFilterList"); + capabilityNames.append("ParcelNavigateMedia"); + capabilityNames.append("ParcelVoiceInfoRequest"); + capabilityNames.append("ProductInfoRequest"); + capabilityNames.append("ProvisionVoiceAccountRequest"); + capabilityNames.append("RemoteParcelRequest"); + capabilityNames.append("RequestTextureDownload"); + capabilityNames.append("ResourceCostSelected"); //Unreferenced? + capabilityNames.append("SearchStatRequest"); + capabilityNames.append("SearchStatTracking"); + capabilityNames.append("SendPostcard"); + capabilityNames.append("SendUserReport"); + capabilityNames.append("SendUserReportWithScreenshot"); + capabilityNames.append("ServerReleaseNotes"); + //capabilityNames.append("SimConsole"); + capabilityNames.append("SimulatorFeatures"); + capabilityNames.append("SetDisplayName"); + //capabilityNames.append("SimConsoleAsync"); + capabilityNames.append("StartGroupProposal"); + capabilityNames.append("TextureStats"); + capabilityNames.append("UntrustedSimulatorMessage"); + capabilityNames.append("UpdateAgentInformation"); + capabilityNames.append("UpdateAgentLanguage"); + capabilityNames.append("UpdateGestureAgentInventory"); + capabilityNames.append("UpdateNotecardAgentInventory"); + capabilityNames.append("UpdateScriptAgent"); + capabilityNames.append("UpdateGestureTaskInventory"); + capabilityNames.append("UpdateNotecardTaskInventory"); + capabilityNames.append("UpdateScriptTask"); + capabilityNames.append("UploadBakedTexture"); + //capabilityNames.append("ViewerMetrics"); + capabilityNames.append("ViewerStartAuction"); + capabilityNames.append("ViewerStats"); + // Please add new capabilities alphabetically to reduce + // merge conflicts. +} void LLViewerRegion::setSeedCapability(const std::string& url) { if (getCapability("Seed") == url) @@ -1495,63 +1573,9 @@ void LLViewerRegion::setSeedCapability(const std::string& url) setCapability("Seed", url); LLSD capabilityNames = LLSD::emptyArray(); - capabilityNames.append("ChatSessionRequest"); - capabilityNames.append("CopyInventoryFromNotecard"); - capabilityNames.append("DispatchRegionInfo"); - capabilityNames.append("EstateChangeInfo"); - capabilityNames.append("EventQueueGet"); - if (false)//gSavedSettings.getBOOL("UseHTTPInventory")) //Caps suffixed with 2 by LL. Don't update until rest of fetch system is updated first. - { - capabilityNames.append("FetchLib"); - capabilityNames.append("FetchLibDescendents"); - capabilityNames.append("FetchInventory"); - capabilityNames.append("FetchInventoryDescendents"); - } - capabilityNames.append("GetDisplayNames"); - capabilityNames.append("GetTexture"); -#if MESH_ENABLED - capabilityNames.append("GetMesh"); - capabilityNames.append("GetObjectCost"); - capabilityNames.append("GetObjectPhysicsData"); -#endif //MESH_ENABLED - capabilityNames.append("GroupProposalBallot"); - - capabilityNames.append("HomeLocation"); - capabilityNames.append("MapLayer"); - capabilityNames.append("MapLayerGod"); - capabilityNames.append("NewFileAgentInventory"); - capabilityNames.append("ParcelPropertiesUpdate"); - capabilityNames.append("ParcelMediaURLFilterList"); - capabilityNames.append("ParcelNavigateMedia"); - capabilityNames.append("ParcelVoiceInfoRequest"); - capabilityNames.append("ProductInfoRequest"); - capabilityNames.append("ProvisionVoiceAccountRequest"); - capabilityNames.append("RemoteParcelRequest"); - capabilityNames.append("RequestTextureDownload"); - capabilityNames.append("SearchStatRequest"); - capabilityNames.append("SearchStatTracking"); - capabilityNames.append("SendPostcard"); - capabilityNames.append("SendUserReport"); - capabilityNames.append("SendUserReportWithScreenshot"); - capabilityNames.append("ServerReleaseNotes"); - capabilityNames.append("SimulatorFeatures"); - capabilityNames.append("SetDisplayName"); - capabilityNames.append("StartGroupProposal"); - capabilityNames.append("TextureStats"); - capabilityNames.append("UntrustedSimulatorMessage"); - capabilityNames.append("UpdateAgentInformation"); - capabilityNames.append("UpdateAgentLanguage"); - capabilityNames.append("UpdateGestureAgentInventory"); - capabilityNames.append("UpdateNotecardAgentInventory"); - capabilityNames.append("UpdateScriptAgent"); - capabilityNames.append("UpdateGestureTaskInventory"); - capabilityNames.append("UpdateNotecardTaskInventory"); - capabilityNames.append("UpdateScriptTask"); - capabilityNames.append("UploadBakedTexture"); - capabilityNames.append("ViewerStartAuction"); - capabilityNames.append("ViewerStats"); - // Please add new capabilities alphabetically to reduce - // merge conflicts. + + mImpl->buildCapabilityNames(capabilityNames); + llinfos << "posting to seed " << url << llendl; From 9aa26648c9d49d9de348d226fdc1c134adef534f Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sat, 6 Aug 2011 02:29:04 -0500 Subject: [PATCH 08/10] Added CurlUseMultipleThreads (requires restart to change) --- indra/llmessage/llcurl.cpp | 161 ++++++++++++++++-------- indra/llmessage/llcurl.h | 8 +- indra/newview/app_settings/settings.xml | 13 +- indra/newview/llappviewer.cpp | 2 +- 4 files changed, 126 insertions(+), 58 deletions(-) diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 524c0ef17..8192b97a9 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -92,6 +92,9 @@ std::vector LLCurl::sSSLMutex; std::string LLCurl::sCAPath; std::string LLCurl::sCAFile; +bool LLCurl::sMultiThreaded = false; +static U32 sMainThreadID = 0; + void check_curl_code(CURLcode code) { if (code != CURLE_OK) @@ -250,7 +253,7 @@ public: U32 report(CURLcode); void getTransferInfo(LLCurl::TransferInfo* info); - void prepRequest(const std::string& url, const std::vector& headers, ResponderPtr, bool post = false); + void prepRequest(const std::string& url, const std::vector& headers, ResponderPtr, S32 time_out = 0, bool post = false); const char* getErrorBuffer(); @@ -549,7 +552,7 @@ size_t curlHeaderCallback(void* data, size_t size, size_t nmemb, void* user_data void LLCurl::Easy::prepRequest(const std::string& url, const std::vector& headers, - ResponderPtr responder, bool post) + ResponderPtr responder, S32 time_out, bool post) { resetState(); @@ -599,7 +602,7 @@ void LLCurl::Easy::prepRequest(const std::string& url, //don't verify host name so urls with scrubbed host names will work (improves DNS performance) setopt(CURLOPT_SSL_VERIFYHOST, 0); - setopt(CURLOPT_TIMEOUT, CURL_REQUEST_TIMEOUT); + setopt(CURLOPT_TIMEOUT, llmax(time_out, CURL_REQUEST_TIMEOUT)); setoptString(CURLOPT_URL, url); @@ -642,6 +645,7 @@ public: S32 process(); void perform(); + void doPerform(); virtual void run(); @@ -654,6 +658,7 @@ public: LLCondition* mSignal; bool mQuitting; + bool mThreaded; private: void easyFree(Easy*); @@ -675,7 +680,16 @@ LLCurl::Multi::Multi() mPerformState(PERFORM_STATE_READY) { mQuitting = false; - mSignal = new LLCondition; + + mThreaded = LLCurl::sMultiThreaded && LLThread::currentID() == sMainThreadID; + if (mThreaded) + { + mSignal = new LLCondition; + } + else + { + mSignal = NULL; + } mCurlMultiHandle = curl_multi_init(); if (!mCurlMultiHandle) @@ -722,16 +736,25 @@ CURLMsg* LLCurl::Multi::info_read(S32* msgs_in_queue) void LLCurl::Multi::perform() { - mSignal->lock(); - if (mPerformState == PERFORM_STATE_READY) + if (mThreaded) { - mSignal->signal(); + mSignal->lock(); + if (mPerformState == PERFORM_STATE_READY) + { + mSignal->signal(); + } + mSignal->unlock(); } - mSignal->unlock(); + else + { + doPerform(); + } } void LLCurl::Multi::run() { + llassert(mThreaded); + mSignal->lock(); while (!mQuitting) { @@ -739,26 +762,31 @@ void LLCurl::Multi::run() mPerformState = PERFORM_STATE_PERFORMING; if (!mQuitting) { - S32 q = 0; - for (S32 call_count = 0; - call_count < MULTI_PERFORM_CALL_REPEAT; - call_count += 1) - { - CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q); - if (CURLM_CALL_MULTI_PERFORM != code || q == 0) - { - check_curl_multi_code(code); - break; - } - - } - mQueued = q; - mPerformState = PERFORM_STATE_COMPLETED; + doPerform(); } } mSignal->unlock(); } +void LLCurl::Multi::doPerform() +{ + S32 q = 0; + for (S32 call_count = 0; + call_count < MULTI_PERFORM_CALL_REPEAT; + call_count += 1) + { + CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q); + if (CURLM_CALL_MULTI_PERFORM != code || q == 0) + { + check_curl_multi_code(code); + break; + } + + } + mQueued = q; + mPerformState = PERFORM_STATE_COMPLETED; +} + S32 LLCurl::Multi::process() { perform(); @@ -883,16 +911,21 @@ LLCurlRequest::~LLCurlRequest() for (curlmulti_set_t::iterator iter = mMultiSet.begin(); iter != mMultiSet.end(); ++iter) { LLCurl::Multi* multi = *iter; - multi->mSignal->lock(); - multi->mQuitting = true; - while (!multi->isStopped()) - { - multi->mSignal->signal(); - multi->mSignal->unlock(); - apr_sleep(1000); + if (multi->mThreaded) multi->mSignal->lock(); + multi->mQuitting = true; + if (multi->mThreaded) + { + while (!multi->isStopped()) + { + multi->mSignal->signal(); + multi->mSignal->unlock(); + apr_sleep(1000); + multi->mSignal->lock(); + } } - multi->mSignal->unlock(); + if (multi->mThreaded) + multi->mSignal->unlock(); } for_each(mMultiSet.begin(), mMultiSet.end(), DeletePointer()); } @@ -901,7 +934,10 @@ void LLCurlRequest::addMulti() { llassert_always(mThreadID == LLThread::currentID()); LLCurl::Multi* multi = new LLCurl::Multi(); - multi->start(); + if (multi->mThreaded) + { + multi->start(); + } mMultiSet.insert(multi); mActiveMulti = multi; mActiveRequestCount = 0; @@ -963,14 +999,14 @@ bool LLCurlRequest::getByteRange(const std::string& url, bool LLCurlRequest::post(const std::string& url, const headers_t& headers, const LLSD& data, - LLCurl::ResponderPtr responder) + LLCurl::ResponderPtr responder, S32 time_out) { LLCurl::Easy* easy = allocEasy(); if (!easy) { return false; } - easy->prepRequest(url, headers, responder); + easy->prepRequest(url, headers, responder, time_out); LLSDSerialize::toXML(data, easy->getInput()); S32 bytes = easy->getInput().str().length(); @@ -990,14 +1026,14 @@ bool LLCurlRequest::post(const std::string& url, bool LLCurlRequest::post(const std::string& url, const headers_t& headers, const std::string& data, - LLCurl::ResponderPtr responder) + LLCurl::ResponderPtr responder, S32 time_out) { LLCurl::Easy* easy = allocEasy(); if (!easy) { return false; } - easy->prepRequest(url, headers, responder); + easy->prepRequest(url, headers, responder, time_out); easy->getInput().write(data.data(), data.size()); S32 bytes = easy->getInput().str().length(); @@ -1031,16 +1067,21 @@ S32 LLCurlRequest::process() if (multi != mActiveMulti && tres == 0 && multi->mQueued == 0) { mMultiSet.erase(curiter); - multi->mSignal->lock(); + if (multi->mThreaded) + multi->mSignal->lock(); multi->mQuitting = true; - while (!multi->isStopped()) + if (multi->mThreaded) { - multi->mSignal->signal(); - multi->mSignal->unlock(); - apr_sleep(1000); - multi->mSignal->unlock(); + while (!multi->isStopped()) + { + multi->mSignal->signal(); + multi->mSignal->unlock(); + apr_sleep(1000); + multi->mSignal->unlock(); + } } - multi->mSignal->unlock(); + if (multi->mThreaded) + multi->mSignal->unlock(); delete multi; } @@ -1059,6 +1100,10 @@ S32 LLCurlRequest::getQueued() curlmulti_set_t::iterator curiter = iter++; LLCurl::Multi* multi = *curiter; queued += multi->mQueued; + if (multi->mPerformState != LLCurl::Multi::PERFORM_STATE_READY) + { + ++queued; + } } return queued; } @@ -1072,7 +1117,10 @@ LLCurlEasyRequest::LLCurlEasyRequest() mResultReturned(false) { mMulti = new LLCurl::Multi(); - mMulti->start(); + if (mMulti->mThreaded) + { + mMulti->start(); + } mEasy = mMulti->allocEasy(); if (mEasy) { @@ -1083,16 +1131,21 @@ LLCurlEasyRequest::LLCurlEasyRequest() LLCurlEasyRequest::~LLCurlEasyRequest() { - mMulti->mSignal->lock(); - mMulti->mQuitting = true; - while (!mMulti->isStopped()) - { - mMulti->mSignal->signal(); - mMulti->mSignal->unlock(); - apr_sleep(1000); + if (mMulti->mThreaded) mMulti->mSignal->lock(); + mMulti->mQuitting = true; + if (mMulti->mThreaded) + { + while (!mMulti->isStopped()) + { + mMulti->mSignal->signal(); + mMulti->mSignal->unlock(); + apr_sleep(1000); + mMulti->mSignal->lock(); + } } - mMulti->mSignal->unlock(); + if (mMulti->mThreaded) + mMulti->mSignal->unlock(); delete mMulti; } @@ -1287,8 +1340,10 @@ unsigned long LLCurl::ssl_thread_id(void) } #endif -void LLCurl::initClass() +void LLCurl::initClass(bool multi_threaded) { + sMainThreadID = LLThread::currentID(); + sMultiThreaded = multi_threaded; // Do not change this "unless you are familiar with and mean to control // internal operations of libcurl" // - http://curl.haxx.se/libcurl/c/curl_global_init.html diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index 02abd7400..988205921 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -61,6 +61,8 @@ public: class Easy; class Multi; + static bool sMultiThreaded; + struct TransferInfo { TransferInfo() : mSizeDownload(0.0), mTotalTime(0.0), mSpeedDownload(0.0) {} @@ -164,7 +166,7 @@ public: /** * @ brief Initialize LLCurl class */ - static void initClass(); + static void initClass(bool multi_threaded = false); /** * @ brief Cleanup LLCurl class @@ -206,8 +208,8 @@ public: void get(const std::string& url, LLCurl::ResponderPtr responder); bool getByteRange(const std::string& url, const headers_t& headers, S32 offset, S32 length, LLCurl::ResponderPtr responder); - bool post(const std::string& url, const headers_t& headers, const LLSD& data, LLCurl::ResponderPtr responder); - bool post(const std::string& url, const headers_t& headers, const std::string& data, LLCurl::ResponderPtr responder); + bool post(const std::string& url, const headers_t& headers, const LLSD& data, LLCurl::ResponderPtr responder, S32 time_out = 0); + bool post(const std::string& url, const headers_t& headers, const std::string& data, LLCurl::ResponderPtr responder, S32 time_out = 0); S32 process(); S32 getQueued(); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index ca13e4f39..2fa47eaea 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3772,10 +3772,21 @@ Value 0 + CurlUseMultipleThreads + + Comment + Use background threads for executing curl_multi_perform (requires restart) + Persist + 1 + Type + Boolean + Value + 1 + Cursor3D Comment - Tread Joystick values as absolute positions (not deltas). + Treat Joystick values as absolute positions (not deltas). Persist 1 Type diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index e8fed149a..f621e0779 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -592,7 +592,7 @@ bool LLAppViewer::init() // *NOTE:Mani - LLCurl::initClass is not thread safe. // Called before threads are created. - LLCurl::initClass(); + LLCurl::initClass(gSavedSettings.getBOOL("CurlUseMultipleThreads")); LL_INFOS("InitInfo") << "LLCurl initialized." << LL_ENDL ; initThreads(); From a5f38565fa46e4a57ebcbebf77a0ab24f80e79e5 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sat, 6 Aug 2011 18:14:54 -0500 Subject: [PATCH 09/10] Henri-inspired tweakage. --- indra/newview/llworld.cpp | 4 +-- indra/newview/llworldmapview.cpp | 47 ++++++++++++++++++-------------- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index b1e42c084..171d6a9bb 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -653,8 +653,8 @@ void LLWorld::updateRegions(F32 max_update_time) BOOL did_one = FALSE; // Perform idle time updates for the regions (and associated surfaces) - for (region_list_t::iterator iter = mRegionList.begin(); - iter != mRegionList.end(); ++iter) + for (region_list_t::iterator iter = mActiveRegionList.begin()/*mRegionList.begin()*/; + iter != mActiveRegionList.end()/*mRegionList.end()*/; ++iter) { LLViewerRegion* regionp = *iter; F32 max_time = max_update_time - update_timer.getElapsedTimeF32(); diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index d4c9c7f66..575e8120b 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -484,13 +484,15 @@ void LLWorldMapView::draw() gGL.setSceneBlendType(LLRender::BT_ALPHA); // Infohubs - if (gSavedSettings.getBOOL("MapShowInfohubs")) //(sMapScale >= sThresholdB) + static const LLCachedControl map_show_infohubs("MapShowInfohubs"); + if (map_show_infohubs) //(sMapScale >= sThresholdB) { drawGenericItems(LLWorldMap::getInstance()->mInfohubs, sInfohubImage); } // Telehubs - if (gSavedSettings.getBOOL("MapShowTelehubs")) //(sMapScale >= sThresholdB) + static const LLCachedControl map_show_telehubs("MapShowTelehubs"); + if (map_show_telehubs) //(sMapScale >= sThresholdB) { drawGenericItems(LLWorldMap::getInstance()->mTelehubs, sTelehubImage); } @@ -502,7 +504,8 @@ void LLWorldMapView::draw() drawImage(home, sHomeImage); } - if (gSavedSettings.getBOOL("MapShowLandForSale")) + static const LLCachedControl map_show_land_for_sale("MapShowLandForSale"); + if (map_show_land_for_sale) { drawGenericItems(LLWorldMap::getInstance()->mLandForSale, sForSaleImage); // for 1.23, we're showing normal land and adult land in the same UI; you don't @@ -514,12 +517,7 @@ void LLWorldMapView::draw() } } - if (gSavedSettings.getBOOL("MapShowPGEvents") || - gSavedSettings.getBOOL("MapShowMatureEvents") || - gSavedSettings.getBOOL("MapShowAdultEvents") ) - { - drawEvents(); - } + drawEvents(); // Now draw your avatar after all that other stuff. LLVector3d pos_global = gAgent.getPositionGlobal(); @@ -541,7 +539,8 @@ void LLWorldMapView::draw() // Draw icons for the avatars in each region. // Drawn after your avatar so you can see nearby people. - if (gSavedSettings.getBOOL("MapShowPeople")) + static const LLCachedControl map_show_people("MapShowPeople"); + if (map_show_people) { drawAgents(); } @@ -887,7 +886,8 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { gGL.vertex3f(right, top, 0.f); gGL.end(); - if (gSavedSettings.getBOOL("MapShowLandForSale") && overlayimage && overlayimage->hasGLTexture()) + static const LLCachedControl map_show_land_for_sale("MapShowLandForSale"); + if (map_show_land_for_sale && overlayimage && overlayimage->hasGLTexture()) { gGL.getTexUnit(0)->bind(overlayimage); gGL.color4f(1.f, 1.f, 1.f, alpha); @@ -1057,9 +1057,13 @@ void LLWorldMapView::drawEvents() bool mature_enabled = gAgent.canAccessMature(); bool adult_enabled = gAgent.canAccessAdult(); - BOOL show_pg = gSavedSettings.getBOOL("MapShowPGEvents"); - BOOL show_mature = mature_enabled && gSavedSettings.getBOOL("MapShowMatureEvents"); - BOOL show_adult = adult_enabled && gSavedSettings.getBOOL("MapShowAdultEvents"); + static const LLCachedControl map_show_pg_events("MapShowPGEvents"); + static const LLCachedControl map_show_mature_events("MapShowMatureEvents"); + static const LLCachedControl map_show_adult_events("MapShowAdultEvents"); + + BOOL show_pg = map_show_pg_events; + BOOL show_mature = mature_enabled && map_show_mature_events; + BOOL show_adult = adult_enabled && map_show_adult_events; // First the non-selected events LLWorldMap::item_info_list_t::const_iterator e; @@ -1874,8 +1878,9 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask, } // Select event you clicked on - if (gSavedSettings.getBOOL("MapShowPGEvents")) - { + static const LLCachedControl map_show_pg_events("MapShowPGEvents"); + if (map_show_pg_events) + { for (it = LLWorldMap::getInstance()->mPGEvents.begin(); it != LLWorldMap::getInstance()->mPGEvents.end(); ++it) { LLItemInfo& event = *it; @@ -1889,7 +1894,8 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask, } } } - if (gSavedSettings.getBOOL("MapShowMatureEvents")) + static const LLCachedControl map_show_mature_events("MapShowMatureEvents"); + if (map_show_mature_events) { for (it = LLWorldMap::getInstance()->mMatureEvents.begin(); it != LLWorldMap::getInstance()->mMatureEvents.end(); ++it) { @@ -1904,7 +1910,8 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask, } } } - if (gSavedSettings.getBOOL("MapShowAdultEvents")) + static const LLCachedControl map_show_adult_events("MapShowAdultEvents"); + if (map_show_adult_events) { for (it = LLWorldMap::getInstance()->mAdultEvents.begin(); it != LLWorldMap::getInstance()->mAdultEvents.end(); ++it) { @@ -1919,8 +1926,8 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask, } } } - - if (gSavedSettings.getBOOL("MapShowLandForSale")) + static const LLCachedControl map_show_land_for_sale("MapShowLandForSale"); + if (map_show_land_for_sale) { for (it = LLWorldMap::getInstance()->mLandForSale.begin(); it != LLWorldMap::getInstance()->mLandForSale.end(); ++it) { From 1e7415095c9674d8004ab4b226b2ef1d04293a03 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sat, 6 Aug 2011 18:17:55 -0500 Subject: [PATCH 10/10] mCurlGetRequest->process() kersploded. Debugger is being dumb, so adding an assertion for now. --- indra/newview/lltexturefetch.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 8caf60b02..d5e094b0f 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1144,7 +1144,7 @@ bool LLTextureFetchWorker::doWork(S32 param) if (region) { - std::string http_url = region->getCapability("GetTexture"); + std::string http_url = region->getHttpUrl() ; if (!http_url.empty()) { mUrl = http_url + "/?texture_id=" + mID.asString().c_str(); @@ -2348,6 +2348,7 @@ void LLTextureFetch::commonUpdate() #endif // Update Curl on same thread as mCurlGetRequest was constructed + llassert_always(mCurlGetRequest); S32 processed = mCurlGetRequest->process(); if (processed > 0) {