SH-2889 Add visual auto-muting controls

master
Dave Parks 2012-01-20 16:42:57 -06:00
parent 655505d304
commit 18e7f1bffd
13 changed files with 193 additions and 45 deletions

View File

@ -2078,6 +2078,7 @@ LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL ge
mFaceMask = 0x0;
mDetail = detail;
mSculptLevel = -2;
mSurfaceArea = 1.f; //only calculated for sculpts, defaults to 1 for all other prims
mIsMeshAssetLoaded = FALSE;
mLODScaleBias.setVec(1,1,1);
mHullPoints = NULL;
@ -3144,6 +3145,8 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components,
{
F32 area = sculptGetSurfaceArea();
mSurfaceArea = area;
const F32 SCULPT_MAX_AREA = 384.f;
if (area < SCULPT_MIN_AREA || area > SCULPT_MAX_AREA)

View File

@ -963,6 +963,7 @@ public:
S32 getNumFaces() const;
S32 getNumVolumeFaces() const { return mVolumeFaces.size(); }
F32 getDetail() const { return mDetail; }
F32 getSurfaceArea() const { return mSurfaceArea; }
const LLVolumeParams& getParams() const { return mParams; }
LLVolumeParams getCopyOfParams() const { return mParams; }
const LLProfile& getProfile() const { return *mProfilep; }
@ -1065,6 +1066,7 @@ public:
BOOL mUnique;
F32 mDetail;
S32 mSculptLevel;
F32 mSurfaceArea; //unscaled surface area
BOOL mIsMeshAssetLoaded;
LLVolumeParams mParams;

View File

@ -9024,6 +9024,28 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>RenderAutoMuteByteLimit</key>
<map>
<key>Comment</key>
<string>Maximum bytes of attachments before an avatar is automatically visually muted (0 for no limit).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>RenderAutoMuteSurfaceAreaLimit</key>
<map>
<key>Comment</key>
<string>Maximum surface area of attachments before an avatar is automatically visually muted (0 for no limit).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>RenderUseShaderLOD</key>
<map>
<key>Comment</key>

View File

@ -1077,6 +1077,7 @@ BOOL LLDrawable::isVisible() const
LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask)
: LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB)
{
mBridge = this;
mDrawable = root;
root->setSpatialBridge(this);
@ -1105,6 +1106,15 @@ LLSpatialBridge::~LLSpatialBridge()
{
group->mSpatialPartition->remove(this, group);
}
//delete octree here so listeners will still be able to access bridge specific state
destroyTree();
}
void LLSpatialBridge::destroyTree()
{
delete mOctree;
mOctree = NULL;
}
void LLSpatialBridge::updateSpatialExtents()

View File

