summaryrefslogtreecommitdiff
path: root/indra/newview/llvovolume.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llvovolume.cpp')
-rw-r--r--indra/newview/llvovolume.cpp129
1 files changed, 89 insertions, 40 deletions
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 9b63875ffe..e4dd5fead6 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -250,10 +250,12 @@ LLVOVolume::~LLVOVolume()
delete mVolumeImpl;
mVolumeImpl = NULL;
- gMeshRepo.unregisterMesh(this);
+ unregisterOldMeshAndSkin();
if(!mMediaImplList.empty())
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_MEDIA("delete volume media list");
+
for(U32 i = 0 ; i < mMediaImplList.size() ; i++)
{
if(mMediaImplList[i].notNull())
@@ -639,6 +641,15 @@ void LLVOVolume::animateTextures()
if (!facep->mTextureMatrix)
{
facep->mTextureMatrix = new LLMatrix4();
+ if (facep->getVirtualSize() > MIN_TEX_ANIM_SIZE)
+ {
+ // Fix the one edge case missed in
+ // LLVOVolume::updateTextureVirtualSize when the
+ // mTextureMatrix is not yet present
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
+ mDrawable->getSpatialGroup()->dirtyGeom();
+ gPipeline.markRebuild(mDrawable->getSpatialGroup());
+ }
}
LLMatrix4& tex_mat = *facep->mTextureMatrix;
@@ -782,11 +793,29 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
for (S32 i = 0; i < num_faces; i++)
{
LLFace* face = mDrawable->getFace(i);
- if (!face) continue;
+ if (!face || face->mExtents[0].equals3(face->mExtents[1])) continue;
const LLTextureEntry *te = face->getTextureEntry();
- LLViewerTexture *imagep = face->getTexture();
- if (!imagep || !te ||
- face->mExtents[0].equals3(face->mExtents[1]))
+ if (!te) continue;
+
+ LLViewerTexture *imagep = nullptr;
+ U32 ch_min;
+ U32 ch_max;
+ if (!te->getGLTFRenderMaterial())
+ {
+ ch_min = LLRender::DIFFUSE_MAP;
+ ch_max = LLRender::SPECULAR_MAP;
+ }
+ else
+ {
+ ch_min = LLRender::BASECOLOR_MAP;
+ ch_max = LLRender::EMISSIVE_MAP;
+ }
+ for (U32 ch = ch_min; (!imagep && ch <= ch_max); ++ch)
+ {
+ // Get _a_ non-null texture if possible (usually diffuse/basecolor, but could be something else)
+ imagep = face->getTexture(ch);
+ }
+ if (!imagep)
{
continue;
}
@@ -812,12 +841,25 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
// if the face has gotten small enough to turn off texture animation and texture
// animation is running, rebuild the render batch for this face to turn off
// texture animation
+ // Do the opposite when the face gets big enough.
+ // If a face is animatable, it will always have non-null mTextureMatrix
+ // pointer defined after the first call to LLVOVolume::animateTextures,
+ // although the animation is not always turned on.
if (face->mTextureMatrix != NULL)
{
- if ((vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE) ||
- (vsize > MIN_TEX_ANIM_SIZE && old_size < MIN_TEX_ANIM_SIZE))
+ if ((vsize > MIN_TEX_ANIM_SIZE) != (old_size > MIN_TEX_ANIM_SIZE))
{
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
+ // dirtyGeom+markRebuild tells the engine to call
+ // LLVolumeGeometryManager::rebuildGeom, which rebuilds the
+ // LLDrawInfo for the spatial group containing this LLFace,
+ // safely copying the mTextureMatrix from the LLFace the the
+ // LLDrawInfo. While it's not ideal to call it here, prims with
+ // animated faces get moved to a smaller partition to reduce
+ // side-effects of their updates (see shrinkWrap in
+ // LLVOVolume::animateTextures).
+ mDrawable->getSpatialGroup()->dirtyGeom();
+ gPipeline.markRebuild(mDrawable->getSpatialGroup());
}
}
@@ -998,6 +1040,28 @@ LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline)
return mDrawable;
}
+// Inverse of gMeshRepo.loadMesh and gMeshRepo.getSkinInfo, combined into one function
+// Assume a Collada mesh never changes after being set.
+void LLVOVolume::unregisterOldMeshAndSkin()
+{
+ if (mVolumep)
+ {
+ const LLVolumeParams& params = mVolumep->getParams();
+ if ((params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
+ {
+ // object is being deleted, so it will no longer need to request
+ // meshes.
+ for (S32 lod = 0; lod != LLVolumeLODGroup::NUM_LODS; ++lod)
+ {
+ gMeshRepo.unregisterMesh(this, params, lod);
+ }
+ // This volume may or may not have a skin
+ gMeshRepo.unregisterSkinInfo(params.getSculptID(), this);
+ }
+ }
+}
+
+
bool LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bool unique_volume)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
@@ -1511,11 +1575,16 @@ bool LLVOVolume::calcLOD()
mLODAdjustedDistance = distance;
+ static LLCachedControl<S32> debug_selection_lods(gSavedSettings, "DebugSelectionLODs", 0);
if (isHUDAttachment())
{
// HUDs always show at highest detail
cur_detail = 3;
}
+ else if (isSelected() && debug_selection_lods() >= 0)
+ {
+ cur_detail = llmin(debug_selection_lods(), 3);
+ }
else
{
cur_detail = computeLODDetail(ll_round(distance, 0.01f), ll_round(radius, 0.01f), lod_factor);
@@ -3210,6 +3279,7 @@ void LLVOVolume::updateSpotLightPriority()
{
return;
}
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
F32 r = getLightRadius();
LLVector3 pos = mDrawable->getPositionAgent();
@@ -3656,7 +3726,7 @@ const LLMeshSkinInfo* LLVOVolume::getSkinInfo() const
// virtual
bool LLVOVolume::isRiggedMesh() const
{
- return isMesh() && getSkinInfo();
+ return getSkinInfo() != nullptr;
}
//----------------------------------------------------------------------------
@@ -3817,7 +3887,6 @@ void LLVOVolume::updateRiggingInfo()
LLVolume *volume = getVolume();
if (skin && avatar && volume)
{
- LL_DEBUGS("RigSpammish") << "starting, vovol " << this << " lod " << getLOD() << " last " << mLastRiggingInfoLOD << LL_ENDL;
if (getLOD()>mLastRiggingInfoLOD || getLOD()==3)
{
// Rigging info may need update
@@ -3833,9 +3902,6 @@ void LLVOVolume::updateRiggingInfo()
}
// Keep the highest LOD info available.
mLastRiggingInfoLOD = getLOD();
- LL_DEBUGS("RigSpammish") << "updated rigging info for LLVOVolume "
- << this << " lod " << mLastRiggingInfoLOD
- << LL_ENDL;
}
}
}
@@ -5370,7 +5436,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
info->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange &&
info->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&
#endif
- info->mMaterialID == mat_id &&
+ info->mMaterialHash == mat_id &&
info->mFullbright == fullbright &&
info->mBump == bump &&
(!mat || (info->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different
@@ -5429,11 +5495,11 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
if (gltf_mat)
{
// just remember the material ID, render pools will reference the GLTF material
- draw_info->mMaterialID = mat_id;
+ draw_info->mMaterialHash = mat_id;
}
else if (mat)
{
- draw_info->mMaterialID = mat_id;
+ draw_info->mMaterialHash = mat_id;
// We have a material. Update our draw info accordingly.
@@ -5465,10 +5531,10 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
}
}
- // if (type == LLRenderPass::PASS_ALPHA) // always populate the draw_info ptr
- { //for alpha sorting
- facep->setDrawInfo(draw_info);
- }
+ // This backpointer is used by alpha sorting and avatar attachment
+ // accounting.
+ // To be safe, always populate the draw_info ptr.
+ facep->setDrawInfo(draw_info);
if (index < FACE_DO_NOT_BATCH_TEXTURES)
{ //initialize texture list for texture batching
@@ -6026,8 +6092,8 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
group->mBuilt = 1.f;
- const U32 MAX_BUFFER_COUNT = 4096;
- LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT];
+ static std::vector<LLVertexBuffer*> locked_buffer;
+ locked_buffer.resize(0);
U32 buffer_count = 0;
@@ -6072,8 +6138,6 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
group->dirtyGeom();
gPipeline.markRebuild(group);
}
-
- buff->unmapBuffer();
}
}
}
@@ -6089,20 +6153,10 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
{
LL_PROFILE_ZONE_NAMED("rebuildMesh - flush");
- for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter)
- {
- (*iter)->unmapBuffer();
- }
-
- // don't forget alpha
- if(group != NULL &&
- !group->mVertexBuffer.isNull())
- {
- group->mVertexBuffer->unmapBuffer();
- }
+ LLVertexBuffer::flushBuffers();
}
- group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
+ group->clearState(LLSpatialGroup::MESH_DIRTY);
}
}
}
@@ -6781,11 +6835,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
++face_iter;
}
-
- if (buffer)
- {
- buffer->unmapBuffer();
- }
}
group->mBufferMap[mask].clear();