Add debug floater to show how much texture memory objects in view use (per object).

Wed, 07 Jan 2015 01:34:44 +0100

author
Nicky
date
Wed, 07 Jan 2015 01:34:44 +0100
changeset 43106
f3934808b579
parent 43105
bf8b86ab1f11
child 43107
f6a5c7440b7c

Add debug floater to show how much texture memory objects in view use (per object).

indra/llrender/llgltexture.h file | annotate | diff | revisions
indra/newview/CMakeLists.txt file | annotate | diff | revisions
indra/newview/fsfloatervramusage.cpp file | annotate | diff | revisions
indra/newview/fsfloatervramusage.h file | annotate | diff | revisions
indra/newview/llface.cpp file | annotate | diff | revisions
indra/newview/llselectmgr.cpp file | annotate | diff | revisions
indra/newview/llselectmgr.h file | annotate | diff | revisions
indra/newview/llviewerfloaterreg.cpp file | annotate | diff | revisions
indra/newview/skins/default/xui/en/fs_floater_vram_usage.xml file | annotate | diff | revisions
indra/newview/skins/default/xui/en/menu_viewer.xml file | annotate | diff | revisions
     1.1 --- a/indra/llrender/llgltexture.h	Tue Jan 06 20:11:15 2015 +0100
     1.2 +++ b/indra/llrender/llgltexture.h	Wed Jan 07 01:34:44 2015 +0100
     1.3 @@ -192,7 +192,10 @@
     1.4  protected:
     1.5  	LLGLTextureState  mTextureState ;
     1.6  
     1.7 -
     1.8 +// <FS>ND> Expose mipmap generation so we can check it for texture memory tax
     1.9 +public:
    1.10 +	bool getUseMipMaps() const { return mUseMipMaps; }
    1.11 +// </FS:ND>
    1.12  };
    1.13  
    1.14  #endif // LL_GL_TEXTURE_H
     2.1 --- a/indra/newview/CMakeLists.txt	Tue Jan 06 20:11:15 2015 +0100
     2.2 +++ b/indra/newview/CMakeLists.txt	Wed Jan 07 01:34:44 2015 +0100
     2.3 @@ -208,6 +208,7 @@
     2.4      lggcontactsets.cpp
     2.5      lfsimfeaturehandler.cpp
     2.6      llpanelopenregionsettings.cpp
     2.7 +	fsfloatervramusage.cpp
     2.8  
     2.9      llaccountingcostmanager.cpp
    2.10      llagent.cpp
    2.11 @@ -926,6 +927,7 @@
    2.12      lggbeamscolors.h
    2.13      lggcontactsets.h
    2.14      lfsimfeaturehandler.h
    2.15 +	fsfloatervramusage.h
    2.16  
    2.17      llaccountingcostmanager.h
    2.18      llagent.h
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/indra/newview/fsfloatervramusage.cpp	Wed Jan 07 01:34:44 2015 +0100
     3.3 @@ -0,0 +1,343 @@
     3.4 +/**
     3.5 + * $LicenseInfo:firstyear=2015&license=viewerlgpl$
     3.6 + * Phoenix Firestorm Viewer Source Code
     3.7 + * Copyright (c) 2015 Nicky Dasmijn
     3.8 + *
     3.9 + * This library is free software; you can redistribute it and/or
    3.10 + * modify it under the terms of the GNU Lesser General Public
    3.11 + * License as published by the Free Software Foundation;
    3.12 + * version 2.1 of the License only.
    3.13 + *
    3.14 + * This library is distributed in the hope that it will be useful,
    3.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    3.17 + * Lesser General Public License for more details.
    3.18 + *
    3.19 + * You should have received a copy of the GNU Lesser General Public
    3.20 + * License along with this library; if not, write to the Free Software
    3.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    3.22 + * 
    3.23 + * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
    3.24 + * http://www.firestormviewer.org
    3.25 + * $/LicenseInfo$
    3.26 + */
    3.27 +
    3.28 +#include "llviewerprecompiledheaders.h"
    3.29 +
    3.30 +#include "fsfloatervramusage.h"
    3.31 +#include "llscrolllistctrl.h"
    3.32 +#include "llviewerobjectlist.h"
    3.33 +#include "lldrawable.h"
    3.34 +#include "llviewertexture.h"
    3.35 +#include "lltoolpie.h"
    3.36 +#include "llfloaterreg.h"
    3.37 +#include "llface.h"
    3.38 +#include "llvertexbuffer.h"
    3.39 +#include "llcallbacklist.h"
    3.40 +#include "llvoavatarself.h"
    3.41 +#include "llagentcamera.h"
    3.42 +
    3.43 +const F32 PROPERTIES_REQUEST_TIMEOUT = 10.0f;
    3.44 +const F32 PROPERY_REQUEST_INTERVAL = 2.0f;
    3.45 +const U32 PROPERTIES_MAX_REQUEST_COUNT = 250;
    3.46 +
    3.47 +static void onIdle( void *aData )
    3.48 +{
    3.49 +	FSFloaterVRAMUsage *pFloater = reinterpret_cast<FSFloaterVRAMUsage*>(aData);
    3.50 +	pFloater->onIdle();
    3.51 +}
    3.52 +
    3.53 +struct ObjectStat
    3.54 +{
    3.55 +	LLUUID mId;
    3.56 +	U32 mTextureSize;
    3.57 +};
    3.58 +
    3.59 +struct FSFloaterVRAMUsage::ImplData
    3.60 +{
    3.61 +	LLScrollListCtrl *mList;
    3.62 +	LLObjectSelectionHandle mSelection;
    3.63 +	U32 mPending;
    3.64 +	LLFrameTimer mPropTimer;
    3.65 +
    3.66 +	std::deque< ObjectStat > mObjects;
    3.67 +};
    3.68 +
    3.69 +bool sortByTexture( ObjectStat const &lhs, ObjectStat const &rhs )
    3.70 +{
    3.71 +	return lhs.mTextureSize > rhs.mTextureSize;
    3.72 +}
    3.73 +
    3.74 +FSFloaterVRAMUsage::FSFloaterVRAMUsage(const LLSD& seed)
    3.75 +	: LLFloater( seed )
    3.76 +{
    3.77 +	mData = new ImplData();
    3.78 +	mData->mList = 0;
    3.79 +	mData->mPending = 0;
    3.80 +
    3.81 + 	gIdleCallbacks.addFunction( &::onIdle, this) ;
    3.82 +}
    3.83 +
    3.84 +FSFloaterVRAMUsage::~FSFloaterVRAMUsage()
    3.85 +{
    3.86 + 	gIdleCallbacks.deleteFunction( &::onIdle, this );
    3.87 +	delete mData;
    3.88 +	LLSelectMgr::instance().removePropertyListener( this );
    3.89 +	LLSelectMgr::instance().enableSilhouette( TRUE );
    3.90 +}
    3.91 +
    3.92 +void FSFloaterVRAMUsage::onOpen(const LLSD& key)
    3.93 +{
    3.94 +}
    3.95 +
    3.96 +BOOL FSFloaterVRAMUsage::postBuild()
    3.97 +{
    3.98 +	LLButton *pRefresh = getChild< LLButton >( "refresh_button" );
    3.99 +	pRefresh->setClickedCallback( boost::bind( &FSFloaterVRAMUsage::doRefresh, this ) );
   3.100 +
   3.101 +	mData->mList = getChild< LLScrollListCtrl >( "result_list" );
   3.102 +
   3.103 +	LLSelectMgr::instance().registerPropertyListener( this );
   3.104 +	LLSelectMgr::instance().enableSilhouette( FALSE );
   3.105 +
   3.106 +	return TRUE;
   3.107 +}
   3.108 +
   3.109 +void FSFloaterVRAMUsage::onIdle()
   3.110 +{
   3.111 +	if( !mData->mPending && mData->mObjects.empty() )
   3.112 +	{
   3.113 +		LLSelectMgr::instance().deselectAll();
   3.114 +		return;
   3.115 +	}
   3.116 +	
   3.117 +	if( mData->mPending && mData->mPropTimer.getElapsedTimeF32() < PROPERTIES_REQUEST_TIMEOUT ) 
   3.118 +		return;
   3.119 +
   3.120 +	if( !mData->mPending && mData->mPropTimer.getStarted() && mData->mPropTimer.getElapsedTimeF32() < PROPERY_REQUEST_INTERVAL ) 
   3.121 +		return;
   3.122 +
   3.123 +	LLSelectMgr::instance().deselectAll();
   3.124 +	mData->mPending = 0;
   3.125 +
   3.126 +	std::vector< LLViewerObject* > vctSelection;
   3.127 +	std::deque< ObjectStat > withoutRegion;
   3.128 +
   3.129 +	while( mData->mPending < PROPERTIES_MAX_REQUEST_COUNT && !mData->mObjects.empty() )
   3.130 +	{
   3.131 +		LLViewerObject *pObj = gObjectList.findObject(  mData->mObjects[ 0 ].mId );
   3.132 +		if( pObj && pObj->getRegion() )
   3.133 +		{
   3.134 +			++mData->mPending;
   3.135 +			vctSelection.push_back( pObj );
   3.136 +		}
   3.137 +		else if( pObj )
   3.138 +			withoutRegion.push_back( mData->mObjects[0] );
   3.139 +
   3.140 +		mData->mObjects.erase( mData->mObjects.begin() );
   3.141 +	}
   3.142 +
   3.143 +	mData->mObjects.insert( mData->mObjects.end(), withoutRegion.begin(), withoutRegion.end() );
   3.144 +
   3.145 +	mData->mPropTimer.start();
   3.146 +	if( vctSelection.size() )
   3.147 +	{
   3.148 +		LLSelectMgr::instance().enableBatchMode();
   3.149 +		mData->mSelection = LLSelectMgr::instance().selectObjectAndFamily( vctSelection );
   3.150 +		LLSelectMgr::instance().disableBatchMode();
   3.151 +	}
   3.152 +}
   3.153 +
   3.154 +U32 FSFloaterVRAMUsage::calcTexturSize( LLViewerObject *aObject, std::ostream *aTooltip )
   3.155 +{
   3.156 +	if( !aObject || !aObject->mDrawable || aObject->mDrawable->isDead() )
   3.157 +		return 0;
   3.158 +
   3.159 +	std::map< LLUUID, U32 > stTextures;
   3.160 +
   3.161 +	F64 totalTexSize = 0;
   3.162 +	U8 numTEs = aObject->getNumTEs();
   3.163 +
   3.164 +	if (aTooltip )
   3.165 +		*aTooltip << (U32)numTEs << " TEs" << std::endl;
   3.166 +
   3.167 +	for( U8 j = 0; j < numTEs; ++j )
   3.168 +	{
   3.169 +		LLViewerTexture *pTex = aObject->getTEImage( j );
   3.170 +		if( !pTex || pTex->isMissingAsset() )
   3.171 +			continue;
   3.172 +
   3.173 +		U32 textureId = stTextures.size();
   3.174 +		bool bOldTexId( false );
   3.175 +
   3.176 +		if( stTextures.end() != stTextures.find( pTex->getID() ) )
   3.177 +		{
   3.178 +			textureId = stTextures[ pTex->getID() ];
   3.179 +			bOldTexId = true;
   3.180 +		}
   3.181 +
   3.182 +		if (aTooltip )
   3.183 +			*aTooltip << "TE: " << (U32)j << " tx: " << textureId	<< " w/h/c " << pTex->getFullWidth() << "/" << pTex->getFullHeight() << "/" << (U32)pTex->getComponents() << std::endl;
   3.184 +
   3.185 +		if( bOldTexId )
   3.186 +			continue;
   3.187 +
   3.188 +		stTextures[ pTex->getID() ] = textureId;
   3.189 +
   3.190 +		S32 texSize = pTex->getFullWidth() * pTex->getFullHeight() * pTex->getComponents();
   3.191 +		if( pTex->getUseMipMaps() )
   3.192 +			texSize += (texSize*33)/100;
   3.193 +
   3.194 +		totalTexSize += texSize;
   3.195 +	}
   3.196 +
   3.197 +	totalTexSize /= 1024.0;
   3.198 +	return static_cast< U32 >( totalTexSize );
   3.199 +}
   3.200 +
   3.201 +void FSFloaterVRAMUsage::doRefresh()
   3.202 +{
   3.203 +	mData->mList->deleteAllItems();
   3.204 +	S32 numObjects = gObjectList.getNumObjects();
   3.205 +
   3.206 +	mData->mPending = 0;
   3.207 +	mData->mObjects.clear();
   3.208 +	LLSelectMgr::instance().deselectAll();
   3.209 +
   3.210 +	for( S32 i = 0; i < numObjects; ++i )
   3.211 +	{
   3.212 +		LLViewerObject *pObj = gObjectList.getObject( i );
   3.213 +		if( !pObj ) // Might be dead
   3.214 +			continue;
   3.215 +
   3.216 +		if( !pObj->mbCanSelect ||
   3.217 +			pObj->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH ||
   3.218 +			pObj->getPCode() == LLViewerObject::LL_VO_SKY ||
   3.219 +			pObj->getPCode() == LLViewerObject::LL_VO_WL_SKY ||
   3.220 +			pObj->getPCode() == LLViewerObject::LL_VO_VOID_WATER ||
   3.221 +			pObj->getPCode() == LLViewerObject::LL_VO_WATER ||
   3.222 +			pObj->isAvatar() )
   3.223 +			continue;
   3.224 +
   3.225 +		// Exclude everything that's not in a sphere with r=draw distance around the avatar.
   3.226 +		F64 distance = (pObj->getPositionGlobal() - gAgentAvatarp->getPositionGlobal()).length();
   3.227 +		if( distance > gAgentCamera.mDrawDistance )
   3.228 +			continue;
   3.229 +
   3.230 +		ObjectStat oObject;
   3.231 +		oObject.mId = pObj->getID();
   3.232 +		oObject.mTextureSize = calcTexturSize( pObj );
   3.233 +
   3.234 +		mData->mObjects.push_back( oObject );
   3.235 +	}
   3.236 +	std::sort( mData->mObjects.begin(), mData->mObjects.end(), sortByTexture );
   3.237 +}
   3.238 +
   3.239 +void FSFloaterVRAMUsage::addObjectToList( LLViewerObject *aObject, std::string const &aName )
   3.240 +{
   3.241 +	LLScrollListItem::Params item;
   3.242 +
   3.243 +	F64 distance = (aObject->getPositionGlobal() - gAgentAvatarp->getPositionGlobal()).length();
   3.244 +
   3.245 +	item.columns.add().column("uuid").value( aObject->getID() );
   3.246 +	item.columns.add().column("name").value( aName );
   3.247 +	item.columns.add().column("distance").value( distance );
   3.248 +	item.columns.add().column("faces").value( aObject->getNumFaces() );
   3.249 +	item.columns.add().column("vertices").value( static_cast<S32>( aObject->getNumVertices() ) );
   3.250 +	item.columns.add().column("indices").value( static_cast<S32>( aObject->getNumIndices() ) );
   3.251 +
   3.252 +	std::stringstream strTooltip;
   3.253 +	U32 totalTexSize = calcTexturSize( aObject, &strTooltip );
   3.254 +
   3.255 +	F64 totalVboSize(0.0);
   3.256 +
   3.257 +	LLPointer< LLDrawable > pDrawable = aObject->mDrawable;
   3.258 +	S32 numFaces = 0;
   3.259 +	if( pDrawable && !pDrawable->isDead() )
   3.260 +		numFaces = pDrawable->getNumFaces();
   3.261 +
   3.262 +	strTooltip << numFaces << " faces" << std::endl;
   3.263 +	for (S32 j = 0; j < numFaces; j++)
   3.264 +	{
   3.265 +		LLFace* pFace = pDrawable->getFace( j );
   3.266 +		if( !pFace )
   3.267 +			continue;
   3.268 +
   3.269 +		S32 cmW = 0, cmH = 0;
   3.270 +
   3.271 +		calcFaceSize( pFace, cmW, cmH );
   3.272 +
   3.273 +		strTooltip << "Face: " << j << " extends (cm) w/h " << cmW << "/" << cmH << std::endl;
   3.274 +
   3.275 +		S32 vertexSize = calcVBOEntrySize( pFace->getVertexBuffer() ) * aObject->getNumVertices();;
   3.276 +		S32 indexSize = sizeof( S16 ) * aObject->getNumIndices();
   3.277 +
   3.278 +		totalVboSize += vertexSize;
   3.279 +		totalVboSize += indexSize;
   3.280 +	}
   3.281 +
   3.282 +	totalVboSize /= 1024.0;
   3.283 +
   3.284 +	item.columns.add().column("vram_usage").value( (S32)totalTexSize );
   3.285 +	item.columns.add().column("vram_usage_vbo").value( (S32)totalVboSize );
   3.286 +
   3.287 +	LLScrollListItem *pRow = mData->mList->addRow( item );
   3.288 +	if( pRow )
   3.289 +	{
   3.290 +		for( S32 j = 0; j < pRow->getNumColumns(); ++j )
   3.291 +			pRow->getColumn( j )->setToolTip( strTooltip.str() );
   3.292 +	}
   3.293 +}
   3.294 +
   3.295 +void FSFloaterVRAMUsage::calcFaceSize( LLFace *aFace, S32 &aW, S32 &aH )
   3.296 +{
   3.297 +	aW = aH = 0;
   3.298 +	if( !aFace )
   3.299 +		return;
   3.300 +
   3.301 +	LLVector4a size;
   3.302 +	size.setSub( aFace->mExtents[1], aFace->mExtents[0] );
   3.303 +
   3.304 +	S32 cmX = static_cast<S32>( size[0]*100 );
   3.305 +	S32 cmY = static_cast<S32>( size[1]*100 );
   3.306 +	S32 cmZ = static_cast<S32>( size[2]*100 );
   3.307 +
   3.308 +	aW = cmX;
   3.309 +	aH = cmY;
   3.310 +
   3.311 +	if( 0 != cmZ )
   3.312 +	{
   3.313 +		if( 0 == aW )
   3.314 +			aW = cmZ;
   3.315 +		else
   3.316 +			aH = cmZ;
   3.317 +	}
   3.318 +}
   3.319 +
   3.320 +S32 FSFloaterVRAMUsage::calcVBOEntrySize( LLVertexBuffer *aVBO )
   3.321 +{
   3.322 +	if( !aVBO )
   3.323 +		return 0;
   3.324 +
   3.325 +	S32 vboEntrySize(0);
   3.326 +
   3.327 +	U32 vboMask = aVBO->getTypeMask();
   3.328 +	for( S32 k = 0, l = 1; k < LLVertexBuffer::TYPE_MAX; ++k )
   3.329 +	{
   3.330 +		if( vboMask & l && k != LLVertexBuffer::TYPE_TEXTURE_INDEX )
   3.331 +			vboEntrySize += LLVertexBuffer::sTypeSize[ k ];
   3.332 +		l = l << 1;
   3.333 +	}
   3.334 +
   3.335 +	return vboEntrySize;
   3.336 +}
   3.337 +
   3.338 +void FSFloaterVRAMUsage::onProperties( LLSelectNode const *aProps )
   3.339 +{
   3.340 +	if( !aProps && !aProps->getObject() )
   3.341 +		return;
   3.342 +
   3.343 +	LLUUID id = aProps->getObject()->getID();
   3.344 +	LLViewerObject *pObj = gObjectList.findObject( id );
   3.345 +	addObjectToList( pObj, aProps->mName );
   3.346 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/indra/newview/fsfloatervramusage.h	Wed Jan 07 01:34:44 2015 +0100
     4.3 @@ -0,0 +1,61 @@
     4.4 +/**
     4.5 + * $LicenseInfo:firstyear=2015&license=viewerlgpl$
     4.6 + * Phoenix Firestorm Viewer Source Code
     4.7 + * Copyright (c) 2015 Nicky Dasmijn
     4.8 + *
     4.9 + * This library is free software; you can redistribute it and/or
    4.10 + * modify it under the terms of the GNU Lesser General Public
    4.11 + * License as published by the Free Software Foundation;
    4.12 + * version 2.1 of the License only.
    4.13 + *
    4.14 + * This library is distributed in the hope that it will be useful,
    4.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    4.17 + * Lesser General Public License for more details.
    4.18 + *
    4.19 + * You should have received a copy of the GNU Lesser General Public
    4.20 + * License along with this library; if not, write to the Free Software
    4.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    4.22 + * 
    4.23 + * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
    4.24 + * http://www.firestormviewer.org
    4.25 + * $/LicenseInfo$
    4.26 + */
    4.27 +
    4.28 +#ifndef FS_FLOATERVRAMUSAGE_H
    4.29 +#define FS_FLOATERVRAMUSAGE_H
    4.30 +
    4.31 +#include "llfloater.h"
    4.32 +#include "llselectmgr.h"
    4.33 +
    4.34 +class LLScrollListCtrl;
    4.35 +class LLViewerObject;
    4.36 +class LLFace;
    4.37 +class LLVertexBuffer;
    4.38 +
    4.39 +class FSFloaterVRAMUsage : public LLFloater, public nd::selection::PropertiesListener
    4.40 +{
    4.41 +public:
    4.42 +	FSFloaterVRAMUsage(const LLSD& seed);
    4.43 +	/*virtual*/ ~FSFloaterVRAMUsage();
    4.44 +	/*virtual*/ void onOpen(const LLSD& key);
    4.45 +
    4.46 +	BOOL postBuild();
    4.47 +
    4.48 +	virtual void onProperties( LLSelectNode const * );
    4.49 +
    4.50 +	void onIdle();
    4.51 +
    4.52 +private:
    4.53 +	void doRefresh();
    4.54 +
    4.55 +	void addObjectToList( LLViewerObject*, std::string const& );
    4.56 +	void calcFaceSize( LLFace *aFace, S32 &aW, S32 &aH );
    4.57 +	S32 calcVBOEntrySize( LLVertexBuffer *aVBO );
    4.58 +	U32 calcTexturSize( LLViewerObject*, std::ostream * = 0 );
    4.59 +
    4.60 +	struct ImplData;
    4.61 +	ImplData *mData;
    4.62 +};
    4.63 +
    4.64 +#endif // FS_FLOATERBLOCKLIST_H
     5.1 --- a/indra/newview/llface.cpp	Tue Jan 06 20:11:15 2015 +0100
     5.2 +++ b/indra/newview/llface.cpp	Wed Jan 07 01:34:44 2015 +0100
     5.3 @@ -954,6 +954,23 @@
     5.4  void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_pos, F32* scale) const
     5.5  {
     5.6  	const LLMatrix4& vol_mat = getWorldMatrix();
     5.7 +	if( ! getViewerObject() )
     5.8 +	{
     5.9 +		LL_WARNS() << "No viewer object" << LL_ENDL;
    5.10 +		return;
    5.11 +	}
    5.12 +	if( ! getViewerObject()->getVolume() )
    5.13 +	{
    5.14 +		LL_WARNS() << "No volume" << LL_ENDL;
    5.15 +		return;
    5.16 +	}
    5.17 +
    5.18 +	if( getViewerObject()->getVolume()->getNumVolumeFaces() <= mTEOffset )
    5.19 +	{
    5.20 +		LL_WARNS() << "No volume face" << (S32)mTEOffset << LL_ENDL;
    5.21 +		return;
    5.22 +	}
    5.23 +
    5.24  	const LLVolumeFace& vf = getViewerObject()->getVolume()->getVolumeFace(mTEOffset);
    5.25  	const LLVector4a& normal4a = vf.mNormals[0];
    5.26  	const LLVector4a& tangent = vf.mTangents[0];
     6.1 --- a/indra/newview/llselectmgr.cpp	Tue Jan 06 20:11:15 2015 +0100
     6.2 +++ b/indra/newview/llselectmgr.cpp	Wed Jan 07 01:34:44 2015 +0100
     6.3 @@ -490,6 +490,9 @@
     6.4  		object->addThisAndNonJointChildren(objects);
     6.5  		addAsFamily(objects);
     6.6  
     6.7 +		if( isBatchMode() )
     6.8 +			continue;
     6.9 +
    6.10  		// Stop the object from moving (this anticipates changes on the
    6.11  		// simulator in LLTask::userSelect)
    6.12  		object->setVelocity(LLVector3::zero);
    6.13 @@ -498,6 +501,14 @@
    6.14  		object->resetRot();
    6.15  	}
    6.16  
    6.17 +	if( isBatchMode() )
    6.18 +	{
    6.19 +		mShowSelection = FALSE;
    6.20 +		sendSelect();
    6.21 +		return mSelectedObjects;
    6.22 +	}
    6.23 +
    6.24 +
    6.25  	updateSelectionCenter();
    6.26  	saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
    6.27  	updatePointAt();
    6.28 @@ -5343,6 +5354,10 @@
    6.29  			node->mInventorySerial = inv_serial;
    6.30  			node->mSitName.assign(sit_name);
    6.31  			node->mTouchName.assign(touch_name);
    6.32 +
    6.33 +			// <FS:ND> Fire for any observer interested in object properties
    6.34 +			LLSelectMgr::instance().firePropertyReceived( node );
    6.35 +			// </FS:ND>
    6.36  		}
    6.37  	}
    6.38  
     7.1 --- a/indra/newview/llselectmgr.h	Tue Jan 06 20:11:15 2015 +0100
     7.2 +++ b/indra/newview/llselectmgr.h	Wed Jan 07 01:34:44 2015 +0100
     7.3 @@ -234,6 +234,11 @@
     7.4  	LLPointer<LLViewerObject>	mObject;
     7.5  	S32				mTESelectMask;
     7.6  	S32				mLastTESelected;
     7.7 +
     7.8 +// <FS:ND> For const access. Need to check for isDead yourself.
     7.9 +public:
    7.10 +	LLViewerObject const* getObject() const { return mObject; } 
    7.11 +// </FS:ND>
    7.12  };
    7.13  
    7.14  class LLObjectSelection : public LLRefCount
    7.15 @@ -397,7 +402,47 @@
    7.16  // For use with getFirstTest()
    7.17  struct LLSelectGetFirstTest;
    7.18  
    7.19 -class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr>
    7.20 +// <FS:ND> To listened into received prop. messages
    7.21 +namespace nd
    7.22 +{
    7.23 +	namespace selection
    7.24 +	{
    7.25 +		class PropertiesListener
    7.26 +		{
    7.27 +		public:
    7.28 +			virtual void onProperties( LLSelectNode const * ) = 0;
    7.29 +		};
    7.30 +
    7.31 +		class PropertiesServer
    7.32 +		{
    7.33 +		public:
    7.34 +			PropertiesServer()
    7.35 +				: mBatchMode( false )
    7.36 +			{ }
    7.37 +
    7.38 +			void registerPropertyListener( nd::selection::PropertiesListener *aP) { mListener.insert( aP ); }
    7.39 +			void removePropertyListener( nd::selection::PropertiesListener *aP) { mListener.erase( aP ); }
    7.40 +
    7.41 +			void enableBatchMode( ) { mBatchMode = true; }
    7.42 +			void disableBatchMode( ) { mBatchMode = false; }
    7.43 +			bool isBatchMode() const { return mBatchMode; }
    7.44 +
    7.45 +		protected:
    7.46 +			void firePropertyReceived( LLSelectNode const *aNode  )
    7.47 +			{
    7.48 +				for( std::set< nd::selection::PropertiesListener * >::iterator itr = mListener.begin(); itr != mListener.end(); ++itr )
    7.49 +					(*itr)->onProperties( aNode );
    7.50 +			}
    7.51 +
    7.52 +		private:
    7.53 +			std::set< nd::selection::PropertiesListener * > mListener;
    7.54 +			bool mBatchMode;
    7.55 +		};
    7.56 +	}
    7.57 +}
    7.58 +// </FS:ND>
    7.59 +
    7.60 +class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr>, public nd::selection::PropertiesServer
    7.61  {
    7.62  public:
    7.63  	static BOOL					sRectSelectInclusive;	// do we need to surround an object to pick it?
     8.1 --- a/indra/newview/llviewerfloaterreg.cpp	Tue Jan 06 20:11:15 2015 +0100
     8.2 +++ b/indra/newview/llviewerfloaterreg.cpp	Wed Jan 07 01:34:44 2015 +0100
     8.3 @@ -187,6 +187,9 @@
     8.4  #include "NACLfloaterexploresounds.h"
     8.5  #include "particleeditor.h"
     8.6  #include "quickprefs.h"
     8.7 +
     8.8 +#include "fsfloatervramusage.h"
     8.9 +
    8.10  // handle secondlife:///app/openfloater/{NAME} URLs
    8.11  class LLFloaterOpenHandler : public LLCommandHandler
    8.12  {
    8.13 @@ -427,5 +430,7 @@
    8.14  	LLFloaterReg::add("sound_explorer", "floater_NACL_explore_sounds.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<NACLFloaterExploreSounds>);
    8.15  	LLFloaterReg::add("ws_asset_blacklist", "floater_asset_blacklist.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterWSAssetBlacklist>);
    8.16  
    8.17 +	LLFloaterReg::add( "vram_usage", "fs_floater_vram_usage.xml", static_cast<LLFloaterBuildFunc>( &LLFloaterReg::build< FSFloaterVRAMUsage >) );
    8.18 +
    8.19  	LLFloaterReg::registerControlVariables(); // Make sure visibility and rect controls get preserved when saving
    8.20  }
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/indra/newview/skins/default/xui/en/fs_floater_vram_usage.xml	Wed Jan 07 01:34:44 2015 +0100
     9.3 @@ -0,0 +1,73 @@
     9.4 +<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
     9.5 +<floater
     9.6 + positioning="centered"
     9.7 + legacy_header_height="18"
     9.8 + can_resize="true"
     9.9 + default_tab_group="1"
    9.10 + height="350"
    9.11 + layout="topleft"
    9.12 + min_height="160"
    9.13 + min_width="270"
    9.14 + name="object_vram_usage"
    9.15 + help_topic=""
    9.16 + save_rect="true"
    9.17 + title="Object impact on VRAM"
    9.18 + width="400">
    9.19 +    <scroll_list
    9.20 +        name="result_list"
    9.21 +        left="10"
    9.22 +        right="-10"
    9.23 +        top="14"
    9.24 +        bottom="-32"
    9.25 +        follows="left|top|bottom|right"
    9.26 +        can_resize="true"
    9.27 +        column_padding="0"
    9.28 +        draw_heading="true"
    9.29 +        multi_select="false"
    9.30 +        search_column="6">
    9.31 +      <column
    9.32 +          name="uuid"
    9.33 +          label="uuid"
    9.34 +		  width="0"/>
    9.35 +      <column
    9.36 +          name="name"
    9.37 +          label="Name"
    9.38 +          dynamicwidth="true"/>
    9.39 +      <column
    9.40 +          name="distance"
    9.41 +          label="Distance"
    9.42 +          dynamicwidth="true"/>
    9.43 +      <column
    9.44 +          name="faces"
    9.45 +          label="Faces"
    9.46 +          dynamicwidth="true"/>
    9.47 +      <column
    9.48 +          name="vertices"
    9.49 +          label="Vertices"
    9.50 +          dynamicwidth="true"/>
    9.51 +      <column
    9.52 +          name="indices"
    9.53 +          label="Indices"
    9.54 +          dynamicwidth="true"/>
    9.55 +      <column
    9.56 +          name="vram_usage"
    9.57 +          label="VRAM (Textures) in kb"
    9.58 +          dynamicwidth="true"/>
    9.59 +      <column
    9.60 +          name="vram_usage_vbo"
    9.61 +          label="VRAM (VBO) in kb"
    9.62 +          dynamicwidth="true"/>
    9.63 +    </scroll_list>
    9.64 +    <button
    9.65 +     follows="bottom|left"
    9.66 +	 left="10"
    9.67 +	 top="-25"
    9.68 +     height="23"
    9.69 +     label="Refresh"
    9.70 +     label_selected="Refresh"
    9.71 +     layout="topleft"
    9.72 +     left_pad="10"
    9.73 +     name="refresh_button"
    9.74 +     width="120">
    9.75 +    </button>
    9.76 +</floater>
    10.1 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml	Tue Jan 06 20:11:15 2015 +0100
    10.2 +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml	Wed Jan 07 01:34:44 2015 +0100
    10.3 @@ -3287,6 +3287,13 @@
    10.4                   function="ToggleControl"
    10.5                   parameter="DebugShowTextureInfo" />
    10.6              </menu_item_check>
    10.7 +            <menu_item_call
    10.8 +              label="VRAM usage per object"
    10.9 +              name="VRAM usage per object">
   10.10 +              <menu_item_call.on_click
   10.11 +                function="Floater.Show"
   10.12 +                parameter="vram_usage" />
   10.13 +            </menu_item_call>
   10.14              <menu_item_check
   10.15               label="Show Avatar Render Info"
   10.16               name="Show Avatar Render Info">

mercurial