summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorGraham Madarasz (Graham) <graham@lindenlab.com>2013-03-04 08:57:58 -0800
committerGraham Madarasz (Graham) <graham@lindenlab.com>2013-03-04 08:57:58 -0800
commit4e81a84abd2c928dbdc6c4e2a3a348494d205edf (patch)
tree7066e1bbe40d44db58660ea65ef126d32b513c62 /indra/newview
parent3849ee79c3810226d1129bcbeb6bd69144aba243 (diff)
parentda2caa46406d07b4b093bc17966ee23d87819f7c (diff)
Performance improvements. Faster threadsaferefcount, faster instancetracker, use hashtable and pre-hashed strings for GLSL uniform lookup, and use dup_handles curl interface to avoid re-initing ares resolvers expensively.
Diffstat (limited to 'indra/newview')
-rwxr-xr-xindra/newview/llagent.cpp33
-rw-r--r--indra/newview/llagent.h2
-rw-r--r--indra/newview/lldrawpoolbump.cpp2
-rwxr-xr-xindra/newview/llface.cpp37
-rwxr-xr-xindra/newview/llmeshrepository.cpp5
-rwxr-xr-xindra/newview/llvoavatar.cpp258
-rw-r--r--indra/newview/llvoavatar.h3
-rw-r--r--indra/newview/llvovolume.cpp35
-rw-r--r--indra/newview/pipeline.cpp47
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml41
10 files changed, 308 insertions, 155 deletions
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index b6fd7bc9c2..f0eee24fef 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -3062,6 +3062,30 @@ void LLAgent::sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request)
sendReliableMessage();
}
+// Send a message to the region to stop the NULL animation state
+// This will reset animation state overrides for the agent.
+void LLAgent::sendAnimationStateReset()
+{
+ if (gAgentID.isNull() || !mRegionp)
+ {
+ return;
+ }
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_AgentAnimation);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, getID());
+ msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
+
+ msg->nextBlockFast(_PREHASH_AnimationList);
+ msg->addUUIDFast(_PREHASH_AnimID, LLUUID::null );
+ msg->addBOOLFast(_PREHASH_StartAnim, FALSE);
+
+ msg->nextBlockFast(_PREHASH_PhysicalAvatarEventList);
+ msg->addBinaryDataFast(_PREHASH_TypeData, NULL, 0);
+ sendReliableMessage();
+}
+
void LLAgent::sendWalkRun(bool running)
{
LLMessageSystem* msgsys = gMessageSystem;
@@ -4140,6 +4164,8 @@ void LLAgent::stopCurrentAnimations()
// avatar, propagating this change back to the server.
if (isAgentAvatarValid())
{
+ LLDynamicArray<LLUUID> anim_ids;
+
for ( LLVOAvatar::AnimIterator anim_it =
gAgentAvatarp->mPlayingAnimations.begin();
anim_it != gAgentAvatarp->mPlayingAnimations.end();
@@ -4157,10 +4183,15 @@ void LLAgent::stopCurrentAnimations()
// stop this animation locally
gAgentAvatarp->stopMotion(anim_it->first, TRUE);
// ...and tell the server to tell everyone.
- sendAnimationRequest(anim_it->first, ANIM_REQUEST_STOP);
+ anim_ids.push_back(anim_it->first);
}
}
+ sendAnimationRequests(anim_ids, ANIM_REQUEST_STOP);
+
+ // Tell the region to clear any animation state overrides.
+ sendAnimationStateReset();
+
// re-assert at least the default standing animation, because
// viewers get confused by avs with no associated anims.
sendAnimationRequest(ANIM_AGENT_STAND,
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 99904e118c..bec9352f5f 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -431,6 +431,8 @@ public:
void onAnimStop(const LLUUID& id);
void sendAnimationRequests(LLDynamicArray<LLUUID> &anim_ids, EAnimRequest request);
void sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request);
+ void sendAnimationStateReset();
+
void endAnimationUpdateUI();
void unpauseAnimation() { mPauseRequest = NULL; }
BOOL getCustomAnim() const { return mCustomAnim; }
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 4137084ebe..7e95046479 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -461,6 +461,8 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32&
}
}
}
+ // Moved below shader->disableTexture call to avoid false alarms from auto-re-enable of textures on stage 0
+ // MAINT-755
cube_map->disable();
cube_map->restoreMatrix();
}
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 3c7a49d5ce..43d21137b5 100755
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -51,7 +51,9 @@
#include "llviewerregion.h"
#include "llviewerwindow.h"
#include "llviewershadermgr.h"
+#include "llvoavatar.h"
+extern BOOL gGLDebugLoggingEnabled;
#define LL_MAX_INDICES_COUNT 1000000
@@ -328,6 +330,12 @@ void LLFace::dirtyTexture()
if (vobj)
{
vobj->mLODChanged = TRUE;
+
+ LLVOAvatar* avatar = vobj->getAvatar();
+ if (avatar)
+ { //avatar render cost may have changed
+ avatar->updateVisualComplexity();
+ }
}
gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE);
}
@@ -1162,6 +1170,15 @@ static LLFastTimer::DeclareTimer FTM_FACE_GEOM_COLOR("Color");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_EMISSIVE("Emissive");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_WEIGHTS("Weights");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_BINORMAL("Binormal");
+
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK("Face Feedback");
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_POSITION("Feedback Position");
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_NORMAL("Feedback Normal");
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_TEXTURE("Feedback Texture");
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_COLOR("Feedback Color");
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_EMISSIVE("Feedback Emissive");
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_BINORMAL("Feedback Binormal");
+
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX("Index");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX_TAIL("Tail");
static LLFastTimer::DeclareTimer FTM_FACE_POSITION_STORE("Pos");
@@ -1385,12 +1402,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
#ifdef GL_TRANSFORM_FEEDBACK_BUFFER
if (use_transform_feedback &&
+ mVertexBuffer->getUsage() == GL_DYNAMIC_COPY_ARB &&
gTransformPositionProgram.mProgramObject && //transform shaders are loaded
mVertexBuffer->useVBOs() && //target buffer is in VRAM
!rebuild_weights && //TODO: add support for weights
!volume.isUnique()) //source volume is NOT flexi
{ //use transform feedback to pack vertex buffer
-
+ //gGLDebugLoggingEnabled = TRUE;
+ LLFastTimer t(FTM_FACE_GEOM_FEEDBACK);
LLVertexBuffer* buff = (LLVertexBuffer*) vf.mVertexBuffer.get();
if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices)
@@ -1407,7 +1426,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_pos)
{
- LLFastTimer t(FTM_FACE_GEOM_POSITION);
+ LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_POSITION);
gTransformPositionProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_VERTEX, mGeomIndex, mGeomCount);
@@ -1420,7 +1439,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
vp[1] = 0;
vp[2] = 0;
vp[3] = 0;
-
+
gTransformPositionProgram.uniform1i(sTextureIndexIn, val);
glBeginTransformFeedback(GL_POINTS);
buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
@@ -1432,7 +1451,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_color)
{
- LLFastTimer t(FTM_FACE_GEOM_COLOR);
+ LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_COLOR);
gTransformColorProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_COLOR, mGeomIndex, mGeomCount);
@@ -1448,7 +1467,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_emissive)
{
- LLFastTimer t(FTM_FACE_GEOM_EMISSIVE);
+ LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_EMISSIVE);
gTransformColorProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_EMISSIVE, mGeomIndex, mGeomCount);
@@ -1469,7 +1488,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_normal)
{
- LLFastTimer t(FTM_FACE_GEOM_NORMAL);
+ LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_NORMAL);
gTransformNormalProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_NORMAL, mGeomIndex, mGeomCount);
@@ -1482,7 +1501,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_binormal)
{
- LLFastTimer t(FTM_FACE_GEOM_BINORMAL);
+ LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_BINORMAL);
gTransformBinormalProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_BINORMAL, mGeomIndex, mGeomCount);
@@ -1495,7 +1514,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_tcoord)
{
- LLFastTimer t(FTM_FACE_GEOM_TEXTURE);
+ LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_TEXTURE);
gTransformTexCoordProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD0, mGeomIndex, mGeomCount);
@@ -1518,13 +1537,13 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
glBindBufferARB(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
-
gGL.popMatrix();
if (cur_shader)
{
cur_shader->bind();
}
+ //gGLDebugLoggingEnabled = FALSE;
}
else
#endif
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 1223615079..ae48898e82 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -588,7 +588,7 @@ void LLMeshRepoThread::run()
if (!fetchMeshLOD(req.mMeshParams, req.mLOD, count))//failed, resubmit
{
mMutex->lock();
- mLODReqQ.push(req) ;
+ mLODReqQ.push(req);
mMutex->unlock();
}
}
@@ -1200,8 +1200,7 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat
LLMutexLock lock(mHeaderMutex);
mMeshHeaderSize[mesh_id] = header_size;
mMeshHeader[mesh_id] = header;
- }
-
+ }
LLMutexLock lock(mMutex); // make sure only one thread access mPendingLOD at the same time.
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 62e93b7a53..4efd59685e 100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -688,6 +688,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mFullyLoaded(FALSE),
mPreviousFullyLoaded(FALSE),
mFullyLoadedInitialized(FALSE),
+ mVisualComplexity(0),
+ mVisualComplexityStale(TRUE),
mSupportsAlphaLayers(FALSE),
mLoadedCallbacksPaused(FALSE),
mHasPelvisOffset( FALSE ),
@@ -3434,12 +3436,23 @@ void LLVOAvatar::slamPosition()
bool LLVOAvatar::isVisuallyMuted() const
{
- static LLCachedControl<U32> max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit");
- static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit");
+ bool ret = false;
+
+ if (!isSelf())
+ {
+ static LLCachedControl<U32> max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit");
+ static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit");
+ static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAutoMuteRenderCostLimit");
- return LLMuteList::getInstance()->isMuted(getID()) ||
+ U32 max_cost = (U32) (max_render_cost*(LLVOAvatar::sLODFactor+0.5));
+
+ ret = LLMuteList::getInstance()->isMuted(getID()) ||
(mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) ||
- (mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f);
+ (mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f) ||
+ (mVisualComplexity > max_cost && max_render_cost > 0);
+ }
+
+ return ret;
}
//------------------------------------------------------------------------
@@ -4139,46 +4152,6 @@ bool LLVOAvatar::shouldAlphaMask()
}
-U32 LLVOAvatar::renderSkinnedAttachments()
-{
- /*U32 num_indices = 0;
-
- const U32 data_mask = LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_NORMAL |
- LLVertexBuffer::MAP_TEXCOORD0 |
- LLVertexBuffer::MAP_COLOR |
- LLVertexBuffer::MAP_WEIGHT4;
-
- for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- const LLViewerObject* attached_object = (*attachment_iter);
- if (attached_object && !attached_object->isHUDAttachment())
- {
- const LLDrawable* drawable = attached_object->mDrawable;
- if (drawable)
- {
- for (S32 i = 0; i < drawable->getNumFaces(); ++i)
- {
- LLFace* face = drawable->getFace(i);
- if (face->isState(LLFace::RIGGED))
- {
-
- }
- }
- }
- }
-
- return num_indices;*/
- return 0;
-}
-
//-----------------------------------------------------------------------------
// renderSkinned()
//-----------------------------------------------------------------------------
@@ -4336,21 +4309,23 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
BOOL first_pass = TRUE;
if (!LLDrawPoolAvatar::sSkipOpaque)
{
+ bool muted = isVisuallyMuted();
+
if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender)
{
- if (isTextureVisible(TEX_HEAD_BAKED) || mIsDummy)
+ if (isTextureVisible(TEX_HEAD_BAKED) || mIsDummy || muted)
{
num_indices += mMeshLOD[MESH_ID_HEAD]->render(mAdjustedPixelArea, TRUE, mIsDummy);
first_pass = FALSE;
}
}
- if (isTextureVisible(TEX_UPPER_BAKED) || mIsDummy)
+ if (isTextureVisible(TEX_UPPER_BAKED) || mIsDummy || muted)
{
num_indices += mMeshLOD[MESH_ID_UPPER_BODY]->render(mAdjustedPixelArea, first_pass, mIsDummy);
first_pass = FALSE;
}
- if (isTextureVisible(TEX_LOWER_BAKED) || mIsDummy)
+ if (isTextureVisible(TEX_LOWER_BAKED) || mIsDummy || muted)
{
num_indices += mMeshLOD[MESH_ID_LOWER_BODY]->render(mAdjustedPixelArea, first_pass, mIsDummy);
first_pass = FALSE;
@@ -6090,6 +6065,8 @@ const LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_o
return 0;
}
+ mVisualComplexityStale = TRUE;
+
if (viewer_object->isSelected())
{
LLSelectMgr::getInstance()->updateSelectionCenter();
@@ -6244,6 +6221,7 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object)
if (attachment->isObjectAttached(viewer_object))
{
+ mVisualComplexityStale = TRUE;
cleanupAttachedMesh( viewer_object );
attachment->removeObject(viewer_object);
lldebugs << "Detaching object " << viewer_object->mID << " from " << attachment->getName() << llendl;
@@ -8456,7 +8434,7 @@ void LLVOAvatar::updateImpostors()
BOOL LLVOAvatar::isImpostor() const
{
- return (isVisuallyMuted() || (sUseImpostors && mUpdatePeriod >= IMPOSTOR_PERIOD)) ? TRUE : FALSE;
+ return sUseImpostors && (isVisuallyMuted() || (mUpdatePeriod >= IMPOSTOR_PERIOD)) ? TRUE : FALSE;
}
@@ -8501,6 +8479,8 @@ void LLVOAvatar::getImpostorValues(LLVector4a* extents, LLVector3& angle, F32& d
void LLVOAvatar::idleUpdateRenderCost()
{
+ static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAutoMuteRenderCostLimit");
+
static const U32 ARC_BODY_PART_COST = 200;
static const U32 ARC_LIMIT = 20000;
@@ -8511,123 +8491,147 @@ void LLVOAvatar::idleUpdateRenderCost()
setDebugText(llformat("%.1f KB, %.2f m^2", mAttachmentGeometryBytes/1024.f, mAttachmentSurfaceArea));
}
- if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME))
+ if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME) && max_render_cost == 0)
{
return;
}
- U32 cost = 0;
- LLVOVolume::texture_cost_t textures;
-
- for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
+ if (mVisualComplexityStale)
{
- const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
- ETextureIndex tex_index = baked_dict->mTextureIndex;
- if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT)))
+ mVisualComplexityStale = FALSE;
+ U32 cost = 0;
+ LLVOVolume::texture_cost_t textures;
+
+ for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
{
- if (isTextureVisible(tex_index))
+ const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
+ ETextureIndex tex_index = baked_dict->mTextureIndex;
+ if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT)))
{
- cost +=ARC_BODY_PART_COST;
+ if (isTextureVisible(tex_index))
+ {
+ cost +=ARC_BODY_PART_COST;
+ }
}
}
- }
- for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
- iter != mAttachmentPoints.end();
- ++iter)
- {
- LLViewerJointAttachment* attachment = iter->second;
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
+ for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
{
- const LLViewerObject* attached_object = (*attachment_iter);
- if (attached_object && !attached_object->isHUDAttachment())
+ LLViewerJointAttachment* attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
{
- textures.clear();
- const LLDrawable* drawable = attached_object->mDrawable;
- if (drawable)
+ const LLViewerObject* attached_object = (*attachment_iter);
+ if (attached_object && !attached_object->isHUDAttachment())
{
- const LLVOVolume* volume = drawable->getVOVolume();
- if (volume)
+ textures.clear();
+ const LLDrawable* drawable = attached_object->mDrawable;
+ if (drawable)
{
- cost += volume->getRenderCost(textures);
-
- const_child_list_t children = volume->getChildren();
- for (const_child_list_t::const_iterator child_iter = children.begin();
- child_iter != children.end();
- ++child_iter)
+ const LLVOVolume* volume = drawable->getVOVolume();
+ if (volume)
{
- LLViewerObject* child_obj = *child_iter;
- LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj );
- if (child)
+ cost += volume->getRenderCost(textures);
+
+ const_child_list_t children = volume->getChildren();
+ for (const_child_list_t::const_iterator child_iter = children.begin();
+ child_iter != children.end();
+ ++child_iter)
{
- cost += child->getRenderCost(textures);
+ LLViewerObject* child_obj = *child_iter;
+ LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj );
+ if (child)
+ {
+ cost += child->getRenderCost(textures);
+ }
}
- }
- for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter)
- {
- // add the cost of each individual texture in the linkset
- cost += iter->second;
+ for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter)
+ {
+ // add the cost of each individual texture in the linkset
+ cost += iter->second;
+ }
}
}
}
}
- }
- }
+ }
- // Diagnostic output to identify all avatar-related textures.
- // Does not affect rendering cost calculation.
- // Could be wrapped in a debug option if output becomes problematic.
- if (isSelf())
- {
- // print any attachment textures we didn't already know about.
- for (LLVOVolume::texture_cost_t::iterator it = textures.begin(); it != textures.end(); ++it)
+ // Diagnostic output to identify all avatar-related textures.
+ // Does not affect rendering cost calculation.
+ // Could be wrapped in a debug option if output becomes problematic.
+ if (isSelf())
{
- LLUUID image_id = it->first;
- if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR)
- continue;
- if (all_textures.find(image_id) == all_textures.end())
+ // print any attachment textures we didn't already know about.
+ for (LLVOVolume::texture_cost_t::iterator it = textures.begin(); it != textures.end(); ++it)
+ {
+ LLUUID image_id = it->first;
+ if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR)
+ continue;
+ if (all_textures.find(image_id) == all_textures.end())
+ {
+ // attachment texture not previously seen.
+ llinfos << "attachment_texture: " << image_id.asString() << llendl;
+ all_textures.insert(image_id);
+ }
+ }
+
+ // print any avatar textures we didn't already know about
+ for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
+ iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+ ++iter)
{
- // attachment texture not previously seen.
- llinfos << "attachment_texture: " << image_id.asString() << llendl;
- all_textures.insert(image_id);
+ const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+ // TODO: MULTI-WEARABLE: handle multiple textures for self
+ const LLViewerTexture* te_image = getImage(iter->first,0);
+ if (!te_image)
+ continue;
+ LLUUID image_id = te_image->getID();
+ if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR)
+ continue;
+ if (all_textures.find(image_id) == all_textures.end())
+ {
+ llinfos << "local_texture: " << texture_dict->mName << ": " << image_id << llendl;
+ all_textures.insert(image_id);
+ }
}
}
- // print any avatar textures we didn't already know about
- for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
- iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
- ++iter)
- {
- const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
- // TODO: MULTI-WEARABLE: handle multiple textures for self
- const LLViewerTexture* te_image = getImage(iter->first,0);
- if (!te_image)
- continue;
- LLUUID image_id = te_image->getID();
- if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR)
- continue;
- if (all_textures.find(image_id) == all_textures.end())
+ if (isSelf() && max_render_cost > 0 && mVisualComplexity != cost)
+ { //pop up notification that you have exceeded a render cost limit
+ if (cost > max_render_cost+max_render_cost/2)
+ {
+ LLNotificationsUtil::add("ExceededHighDetailRenderCost");
+ }
+ else if (cost > max_render_cost)
{
- llinfos << "local_texture: " << texture_dict->mName << ": " << image_id << llendl;
- all_textures.insert(image_id);
+ LLNotificationsUtil::add("ExceededMidDetailRenderCost");
+ }
+ else if (cost > max_render_cost/2)
+ {
+ LLNotificationsUtil::add("ExceededLowDetailRenderCost");
}
}
+
+ mVisualComplexity = cost;
}
- std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus());
- setDebugText(llformat("%s %d", viz_string.c_str(), cost));
- mVisualComplexity = cost;
- F32 green = 1.f-llclamp(((F32) cost-(F32)ARC_LIMIT)/(F32)ARC_LIMIT, 0.f, 1.f);
- F32 red = llmin((F32) cost/(F32)ARC_LIMIT, 1.f);
- mText->setColor(LLColor4(red,green,0,1));
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME))
+ {
+ std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus());
+ setDebugText(llformat("%s %d", viz_string.c_str(), mVisualComplexity));
+ F32 green = 1.f-llclamp(((F32) mVisualComplexity-(F32)ARC_LIMIT)/(F32)ARC_LIMIT, 0.f, 1.f);
+ F32 red = llmin((F32) mVisualComplexity/(F32)ARC_LIMIT, 1.f);
+ mText->setColor(LLColor4(red,green,0,1));
+ }
}
// static
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 1adb680962..e6569c557c 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -252,6 +252,7 @@ public:
static void invalidateNameTags();
void addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font);
void idleUpdateRenderCost();
+ void updateVisualComplexity() { mVisualComplexityStale = TRUE; }
void idleUpdateBelowWater();
//--------------------------------------------------------------------
@@ -314,6 +315,7 @@ private:
BOOL mFullyLoadedInitialized;
S32 mFullyLoadedFrameCounter;
S32 mVisualComplexity;
+ BOOL mVisualComplexityStale;
LLFrameTimer mFullyLoadedTimer;
LLFrameTimer mRuthTimer;
@@ -437,7 +439,6 @@ public:
U32 renderRigid();
U32 renderSkinned(EAvatarRenderPass pass);
F32 getLastSkinTime() { return mLastSkinTime; }
- U32 renderSkinnedAttachments();
U32 renderTransparent(BOOL first_pass);
void renderCollisionVolumes();
static void deleteCachedImages(bool clearAll=true);
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index c0f80cf855..6a18534484 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -99,6 +99,8 @@ static LLFastTimer::DeclareTimer FTM_GEN_TRIANGLES("Generate Triangles");
static LLFastTimer::DeclareTimer FTM_GEN_VOLUME("Generate Volumes");
static LLFastTimer::DeclareTimer FTM_VOLUME_TEXTURES("Volume Textures");
+extern BOOL gGLDebugLoggingEnabled;
+
// Implementation class of LLMediaDataClientObject. See llmediadataclient.h
class LLMediaDataClientObjectImpl : public LLMediaDataClientObject
{
@@ -1067,7 +1069,9 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
break;
}
volume->genBinormals(i);
+ //gGLDebugLoggingEnabled = TRUE;
LLFace::cacheFaceInVRAM(face);
+ //gGLDebugLoggingEnabled = FALSE;
}
}
@@ -1116,6 +1120,12 @@ void LLVOVolume::notifyMeshLoaded()
{
mSculptChanged = TRUE;
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, TRUE);
+
+ LLVOAvatar* avatar = getAvatar();
+ if (avatar)
+ {
+ avatar->updateVisualComplexity();
+ }
}
// sculpt replaces generate() for sculpted surfaces
@@ -4830,6 +4840,16 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
U32 buffer_usage = group->mBufferUsage;
+ static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback");
+
+ if (use_transform_feedback &&
+ gTransformPositionProgram.mProgramObject && //transform shaders are loaded
+ buffer_usage == GL_DYNAMIC_DRAW_ARB && //target buffer is in VRAM
+ !(mask & LLVertexBuffer::MAP_WEIGHT4)) //TODO: add support for weights
+ {
+ buffer_usage = GL_DYNAMIC_COPY_ARB;
+ }
+
#if LL_DARWIN
// HACK from Leslie:
// Disable VBO usage for alpha on Mac OS X because it kills the framerate
@@ -4889,6 +4909,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
//NEVER use more than 16 texture index channels (workaround for prevalent driver bug)
texture_index_channels = llmin(texture_index_channels, 16);
+ bool flexi = false;
+
while (face_iter != faces.end())
{
//pull off next face
@@ -4915,6 +4937,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
U32 index_count = facep->getIndicesCount();
U32 geom_count = facep->getGeomCount();
+ flexi = flexi || facep->getViewerObject()->getVolume()->isUnique();
+
//sum up vertices needed for this render batch
std::vector<LLFace*>::iterator i = face_iter;
++i;
@@ -4983,6 +5007,9 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
}
++i;
+
+ flexi = flexi || facep->getViewerObject()->getVolume()->isUnique();
+
index_count += facep->getIndicesCount();
geom_count += facep->getGeomCount();
@@ -5012,10 +5039,18 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
++i;
index_count += facep->getIndicesCount();
geom_count += facep->getGeomCount();
+
+ flexi = flexi || facep->getViewerObject()->getVolume()->isUnique();
}
}
}
+
+ if (flexi && buffer_usage && buffer_usage != GL_STREAM_DRAW_ARB)
+ {
+ buffer_usage = GL_STREAM_DRAW_ARB;
+ }
+
//create vertex buffer
LLVertexBuffer* buffer = NULL;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 92c5ac8583..690bf64798 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -253,15 +253,15 @@ LLFastTimer::DeclareTimer FTM_RENDER_DEFERRED("Deferred Shading");
static LLFastTimer::DeclareTimer FTM_STATESORT_DRAWABLE("Sort Drawables");
static LLFastTimer::DeclareTimer FTM_STATESORT_POSTSORT("Post Sort");
-static LLStaticHashedString sTint("tint");
-static LLStaticHashedString sAmbiance("ambiance");
-static LLStaticHashedString sAlphaScale("alpha_scale");
-static LLStaticHashedString sNormMat("norm_mat");
-static LLStaticHashedString sOffset("offset");
-static LLStaticHashedString sScreenRes("screenRes");
-static LLStaticHashedString sDelta("delta");
-static LLStaticHashedString sDistFactor("dist_factor");
-static LLStaticHashedString sKern("kern");
+static LLStaticHashedString sTint("tint");
+static LLStaticHashedString sAmbiance("ambiance");
+static LLStaticHashedString sAlphaScale("alpha_scale");
+static LLStaticHashedString sNormMat("norm_mat");
+static LLStaticHashedString sOffset("offset");
+static LLStaticHashedString sScreenRes("screenRes");
+static LLStaticHashedString sDelta("delta");
+static LLStaticHashedString sDistFactor("dist_factor");
+static LLStaticHashedString sKern("kern");
static LLStaticHashedString sKernScale("kern_scale");
//----------------------------------------
@@ -10258,6 +10258,13 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
avatar->mImpostor.bindTarget();
}
+ F32 old_alpha = LLDrawPoolAvatar::sMinimumAlpha;
+
+ if (muted)
+ { //disable alpha masking for muted avatars (get whole skin silhouette)
+ LLDrawPoolAvatar::sMinimumAlpha = 0.f;
+ }
+
if (LLPipeline::sRenderDeferred)
{
avatar->mImpostor.clear();
@@ -10272,6 +10279,8 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
renderGeom(camera);
}
+ LLDrawPoolAvatar::sMinimumAlpha = old_alpha;
+
{ //create alpha mask based on depth buffer (grey out if muted)
LLFastTimer t(FTM_IMPOSTOR_BACKGROUND);
if (LLPipeline::sRenderDeferred)
@@ -10285,6 +10294,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
if (muted)
{
gGL.setColorMask(true, true);
+
}
else
{
@@ -10303,14 +10313,24 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
gGL.pushMatrix();
gGL.loadIdentity();
- static const F32 clip_plane = 0.99999f;
+ static const F32 clip_plane = 0.999f;
if (LLGLSLShader::sNoFixedFunction)
{
- gUIProgram.bind();
+ gDebugProgram.bind();
}
- gGL.color4ub(64,64,64,255);
+
+ if (LLMuteList::getInstance()->isMuted(avatar->getID()))
+ { //grey muted avatar
+ gGL.diffuseColor4ub(64,64,64,255);
+ }
+ else
+ { //blue visually muted avatar
+ gGL.diffuseColor4ub(72,61,139,255);
+ }
+
+ {
gGL.begin(LLRender::QUADS);
gGL.vertex3f(-1, -1, clip_plane);
gGL.vertex3f(1, -1, clip_plane);
@@ -10318,10 +10338,11 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
gGL.vertex3f(-1, 1, clip_plane);
gGL.end();
gGL.flush();
+ }
if (LLGLSLShader::sNoFixedFunction)
{
- gUIProgram.unbind();
+ gDebugProgram.unbind();
}
gGL.popMatrix();
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 832e05a06f..fb530ef22d 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -203,6 +203,45 @@ Message Template [PATH] not found.
</notification>
<notification
+ icon="notify.tga"
+ name="ExceededHighDetailRenderCost"
+ persist="false"
+ type="alertmodal">
+ Your avatar has become too complex to be rendered by even high performance computers. Almost all Residents will see a low detail stand in instead of your actual avatar.
+ <unique/>
+ <usetemplate
+ ignoretext="Avatar exceeded high detail complexity."
+ name="okignore"
+ yestext="Close"/>
+ </notification>
+
+ <notification
+ icon="notify.tga"
+ name="ExceededMidDetailRenderCost"
+ persist="false"
+ type="alertmodal">
+ Your avatar has become too complex to be rendered by most computers. Many Residents will see a low detail stand in instead of your actual avatar.
+ <unique/>
+ <usetemplate
+ ignoretext="Avatar exceeded mid detail complexity."
+ name="okignore"
+ yestext="Close"/>
+</notification>
+
+ <notification
+ icon="notify.tga"
+ name="ExceededLowDetailRenderCost"
+ persist="false"
+ type="alertmodal">
+ Your avatar has become too complex to be rendered by some computers. Some Residents will see a low detail stand in instead of your actual avatar.
+ <unique/>
+ <usetemplate
+ ignoretext="Avatar exceeded low detail complexity."
+ name="okignore"
+ yestext="Close"/>
+ </notification>
+
+ <notification
icon="alertmodal.tga"
name="WearableSave"
type="alertmodal">
@@ -9935,5 +9974,5 @@ An internal error prevented us from properly updating your viewer. The L$ balan
<tag>fail</tag>
Cannot create large prims that intersect other players. Please re-try when other players have moved.
</notification>
-
+
</notifications>