@ -1187,6 +1187,8 @@ void LLSpatialGroup::clearOcclusionState(U32 state, S32 mode)
LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
mState(0),
mGeometryBytes(0),
mSurfaceArea(0.f),
mBuilt(0.f),
mOctreeNode(node),
mSpatialPartition(part),
@ -1412,6 +1414,17 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node)
}
}
//clean up avatar attachment stats
LLSpatialBridge* bridge = mSpatialPartition->asBridge();
if (bridge)
{
if (bridge->mAvatar.notNull())
{
bridge->mAvatar->mAttachmentGeometryBytes -= mGeometryBytes;
bridge->mAvatar->mAttachmentSurfaceArea -= mSurfaceArea;
}
}
clearDrawMap();
mVertexBuffer = NULL;
mBufferMap.clear();
@ -1767,7 +1780,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
//==============================================
LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage)
: mRenderByGroup(render_by_group)
: mRenderByGroup(render_by_group), mBridge(NULL)
{
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
mOcclusionEnabled = TRUE;

View File

@ -405,6 +405,9 @@ public:
bridge_list_t mBridgeList;
buffer_map_t mBufferMap; //used by volume buffers to attempt to reuse vertex buffers
U32 mGeometryBytes; //used by volumes to track how many bytes of geometry data are in this node
F32 mSurfaceArea; //used by volumes to track estimated surface area of geometry in this node
F32 mBuilt;
OctreeNode* mOctreeNode;
LLSpatialPartition* mSpatialPartition;
@ -474,8 +477,8 @@ public:
BOOL isVisible(const LLVector3& v);
bool isHUDPartition() ;
virtual LLSpatialBridge* asBridge() { return NULL; }
virtual BOOL isBridge() { return asBridge() != NULL; }
LLSpatialBridge* asBridge() { return mBridge; }
BOOL isBridge() { return asBridge() != NULL; }
void renderPhysicsShapes();
void renderDebug();
@ -487,6 +490,9 @@ public:
public:
LLSpatialGroup::OctreeNode* mOctree;
LLSpatialBridge* mBridge; // NULL for non-LLSpatialBridge instances, otherwise, mBridge == this
// use a pointer instead of making "isBridge" and "asBridge" virtual so it's safe
// to call asBridge() from the destructor
BOOL mOcclusionEnabled; // if TRUE, occlusion culling is performed
BOOL mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane
U32 mBufferUsage;
@ -511,8 +517,9 @@ public:
LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask);
virtual BOOL isSpatialBridge() const { return TRUE; }
void destroyTree();
virtual BOOL isSpatialBridge() const { return TRUE; }
virtual void updateSpatialExtents();
virtual void updateBinRadius();
virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results = NULL, BOOL for_select = FALSE);
@ -523,11 +530,12 @@ public:
virtual void shiftPos(const LLVector4a& vec);
virtual void cleanupReferences();
virtual LLSpatialPartition* asPartition() { return this; }
virtual LLSpatialBridge* asBridge() { return this; }
virtual LLCamera transformCamera(LLCamera& camera);
LLDrawable* mDrawable;
LLPointer<LLVOAvatar> mAvatar;
};
class LLCullResult

View File

@ -947,6 +947,10 @@ U32 info_display_from_string(std::string info_display)
{
return LLPipeline::RENDER_DEBUG_COMPOSITION;
}
else if ("attachment bytes" == info_display)
{
return LLPipeline::RENDER_DEBUG_ATTACHMENT_BYTES;
}
else if ("glow" == info_display)
{
return LLPipeline::RENDER_DEBUG_GLOW;

View File

@ -651,6 +651,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
LLViewerObject(id, pcode, regionp),
mIsDummy(FALSE),
mSpecialRenderMode(0),
mAttachmentGeometryBytes(0),
mAttachmentSurfaceArea(0.f),
mTurning(FALSE),
mPelvisToFoot(0.f),
mLastSkeletonSerialNum( 0 ),
@ -3363,6 +3365,16 @@ void LLVOAvatar::slamPosition()
mRoot.updateWorldMatrixChildren();
}
bool LLVOAvatar::isVisuallyMuted()
{
static LLCachedControl<U32> max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit");
static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit");
return LLMuteList::getInstance()->isMuted(getID()) ||
(mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) ||
(mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f);
}
//------------------------------------------------------------------------
// updateCharacter()
// called on both your avatar and other avatars
@ -3429,8 +3441,9 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
size.setSub(ext[1],ext[0]);
F32 mag = size.getLength3().getF32()*0.5f;
F32 impostor_area = 256.f*512.f*(8.125f - LLVOAvatar::sLODFactor*8.f);
if (LLMuteList::getInstance()->isMuted(getID()))
if (isVisuallyMuted())
{ // muted avatars update at 16 hz
mUpdatePeriod = 16;
}
@ -8333,6 +8346,11 @@ void LLVOAvatar::idleUpdateRenderCost()
static std::set<LLUUID> all_textures;
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_ATTACHMENT_BYTES))
{ //set debug text to attachment geometry bytes here so render cost will override
setDebugText(llformat("%.1f KB, %.2f m^2", mAttachmentGeometryBytes/1024.f, mAttachmentSurfaceArea));
}
if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME))
{
return;

View File

@ -380,6 +380,8 @@ private:
public:
U32 renderImpostor(LLColor4U color = LLColor4U(255,255,255,255), S32 diffuse_channel = 0);
bool isVisuallyMuted();
U32 renderRigid();
U32 renderSkinned(EAvatarRenderPass pass);
F32 getLastSkinTime() { return mLastSkinTime; }
@ -391,6 +393,9 @@ public:
static void restoreGL();
BOOL mIsDummy; // for special views
S32 mSpecialRenderMode; // special lighting
U32 mAttachmentGeometryBytes; //number of bytes in attached geometry
F32 mAttachmentSurfaceArea; //estimated surface area of attachments
private:
bool shouldAlphaMask();

View File

@ -4097,6 +4097,32 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB);
LLVOAvatar* pAvatarVO = NULL;
LLSpatialBridge* bridge = group->mSpatialPartition->asBridge();
if (bridge)
{
if (bridge->mAvatar.isNull())
{
LLViewerObject* vobj = bridge->mDrawable->getVObj();
if (vobj)
{
bridge->mAvatar = vobj->getAvatar();
}
}
pAvatarVO = bridge->mAvatar;
}
if (pAvatarVO)
{
pAvatarVO->mAttachmentGeometryBytes -= group->mGeometryBytes;
pAvatarVO->mAttachmentSurfaceArea -= group->mSurfaceArea;
}
group->mGeometryBytes = 0;
group->mSurfaceArea = 0;
group->clearDrawMap();
mFaceList.clear();
@ -4133,12 +4159,24 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
LLVOVolume* vobj = drawablep->getVOVolume();
if (!vobj)
{
continue;
}
if (vobj->isMesh() &&
(vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled()))
{
continue;
}
LLVolume* volume = vobj->getVolume();
if (volume)
{
const LLVector3& scale = vobj->getScale();
group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]);
}
llassert_always(vobj);
vobj->updateTextureVirtualSize(true);
vobj->preRebuild();
@ -4183,7 +4221,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
//Determine if we've received skininfo that contains an
//alternate bind matrix - if it does then apply the translational component
//to the joints of the avatar.
LLVOAvatar* pAvatarVO = vobj->getAvatar();
bool pelvisGotSet = false;
if ( pAvatarVO )
@ -4253,13 +4290,16 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (type == LLDrawPool::POOL_ALPHA)
{
if (te->getFullbright())
if (te->getColor().mV[3] > 0.f)
{
pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA);
}
else
{
pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA);
if (te->getFullbright())
{
pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA);
}
else
{
pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA);
}
}
}
else if (te->getShiny())
@ -4392,8 +4432,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
else
{
drawablep->setState(LLDrawable::HAS_ALPHA);
alpha_faces.push_back(facep);
if (te->getColor().mV[3] > 0.f)
{
drawablep->setState(LLDrawable::HAS_ALPHA);
alpha_faces.push_back(facep);
}
}
}
else
@ -4510,6 +4553,12 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
mFaceList.clear();
if (pAvatarVO)
{
pAvatarVO->mAttachmentGeometryBytes += group->mGeometryBytes;
pAvatarVO->mAttachmentSurfaceArea += group->mSurfaceArea;
}
}
static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM("Volume Geometry");
@ -4838,6 +4887,9 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
}
}
group->mGeometryBytes += buffer->getSize() + buffer->getIndicesSize();
buffer_map[mask][*face_iter].push_back(buffer);
//add face geometry

View File

@ -9420,7 +9420,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
assertInitialized();
BOOL muted = LLMuteList::getInstance()->isMuted(avatar->getID());
bool muted = avatar->isVisuallyMuted();
pushRenderTypeMask();

View File

@ -432,34 +432,35 @@ public:
enum LLRenderDebugMask
{
RENDER_DEBUG_COMPOSITION = 0x0000001,
RENDER_DEBUG_VERIFY = 0x0000002,
RENDER_DEBUG_BBOXES = 0x0000004,
RENDER_DEBUG_OCTREE = 0x0000008,
RENDER_DEBUG_WIND_VECTORS = 0x0000010,
RENDER_DEBUG_OCCLUSION = 0x0000020,
RENDER_DEBUG_POINTS = 0x0000040,
RENDER_DEBUG_TEXTURE_PRIORITY = 0x0000080,
RENDER_DEBUG_TEXTURE_AREA = 0x0000100,
RENDER_DEBUG_FACE_AREA = 0x0000200,
RENDER_DEBUG_PARTICLES = 0x0000400,
RENDER_DEBUG_GLOW = 0x0000800,
RENDER_DEBUG_TEXTURE_ANIM = 0x0001000,
RENDER_DEBUG_LIGHTS = 0x0002000,
RENDER_DEBUG_BATCH_SIZE = 0x0004000,
RENDER_DEBUG_ALPHA_BINS = 0x0008000,
RENDER_DEBUG_RAYCAST = 0x0010000,
RENDER_DEBUG_SHAME = 0x0020000,
RENDER_DEBUG_SHADOW_FRUSTA = 0x0040000,
RENDER_DEBUG_SCULPTED = 0x0080000,
RENDER_DEBUG_AVATAR_VOLUME = 0x0100000,
RENDER_DEBUG_BUILD_QUEUE = 0x0200000,
RENDER_DEBUG_AGENT_TARGET = 0x0400000,
RENDER_DEBUG_UPDATE_TYPE = 0x0800000,
RENDER_DEBUG_PHYSICS_SHAPES = 0x1000000,
RENDER_DEBUG_NORMALS = 0x2000000,
RENDER_DEBUG_LOD_INFO = 0x4000000,
RENDER_DEBUG_RENDER_COMPLEXITY = 0x8000000
RENDER_DEBUG_COMPOSITION = 0x00000001,
RENDER_DEBUG_VERIFY = 0x00000002,
RENDER_DEBUG_BBOXES = 0x00000004,
RENDER_DEBUG_OCTREE = 0x00000008,
RENDER_DEBUG_WIND_VECTORS = 0x00000010,
RENDER_DEBUG_OCCLUSION = 0x00000020,
RENDER_DEBUG_POINTS = 0x00000040,
RENDER_DEBUG_TEXTURE_PRIORITY = 0x00000080,
RENDER_DEBUG_TEXTURE_AREA = 0x00000100,
RENDER_DEBUG_FACE_AREA = 0x00000200,
RENDER_DEBUG_PARTICLES = 0x00000400,
RENDER_DEBUG_GLOW = 0x00000800,
RENDER_DEBUG_TEXTURE_ANIM = 0x00001000,
RENDER_DEBUG_LIGHTS = 0x00002000,
RENDER_DEBUG_BATCH_SIZE = 0x00004000,
RENDER_DEBUG_ALPHA_BINS = 0x00008000,
RENDER_DEBUG_RAYCAST = 0x00010000,
RENDER_DEBUG_SHAME = 0x00020000,
RENDER_DEBUG_SHADOW_FRUSTA = 0x00040000,
RENDER_DEBUG_SCULPTED = 0x00080000,
RENDER_DEBUG_AVATAR_VOLUME = 0x00100000,
RENDER_DEBUG_BUILD_QUEUE = 0x00200000,
RENDER_DEBUG_AGENT_TARGET = 0x00400000,
RENDER_DEBUG_UPDATE_TYPE = 0x00800000,
RENDER_DEBUG_PHYSICS_SHAPES = 0x01000000,
RENDER_DEBUG_NORMALS = 0x02000000,
RENDER_DEBUG_LOD_INFO = 0x04000000,
RENDER_DEBUG_RENDER_COMPLEXITY = 0x08000000,
RENDER_DEBUG_ATTACHMENT_BYTES = 0x10000000,
};
public:

View File

@ -2499,6 +2499,16 @@
<menu_item_check.on_click
function="Advanced.ToggleInfoDisplay"
parameter="rendercomplexity" />
</menu_item_check>
<menu_item_check
label="Attachment Bytes"
name="attachment bytes">
<menu_item_check.on_check
function="Advanced.CheckInfoDisplay"
parameter="attachment bytes" />
<menu_item_check.on_click
function="Advanced.ToggleInfoDisplay"
parameter="attachment bytes" />
</menu_item_check>
<menu_item_check
label="Sculpt"