From 74ac0182ec8f7a0f6d0ea89f5814f0998ab90b62 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 10 Oct 2012 19:25:56 -0700 Subject: SH-3405 WIP convert existing stats to lltrace system fixed units conversion so that trace getters return convertable units removed circular dependencies from lltrace* converted more stats to lltrace --- indra/newview/pipeline.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 86791a37fb..4582de805f 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -488,7 +488,7 @@ void LLPipeline::init() getPool(LLDrawPool::POOL_BUMP); getPool(LLDrawPool::POOL_GLOW); - LLViewerStats::getInstance()->mTrianglesDrawnStat.reset(); + //LLViewerStats::getInstance()->mTrianglesDrawnStat.reset(); resetFrameStats(); for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) @@ -1768,7 +1768,8 @@ void LLPipeline::resetFrameStats() { assertInitialized(); - LLViewerStats::getInstance()->mTrianglesDrawnStat.addValue(mTrianglesDrawn/1000.f); + LLStatViewer::TRIANGLES_DRAWN.add(mTrianglesDrawn); + //LLViewerStats::getInstance()->mTrianglesDrawnStat.addValue(mTrianglesDrawn/1000.f); if (mBatchCount > 0) { -- cgit v1.3 From c0ba626c8009b22310b3923e8170e5db2a021253 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Mon, 15 Oct 2012 21:34:29 -0600 Subject: For SH-3333: Design and implement a new object cache system on viewer side --- indra/newview/CMakeLists.txt | 2 + indra/newview/app_settings/settings.xml | 11 + indra/newview/llappviewer.cpp | 2 +- indra/newview/lldrawable.cpp | 349 +++++++------- indra/newview/lldrawable.h | 62 +-- indra/newview/llspatialpartition.cpp | 787 +++++++++++--------------------- indra/newview/llspatialpartition.h | 128 +++--- indra/newview/lltextureview.cpp | 9 +- indra/newview/llviewermessage.cpp | 25 +- indra/newview/llviewerobject.cpp | 105 +++-- indra/newview/llviewerobjectlist.cpp | 145 +++++- indra/newview/llviewerobjectlist.h | 6 +- indra/newview/llvieweroctree.cpp | 704 ++++++++++++++++++++++++++++ indra/newview/llvieweroctree.h | 274 +++++++++++ indra/newview/llviewerpartsim.cpp | 4 +- indra/newview/llviewerregion.cpp | 478 +++++++++++++++++-- indra/newview/llviewerregion.h | 38 +- indra/newview/llviewerstatsrecorder.cpp | 2 +- indra/newview/llvoavatarself.cpp | 6 +- indra/newview/llvocache.cpp | 78 +++- indra/newview/llvocache.h | 36 +- indra/newview/llvograss.cpp | 14 +- indra/newview/llvopartgroup.cpp | 20 +- indra/newview/llvosurfacepatch.cpp | 4 +- indra/newview/llvotree.cpp | 4 +- indra/newview/llvovolume.cpp | 44 +- indra/newview/llvowater.cpp | 6 +- indra/newview/llworld.cpp | 20 +- indra/newview/llworld.h | 3 +- indra/newview/pipeline.cpp | 50 +- 30 files changed, 2429 insertions(+), 987 deletions(-) create mode 100644 indra/newview/llvieweroctree.cpp create mode 100644 indra/newview/llvieweroctree.h (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 04ea646100..c81ade6937 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -583,6 +583,7 @@ set(viewer_SOURCE_FILES llviewernetwork.cpp llviewerobject.cpp llviewerobjectlist.cpp + llvieweroctree.cpp llviewerparcelmedia.cpp llviewerparcelmediaautoplay.cpp llviewerparcelmgr.cpp @@ -1148,6 +1149,7 @@ set(viewer_HEADER_FILES llviewernetwork.h llviewerobject.h llviewerobjectlist.h + llvieweroctree.h llviewerparcelmedia.h llviewerparcelmediaautoplay.h llviewerparcelmgr.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 7497a273ea..13c95c2381 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6400,6 +6400,17 @@ Value 1 + ObjectCacheViewCullingEnabled + + Comment + Enable the object cache view culling. Needs to restart viewer. + Persist + 1 + Type + Boolean + Value + 1 + OpenDebugStatAdvanced Comment diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index a43776912c..bffa1708ec 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3685,7 +3685,7 @@ U32 LLAppViewer::getObjectCacheVersion() { // Viewer object cache version, change if object update // format changes. JC - const U32 INDRA_OBJECT_CACHE_VERSION = 14; + const U32 INDRA_OBJECT_CACHE_VERSION = 15; return INDRA_OBJECT_CACHE_VERSION; } diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 46ec1abec1..e29551e83c 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -49,6 +49,7 @@ #include "llspatialpartition.h" #include "llviewerobjectlist.h" #include "llviewerwindow.h" +#include "llvocache.h" const F32 MIN_INTERPOLATE_DISTANCE_SQUARED = 0.001f * 0.001f; const F32 MAX_INTERPOLATE_DISTANCE_SQUARED = 10.f * 10.f; @@ -75,7 +76,6 @@ extern bool gShiftFrame; // // static -U32 LLDrawable::sCurVisible = 0; U32 LLDrawable::sNumZombieDrawables = 0; F32 LLDrawable::sCurPixelAngle = 0; LLDynamicArrayPtr > LLDrawable::sDeadList; @@ -85,33 +85,59 @@ LLDynamicArrayPtr > LLDrawable::sDeadList; // static void LLDrawable::incrementVisible() { - sCurVisible++; + LLViewerOctreeEntryData::incrementVisible(); sCurPixelAngle = (F32) gViewerWindow->getWindowHeightRaw()/LLViewerCamera::getInstance()->getView(); } -void LLDrawable::init() +LLDrawable::LLDrawable(LLViewerObject *vobj, bool new_entry) + : LLViewerOctreeEntryData(LLViewerOctreeEntry::LLDRAWABLE), + mVObjp(vobj) +{ + init(new_entry); +} + +void LLDrawable::init(bool new_entry) { // mXform mParent = NULL; mRenderType = 0; mCurrentScale = LLVector3(1,1,1); - mDistanceWRTCamera = 0.0f; - mPositionGroup.clear(); - mExtents[0].clear(); - mExtents[1].clear(); - + mDistanceWRTCamera = 0.0f; mState = 0; - mVObjp = NULL; - // mFaces - mSpatialGroupp = NULL; - mVisible = sCurVisible - 2;//invisible for the current frame and the last frame. - mRadius = 0.f; - mGeneration = -1; - mBinRadius = 1.f; - mBinIndex = -1; - + // mFaces + mRadius = 0.f; + mGeneration = -1; mSpatialBridge = NULL; + + LLViewerOctreeEntry* entry = NULL; + LLVOCacheEntry* vo_entry = NULL; + if(!new_entry && mVObjp && getRegion() != NULL) + { + vo_entry = getRegion()->getCacheEntryForOctree(mVObjp->getLocalID()); + if(vo_entry) + { + entry = vo_entry->getEntry(); + } + } + setOctreeEntry(entry); + if(vo_entry) + { + if(!entry) + { + vo_entry->setOctreeEntry(mEntry); + } + else if(vo_entry->getNumOfChildren() > 0) + { + getRegion()->addVisibleCacheEntry(vo_entry); //to load all children. + } + + getRegion()->addActiveCacheEntry(vo_entry); + } + + llassert(!vo_entry || vo_entry->getEntry() == mEntry); + + initVisible(sCurVisible - 2);//invisible for the current frame and the last frame. } // static @@ -155,6 +181,7 @@ void LLDrawable::markDead() llwarns << "Warning! Marking dead multiple times!" << llendl; return; } + setState(DEAD); if (mSpatialBridge) { @@ -164,8 +191,7 @@ void LLDrawable::markDead() sNumZombieDrawables++; - // We're dead. Free up all of our references to other objects - setState(DEAD); + // We're dead. Free up all of our references to other objects cleanupReferences(); // sDeadList.put(this); } @@ -219,6 +245,8 @@ void LLDrawable::cleanupReferences() gPipeline.unlinkDrawable(this); + removeFromOctree(); + { LLFastTimer t(FTM_DEREF_DRAWABLE); // Cleanup references to other objects @@ -227,6 +255,21 @@ void LLDrawable::cleanupReferences() } } +void LLDrawable::removeFromOctree() +{ + if(!mEntry) + { + return; + } + + mEntry->removeData(this); + if(mEntry->hasVOCacheEntry()) + { + getRegion()->removeActiveCacheEntry((LLVOCacheEntry*)mEntry->getVOCacheEntry(), this); + } + mEntry = NULL; +} + void LLDrawable::cleanupDeadDrawables() { /* @@ -715,7 +758,7 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update) LLVOVolume* volume = getVOVolume(); if (volume) { - if (getSpatialGroup()) + if (getGroup()) { pos.set(getPositionGroup().getF32ptr()); } @@ -833,9 +876,7 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector) } } - mExtents[0].add(shift_vector); - mExtents[1].add(shift_vector); - mPositionGroup.add(shift_vector); + shift(shift_vector); } else if (mSpatialBridge) { @@ -843,9 +884,7 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector) } else if (isAvatar()) { - mExtents[0].add(shift_vector); - mExtents[1].add(shift_vector); - mPositionGroup.add(shift_vector); + shift(shift_vector); } mVObjp->onShift(shift_vector); @@ -857,40 +896,24 @@ const LLVector3& LLDrawable::getBounds(LLVector3& min, LLVector3& max) const return mXform.getPositionW(); } -const LLVector4a* LLDrawable::getSpatialExtents() const -{ - return mExtents; -} - -void LLDrawable::setSpatialExtents(const LLVector3& min, const LLVector3& max) -{ - mExtents[0].load3(min.mV); - mExtents[1].load3(max.mV); -} - -void LLDrawable::setSpatialExtents(const LLVector4a& min, const LLVector4a& max) -{ - mExtents[0] = min; - mExtents[1] = max; -} - -void LLDrawable::setPositionGroup(const LLVector4a& pos) -{ - mPositionGroup = pos; -} - void LLDrawable::updateSpatialExtents() { if (mVObjp) { - mVObjp->updateSpatialExtents(mExtents[0], mExtents[1]); + const LLVector4a* exts = getSpatialExtents(); + LLVector4a extents[2]; + extents[0] = exts[0]; + extents[1] = exts[1]; + + mVObjp->updateSpatialExtents(extents[0], extents[1]); + setSpatialExtents(extents[0], extents[1]); } updateBinRadius(); if (mSpatialBridge.notNull()) { - mPositionGroup.splat(0.f); + getGroupPosition().splat(0.f); } } @@ -899,11 +922,11 @@ void LLDrawable::updateBinRadius() { if (mVObjp.notNull()) { - mBinRadius = llmin(mVObjp->getBinRadius(), 256.f); + setBinRadius(llmin(mVObjp->getBinRadius(), 256.f)); } else { - mBinRadius = llmin(getRadius()*4.f, 256.f); + setBinRadius(llmin(getRadius()*4.f, 256.f)); } } @@ -937,20 +960,48 @@ void LLDrawable::updateUVMinMax() { } -LLSpatialGroup* LLDrawable::getSpatialGroup() const -{ - llassert((mSpatialGroupp == NULL) ? getBinIndex() == -1 : getBinIndex() != -1); - return mSpatialGroupp; +//virtual +bool LLDrawable::isVisible() const +{ + if (LLViewerOctreeEntryData::isVisible()) + { + return true; + } + + { + LLviewerOctreeGroup* group = mEntry->getGroup(); + if (group && group->isVisible()) + { + LLViewerOctreeEntryData::setVisible(); + return true; + } + } + + return false; } -void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp) +//virtual +bool LLDrawable::isRecentlyVisible() const { -/*if (mSpatialGroupp && (groupp != mSpatialGroupp)) + //currently visible or visible in the previous frame. + bool vis = LLViewerOctreeEntryData::isRecentlyVisible(); + + if(!vis) { - mSpatialGroupp->setState(LLSpatialGroup::GEOM_DIRTY); - }*/ + LLviewerOctreeGroup* group = getGroup(); + if (group && group->isRecentlyVisible()) + { + LLViewerOctreeEntryData::setVisible(); + vis = TRUE ; + } + } + + return vis ; +} - if (mSpatialGroupp != groupp && getVOVolume()) +void LLDrawable::setGroup(LLviewerOctreeGroup *groupp) +{ + if (getGroup() != groupp && getVOVolume()) { //NULL out vertex buffer references for volumes on spatial group change to maintain //requirement that every face vertex buffer is either NULL or points to a vertex buffer //contained by its drawable's spatial group @@ -964,9 +1015,7 @@ void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp) } } - mSpatialGroupp = groupp; - - llassert((mSpatialGroupp == NULL) ? getBinIndex() == -1 : getBinIndex() != -1); + LLViewerOctreeEntryData::setGroup(groupp); } LLSpatialPartition* LLDrawable::getSpatialPartition() @@ -985,11 +1034,11 @@ LLSpatialPartition* LLDrawable::getSpatialPartition() { if (mVObjp->isHUDAttachment()) { - setSpatialBridge(new LLHUDBridge(this)); + setSpatialBridge(new LLHUDBridge(this, getRegion())); } else { - setSpatialBridge(new LLVolumeBridge(this)); + setSpatialBridge(new LLVolumeBridge(this, getRegion())); } } return mSpatialBridge->asPartition(); @@ -1008,89 +1057,26 @@ LLSpatialPartition* LLDrawable::getSpatialPartition() return retval; } -const S32 MIN_VIS_FRAME_RANGE = 2 ; //two frames:the current one and the last one. -//static -S32 LLDrawable::getMinVisFrameRange() +//virtual +S32 LLDrawable::getMinVisFrameRange() const { - return MIN_VIS_FRAME_RANGE ; -} - -BOOL LLDrawable::isRecentlyVisible() const -{ - //currently visible or visible in the previous frame. - BOOL vis = isVisible() || (sCurVisible - mVisible < MIN_VIS_FRAME_RANGE) ; - - if(!vis) - { - LLSpatialGroup* group = getSpatialGroup(); - if (group && group->isRecentlyVisible()) - { - mVisible = sCurVisible; - vis = TRUE ; - } - } - - return vis ; -} - -BOOL LLDrawable::isVisible() const -{ - if (mVisible == sCurVisible) - { - return TRUE; - } - -#if 0 - //disabling this code fixes DEV-20105. Leaving in place in case some other bug pops up as a a result. - //should be safe to just always ask the spatial group for visibility. - if (isActive()) - { - if (isRoot()) - { - LLSpatialGroup* group = mSpatialBridge.notNull() ? mSpatialBridge->getSpatialGroup() : - getSpatialGroup(); - if (group && group->isVisible()) - { - mVisible = sCurVisible; - return TRUE; - } - } - else - { - if (getParent()->isVisible()) - { - mVisible = sCurVisible; - return TRUE; - } - } - } - else -#endif - { - LLSpatialGroup* group = getSpatialGroup(); - if (group && group->isVisible()) - { - mVisible = sCurVisible; - return TRUE; - } - } + const S32 MIN_VIS_FRAME_RANGE = 2 ; //two frames:the current one and the last one. - return FALSE; + return MIN_VIS_FRAME_RANGE ; } //======================================= // Spatial Partition Bridging Drawable //======================================= -LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask) -: LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB) +LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask, LLViewerRegion* regionp) : + LLDrawable(root->getVObj(), true), + LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB, regionp) { mBridge = this; mDrawable = root; root->setSpatialBridge(this); - mBinIndex = -1; - mRenderType = mDrawable->mRenderType; mDrawableType = mDrawable->mRenderType; @@ -1111,10 +1097,13 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 dat LLSpatialBridge::~LLSpatialBridge() { - LLSpatialGroup* group = getSpatialGroup(); - if (group) + if(mEntry) { - group->mSpatialPartition->remove(this, group); + LLSpatialGroup* group = getSpatialGroup(); + if (group) + { + group->mSpatialPartition->remove(this, group); + } } //delete octree here so listeners will still be able to access bridge specific state @@ -1136,8 +1125,9 @@ void LLSpatialBridge::updateSpatialExtents() root->rebound(); } + const LLVector4a* root_bounds = root->getBounds(); LLVector4a offset; - LLVector4a size = root->mBounds[1]; + LLVector4a size = root_bounds[1]; //VECTORIZE THIS LLMatrix4a mat; @@ -1149,7 +1139,7 @@ void LLSpatialBridge::updateSpatialExtents() LLVector4a center; mat.affineTransform(t, center); - mat.rotate(root->mBounds[0], offset); + mat.rotate(root_bounds[0], offset); center.add(offset); LLVector4a v[4]; @@ -1171,12 +1161,9 @@ void LLSpatialBridge::updateSpatialExtents() scale.mul(size); mat.rotate(scale, v[3]); - - LLVector4a& newMin = mExtents[0]; - LLVector4a& newMax = mExtents[1]; - - newMin = newMax = center; - + LLVector4a newMin; + LLVector4a newMax; + newMin = newMax = center; for (U32 i = 0; i < 4; i++) { LLVector4a delta; @@ -1189,19 +1176,21 @@ void LLSpatialBridge::updateSpatialExtents() newMin.setMin(newMin, min); newMax.setMax(newMax, max); } - + setSpatialExtents(newMin, newMax); + LLVector4a diagonal; diagonal.setSub(newMax, newMin); mRadius = diagonal.getLength3().getF32() * 0.5f; - mPositionGroup.setAdd(newMin,newMax); - mPositionGroup.mul(0.5f); + LLVector4a& pos = getGroupPosition(); + pos.setAdd(newMin,newMax); + pos.mul(0.5f); updateBinRadius(); } void LLSpatialBridge::updateBinRadius() { - mBinRadius = llmin( mOctree->getSize()[0]*0.5f, 256.f); + setBinRadius(llmin( mOctree->getSize()[0]*0.5f, 256.f)); } LLCamera LLSpatialBridge::transformCamera(LLCamera& camera) @@ -1236,7 +1225,7 @@ LLCamera LLSpatialBridge::transformCamera(LLCamera& camera) void LLDrawable::setVisible(LLCamera& camera, std::vector* results, BOOL for_select) { - mVisible = sCurVisible; + LLViewerOctreeEntryData::setVisible(); #if 0 && !LL_RELEASE_FOR_DOWNLOAD //crazy paranoid rules checking @@ -1271,21 +1260,21 @@ void LLDrawable::setVisible(LLCamera& camera, std::vector* results, #endif } -class LLOctreeMarkNotCulled: public LLOctreeTraveler +class LLOctreeMarkNotCulled: public OctreeTraveler { public: LLCamera* mCamera; LLOctreeMarkNotCulled(LLCamera* camera_in) : mCamera(camera_in) { } - virtual void traverse(const LLOctreeNode* node) + virtual void traverse(const OctreeNode* node) { LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); group->setVisible(); - LLOctreeTraveler::traverse(node); + OctreeTraveler::traverse(node); } - void visit(const LLOctreeNode* branch) + void visit(const OctreeNode* branch) { gPipeline.markNotCulled((LLSpatialGroup*) branch->getListener(0), *mCamera); } @@ -1329,7 +1318,7 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector* } if (!group || - LLDrawable::getCurrentFrame() - av->mVisible > 1 || + LLDrawable::getCurrentFrame() - av->getVisible() > 1 || impostor || !loaded) { @@ -1343,16 +1332,17 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector* group->rebound(); LLVector4a center; - center.setAdd(mExtents[0], mExtents[1]); + const LLVector4a* exts = getSpatialExtents(); + center.setAdd(exts[0], exts[1]); center.mul(0.5f); LLVector4a size; - size.setSub(mExtents[1], mExtents[0]); + size.setSub(exts[1], exts[0]); size.mul(0.5f); if ((LLPipeline::sShadowRender && camera_in.AABBInFrustum(center, size)) || LLPipeline::sImpostorRender || (camera_in.AABBInFrustumNoFarClip(center, size) && - AABBSphereIntersect(mExtents[0], mExtents[1], camera_in.getOrigin(), camera_in.mFrustumCornerDist))) + AABBSphereIntersect(exts[0], exts[1], camera_in.getOrigin(), camera_in.mFrustumCornerDist))) { if (!LLPipeline::sImpostorRender && !LLPipeline::sShadowRender && @@ -1467,22 +1457,28 @@ BOOL LLSpatialBridge::updateMove() void LLSpatialBridge::shiftPos(const LLVector4a& vec) { - mExtents[0].add(vec); - mExtents[1].add(vec); - mPositionGroup.add(vec); + LLDrawable::shift(vec); } void LLSpatialBridge::cleanupReferences() { + LLPointer dummy_entry; + if (mDrawable && mDrawable->isDead() && mDrawable->getEntry()->hasVOCacheEntry()) + { + //create a dummy entry to insert the entire LLSpatialBridge to the vo_cache partition so it can be reloaded. + + dummy_entry = new LLVOCacheEntry(); + dummy_entry->setOctreeEntry(mEntry); + dummy_entry->addChild((LLVOCacheEntry*)mDrawable->getEntry()->getVOCacheEntry()); + llassert(!mDrawable->getParent()); + + mDrawable->mParent = this; + } + LLDrawable::cleanupReferences(); if (mDrawable) { - LLSpatialGroup* group = mDrawable->getSpatialGroup(); - if (group) - { - group->mOctreeNode->remove(mDrawable); - mDrawable->setSpatialGroup(NULL); - } + mDrawable->setGroup(NULL); if (mDrawable->getVObj()) { @@ -1494,12 +1490,7 @@ void LLSpatialBridge::cleanupReferences() LLDrawable* drawable = child->mDrawable; if (drawable) { - LLSpatialGroup* group = drawable->getSpatialGroup(); - if (group) - { - group->mOctreeNode->remove(drawable); - drawable->setSpatialGroup(NULL); - } + drawable->setGroup(NULL); } } } @@ -1571,8 +1562,8 @@ void LLDrawable::updateFaceSize(S32 idx) } } -LLBridgePartition::LLBridgePartition() -: LLSpatialPartition(0, FALSE, 0) +LLBridgePartition::LLBridgePartition(LLViewerRegion* regionp) +: LLSpatialPartition(0, FALSE, 0, regionp) { mDrawableType = LLPipeline::RENDER_TYPE_AVATAR; mPartitionType = LLViewerRegion::PARTITION_BRIDGE; @@ -1580,8 +1571,8 @@ LLBridgePartition::LLBridgePartition() mSlopRatio = 0.25f; } -LLHUDBridge::LLHUDBridge(LLDrawable* drawablep) -: LLVolumeBridge(drawablep) +LLHUDBridge::LLHUDBridge(LLDrawable* drawablep, LLViewerRegion* regionp) +: LLVolumeBridge(drawablep, regionp) { mDrawableType = LLPipeline::RENDER_TYPE_HUD; mPartitionType = LLViewerRegion::PARTITION_HUD; diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 4608d16fec..8e193a02bd 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -42,6 +42,7 @@ #include "llviewerobject.h" #include "llrect.h" #include "llappviewer.h" // for gFrameTimeSeconds +#include "llvieweroctree.h" class LLCamera; class LLDrawPool; @@ -59,10 +60,10 @@ const U32 SILHOUETTE_HIGHLIGHT = 0; // All data for new renderer goes into this class. LL_ALIGN_PREFIX(16) -class LLDrawable : public LLRefCount +class LLDrawable : public LLViewerOctreeEntryData { public: - LLDrawable(const LLDrawable& rhs) + LLDrawable(const LLDrawable& rhs) : LLViewerOctreeEntryData(rhs) { *this = rhs; } @@ -85,19 +86,17 @@ public: ll_aligned_free_16(ptr); } - LLDrawable() { init(); } + LLDrawable(LLViewerObject *vobj, bool new_entry = false); void markDead(); // Mark this drawable as dead BOOL isDead() const { return isState(DEAD); } BOOL isNew() const { return !isState(BUILT); } BOOL isLight() const; - - BOOL isVisible() const; - BOOL isRecentlyVisible() const; + virtual void setVisible(LLCamera& camera_in, std::vector* results = NULL, BOOL for_select = FALSE); - + LLSpatialGroup* getSpatialGroup()const {return (LLSpatialGroup*)getGroup();} LLViewerRegion* getRegion() const { return mVObjp->getRegion(); } const LLTextureEntry* getTextureEntry(U8 which) const { return mVObjp->getTE(which); } LLPointer& getVObj() { return mVObjp; } @@ -110,17 +109,13 @@ public: const LLVector3& getPosition() const { return mXform.getPosition(); } const LLVector3& getWorldPosition() const { return mXform.getPositionW(); } const LLVector3 getPositionAgent() const; - const LLVector4a& getPositionGroup() const { return mPositionGroup; } const LLVector3& getScale() const { return mCurrentScale; } void setScale(const LLVector3& scale) { mCurrentScale = scale; } const LLQuaternion& getWorldRotation() const { return mXform.getWorldRotation(); } const LLQuaternion& getRotation() const { return mXform.getRotation(); } F32 getIntensity() const { return llmin(mXform.getScale().mV[0], 4.f); } S32 getLOD() const { return mVObjp ? mVObjp->getLOD() : 1; } - F32 getBinRadius() const { return mBinRadius; } - S32 getBinIndex() const { return mBinIndex; } - void setBinIndex(S32 index) const { mBinIndex = index; } - + void getMinMax(LLVector3& min,LLVector3& max) const { mXform.getMinMax(min,max); } LLXformMatrix* getXform() { return &mXform; } @@ -150,7 +145,7 @@ public: void setNumFacesFast(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep); void mergeFaces(LLDrawable* src); - void init(); + void init(bool new_entry); void destroy(); void update(); @@ -181,8 +176,12 @@ public: BOOL getLit() const { return isState(UNLIT) ? FALSE : TRUE; } void setLit(BOOL lit) { lit ? clearState(UNLIT) : setState(UNLIT); } + bool isVisible() const; + bool isRecentlyVisible() const; + virtual void cleanupReferences(); + void setGroup(LLviewerOctreeGroup* group); void setRadius(const F32 radius); F32 getRadius() const { return mRadius; } F32 getVisibilityRadius() const; @@ -192,11 +191,6 @@ public: const LLVector3& getBounds(LLVector3& min, LLVector3& max) const; virtual void updateSpatialExtents(); virtual void updateBinRadius(); - const LLVector4a* getSpatialExtents() const; - void setSpatialExtents(const LLVector3& min, const LLVector3& max); - void setSpatialExtents(const LLVector4a& min, const LLVector4a& max); - - void setPositionGroup(const LLVector4a& pos); void setRenderType(S32 type) { mRenderType = type; } BOOL isRenderType(S32 type) { return mRenderType == type; } @@ -205,10 +199,14 @@ public: // Debugging methods S32 findReferences(LLDrawable *drawablep); // Not const because of @#$! iterators... - void setSpatialGroup(LLSpatialGroup *groupp); - LLSpatialGroup *getSpatialGroup() const; LLSpatialPartition* getSpatialPartition(); + virtual S32 getMinVisFrameRange()const; + void removeFromOctree(); + + void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; } + LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; } + // Statics static void incrementVisible(); static void cleanupDeadDrawables(); @@ -292,10 +290,6 @@ public: ANIMATED_CHILD = 0x20000000, ACTIVE_CHILD = 0x40000000, } EDrawableFlags; - -private: //aligned members - LL_ALIGN_16(LLVector4a mExtents[2]); - LL_ALIGN_16(LLVector4a mPositionGroup); public: LLXformMatrix mXform; @@ -303,35 +297,23 @@ public: // vis data LLPointer mParent; - F32 mDistanceWRTCamera; - - static S32 getCurrentFrame() { return sCurVisible; } - static S32 getMinVisFrameRange(); - - void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; } - LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; } + F32 mDistanceWRTCamera; static F32 sCurPixelAngle; //current pixels per radian private: typedef std::vector face_list_t; - U32 mState; + U32 mState; S32 mRenderType; LLPointer mVObjp; face_list_t mFaces; - LLSpatialGroup* mSpatialGroupp; LLPointer mSpatialBridge; - - mutable U32 mVisible; + F32 mRadius; - F32 mBinRadius; - mutable S32 mBinIndex; S32 mGeneration; - LLVector3 mCurrentScale; - - static U32 sCurVisible; // Counter for what value of mVisible means currently visible + LLVector3 mCurrentScale; static U32 sNumZombieDrawables; static LLDynamicArrayPtr > sDeadList; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 5083478392..debb790c58 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -138,94 +138,6 @@ void sg_assert(BOOL expr) #endif } -S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad) -{ - return AABBSphereIntersectR2(min, max, origin, rad*rad); -} - -S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &r) -{ - F32 d = 0.f; - F32 t; - - if ((min-origin).magVecSquared() < r && - (max-origin).magVecSquared() < r) - { - return 2; - } - - for (U32 i = 0; i < 3; i++) - { - if (origin.mV[i] < min.mV[i]) - { - t = min.mV[i] - origin.mV[i]; - d += t*t; - } - else if (origin.mV[i] > max.mV[i]) - { - t = origin.mV[i] - max.mV[i]; - d += t*t; - } - - if (d > r) - { - return 0; - } - } - - return 1; -} - - -S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad) -{ - return AABBSphereIntersectR2(min, max, origin, rad*rad); -} - -S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &r) -{ - F32 d = 0.f; - F32 t; - - LLVector4a origina; - origina.load3(origin.mV); - - LLVector4a v; - v.setSub(min, origina); - - if (v.dot3(v) < r) - { - v.setSub(max, origina); - if (v.dot3(v) < r) - { - return 2; - } - } - - - for (U32 i = 0; i < 3; i++) - { - if (origin.mV[i] < min[i]) - { - t = min[i] - origin.mV[i]; - d += t*t; - } - else if (origin.mV[i] > max[i]) - { - t = origin.mV[i] - max[i]; - d += t*t; - } - - if (d > r) - { - return 0; - } - } - - return 1; -} - - typedef enum { b000 = 0x00, @@ -352,13 +264,17 @@ LLSpatialGroup::~LLSpatialGroup() { llerrs << "Illegal deletion of LLSpatialGroup!" << llendl; }*/ + if(isVisible()) + { + mSpatialPartition->mRegionp->clearVisibleGroup(this); + } if (gDebugGL) { gPipeline.checkReferences(this); } - if (isState(DEAD)) + if (hasState(DEAD)) { sZombieGroups--; } @@ -514,7 +430,8 @@ BOOL LLSpatialGroup::isHUDGroup() BOOL LLSpatialGroup::isRecentlyVisible() const { - return (LLDrawable::getCurrentFrame() - mVisible[LLViewerCamera::sCurCameraID]) < LLDrawable::getMinVisFrameRange() ; + const S32 MIN_VIS_FRAME_RANGE = 2; + return (LLDrawable::getCurrentFrame() - mVisible[LLViewerCamera::sCurCameraID]) < MIN_VIS_FRAME_RANGE ; } BOOL LLSpatialGroup::isVisible() const @@ -619,7 +536,7 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) OctreeNode* parent = mOctreeNode->getOctParent(); if (mOctreeNode->isInside(drawablep->getPositionGroup()) && - (mOctreeNode->contains(drawablep) || + (mOctreeNode->contains(drawablep->getEntry()) || (drawablep->getBinRadius() > mOctreeNode->getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity))) { @@ -633,15 +550,14 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) } -BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_octree) +BOOL LLSpatialGroup::addObject(LLDrawable *drawablep) { - if (!from_octree) + if(!drawablep) { - mOctreeNode->insert(drawablep); + return FALSE; } - else { - drawablep->setSpatialGroup(this); + drawablep->setGroup(this); setState(OBJECT_DIRTY | GEOM_DIRTY); setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS); gPipeline.markRebuild(this, TRUE); @@ -664,7 +580,7 @@ void LLSpatialGroup::rebuildGeom() { mSpatialPartition->rebuildGeom(this); - if (isState(LLSpatialGroup::MESH_DIRTY)) + if (hasState(LLSpatialGroup::MESH_DIRTY)) { gPipeline.markMeshDirty(this); } @@ -686,7 +602,7 @@ static LLFastTimer::DeclareTimer FTM_GET_GEOMETRY("Get Geometry"); void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) { - if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY)) + if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY)) { return; } @@ -751,103 +667,6 @@ void LLSpatialPartition::rebuildMesh(LLSpatialGroup* group) } -BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut) -{ - const OctreeNode* node = mOctreeNode; - - if (node->isEmpty()) - { //don't do anything if there are no objects - if (empty && mOctreeNode->getParent()) - { //only root is allowed to be empty - OCT_ERRS << "Empty leaf found in octree." << llendl; - } - return FALSE; - } - - LLVector4a& newMin = mObjectExtents[0]; - LLVector4a& newMax = mObjectExtents[1]; - - if (isState(OBJECT_DIRTY)) - { //calculate new bounding box - clearState(OBJECT_DIRTY); - - //initialize bounding box to first element - OctreeNode::const_element_iter i = node->getDataBegin(); - LLDrawable* drawablep = *i; - const LLVector4a* minMax = drawablep->getSpatialExtents(); - - newMin = minMax[0]; - newMax = minMax[1]; - - for (++i; i != node->getDataEnd(); ++i) - { - drawablep = *i; - minMax = drawablep->getSpatialExtents(); - - update_min_max(newMin, newMax, minMax[0]); - update_min_max(newMin, newMax, minMax[1]); - - //bin up the object - /*for (U32 i = 0; i < 3; i++) - { - if (minMax[0].mV[i] < newMin.mV[i]) - { - newMin.mV[i] = minMax[0].mV[i]; - } - if (minMax[1].mV[i] > newMax.mV[i]) - { - newMax.mV[i] = minMax[1].mV[i]; - } - }*/ - } - - mObjectBounds[0].setAdd(newMin, newMax); - mObjectBounds[0].mul(0.5f); - mObjectBounds[1].setSub(newMax, newMin); - mObjectBounds[1].mul(0.5f); - } - - if (empty) - { - minOut = newMin; - maxOut = newMax; - } - else - { - minOut.setMin(minOut, newMin); - maxOut.setMax(maxOut, newMax); - } - - return TRUE; -} - -void LLSpatialGroup::unbound() -{ - if (isState(DIRTY)) - { - return; - } - - setState(DIRTY); - - //all the parent nodes need to rebound this child - if (mOctreeNode) - { - OctreeNode* parent = (OctreeNode*) mOctreeNode->getParent(); - while (parent != NULL) - { - LLSpatialGroup* group = (LLSpatialGroup*) parent->getListener(0); - if (group->isState(DIRTY)) - { - return; - } - - group->setState(DIRTY); - parent = (OctreeNode*) parent->getParent(); - } - } -} - LLSpatialGroup* LLSpatialGroup::getParent() { if (isDead()) @@ -871,17 +690,19 @@ LLSpatialGroup* LLSpatialGroup::getParent() BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) { + if(!drawablep) + { + return FALSE; + } + unbound(); if (mOctreeNode && !from_octree) { - if (!mOctreeNode->remove(drawablep)) - { - OCT_ERRS << "Could not remove drawable from spatial group" << llendl; - } + drawablep->setGroup(NULL); } else { - drawablep->setSpatialGroup(NULL); + drawablep->setGroup(NULL); setState(GEOM_DIRTY); gPipeline.markRebuild(this, TRUE); @@ -928,12 +749,12 @@ void LLSpatialGroup::shift(const LLVector4a &offset) } } -class LLSpatialSetState : public LLSpatialGroup::OctreeTraveler +class LLSpatialSetState : public OctreeTraveler { public: U32 mState; LLSpatialSetState(U32 state) : mState(state) { } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setState(mState); } + virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setState(mState); } }; class LLSpatialSetStateDiff : public LLSpatialSetState @@ -941,24 +762,17 @@ class LLSpatialSetStateDiff : public LLSpatialSetState public: LLSpatialSetStateDiff(U32 state) : LLSpatialSetState(state) { } - virtual void traverse(const LLSpatialGroup::OctreeNode* n) + virtual void traverse(const OctreeNode* n) { LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - if (!group->isState(mState)) + if (!group->hasState(mState)) { - LLSpatialGroup::OctreeTraveler::traverse(n); + OctreeTraveler::traverse(n); } } }; -void LLSpatialGroup::setState(U32 state) -{ - mState |= state; - - llassert(state <= LLSpatialGroup::STATE_MASK); -} - void LLSpatialGroup::setState(U32 state, S32 mode) { llassert(state <= LLSpatialGroup::STATE_MASK); @@ -982,12 +796,12 @@ void LLSpatialGroup::setState(U32 state, S32 mode) } } -class LLSpatialClearState : public LLSpatialGroup::OctreeTraveler +class LLSpatialClearState : public OctreeTraveler { public: U32 mState; LLSpatialClearState(U32 state) : mState(state) { } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearState(mState); } + virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearState(mState); } }; class LLSpatialClearStateDiff : public LLSpatialClearState @@ -995,24 +809,17 @@ class LLSpatialClearStateDiff : public LLSpatialClearState public: LLSpatialClearStateDiff(U32 state) : LLSpatialClearState(state) { } - virtual void traverse(const LLSpatialGroup::OctreeNode* n) + virtual void traverse(const OctreeNode* n) { LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - if (group->isState(mState)) + if (group->hasState(mState)) { - LLSpatialGroup::OctreeTraveler::traverse(n); + OctreeTraveler::traverse(n); } } }; -void LLSpatialGroup::clearState(U32 state) -{ - llassert(state <= LLSpatialGroup::STATE_MASK); - - mState &= ~state; -} - void LLSpatialGroup::clearState(U32 state, S32 mode) { llassert(state <= LLSpatialGroup::STATE_MASK); @@ -1036,22 +843,15 @@ void LLSpatialGroup::clearState(U32 state, S32 mode) } } -BOOL LLSpatialGroup::isState(U32 state) const -{ - llassert(state <= LLSpatialGroup::STATE_MASK); - - return mState & state ? TRUE : FALSE; -} - //===================================== // Occlusion State Set/Clear //===================================== -class LLSpatialSetOcclusionState : public LLSpatialGroup::OctreeTraveler +class LLSpatialSetOcclusionState : public OctreeTraveler { public: U32 mState; LLSpatialSetOcclusionState(U32 state) : mState(state) { } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setOcclusionState(mState); } + virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setOcclusionState(mState); } }; class LLSpatialSetOcclusionStateDiff : public LLSpatialSetOcclusionState @@ -1059,13 +859,13 @@ class LLSpatialSetOcclusionStateDiff : public LLSpatialSetOcclusionState public: LLSpatialSetOcclusionStateDiff(U32 state) : LLSpatialSetOcclusionState(state) { } - virtual void traverse(const LLSpatialGroup::OctreeNode* n) + virtual void traverse(const OctreeNode* n) { LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); if (!group->isOcclusionState(mState)) { - LLSpatialGroup::OctreeTraveler::traverse(n); + OctreeTraveler::traverse(n); } } }; @@ -1110,13 +910,13 @@ void LLSpatialGroup::setOcclusionState(U32 state, S32 mode) } } -class LLSpatialClearOcclusionState : public LLSpatialGroup::OctreeTraveler +class LLSpatialClearOcclusionState : public OctreeTraveler { public: U32 mState; LLSpatialClearOcclusionState(U32 state) : mState(state) { } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearOcclusionState(mState); } + virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearOcclusionState(mState); } }; class LLSpatialClearOcclusionStateDiff : public LLSpatialClearOcclusionState @@ -1124,13 +924,13 @@ class LLSpatialClearOcclusionStateDiff : public LLSpatialClearOcclusionState public: LLSpatialClearOcclusionStateDiff(U32 state) : LLSpatialClearOcclusionState(state) { } - virtual void traverse(const LLSpatialGroup::OctreeNode* n) + virtual void traverse(const OctreeNode* n) { LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); if (group->isOcclusionState(mState)) { - LLSpatialGroup::OctreeTraveler::traverse(n); + OctreeTraveler::traverse(n); } } }; @@ -1166,13 +966,11 @@ void LLSpatialGroup::clearOcclusionState(U32 state, S32 mode) // Octree Listener Implementation //====================================== -LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : +LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLviewerOctreeGroup(node), mObjectBoxSize(1.f), - mState(0), mGeometryBytes(0), mSurfaceArea(0.f), mBuilt(0.f), - mOctreeNode(node), mSpatialPartition(part), mVertexBuffer(NULL), mBufferUsage(part->mBufferUsage), @@ -1191,17 +989,11 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : mViewAngle.splat(0.f); mLastUpdateViewAngle.splat(-1.f); - mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[0] = mObjectBounds[1] = - mObjectExtents[0] = mObjectExtents[1] = mViewAngle; - + sg_assert(mOctreeNode->getListenerCount() == 0); - mOctreeNode->addListener(this); setState(SG_INITIAL_STATE_MASK); gPipeline.markRebuild(this, TRUE); - mBounds[0] = node->getCenter(); - mBounds[1] = node->getSize(); - part->mLODSeed = (part->mLODSeed+1)%part->mLODPeriod; mLODHash = part->mLODSeed; @@ -1235,7 +1027,7 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) } #if !LL_RELEASE_FOR_DOWNLOAD - if (isState(LLSpatialGroup::OBJECT_DIRTY)) + if (hasState(LLSpatialGroup::OBJECT_DIRTY)) { llerrs << "Spatial group dirty on distance update." << llendl; } @@ -1266,7 +1058,7 @@ F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) dist = eye.getLength3().getF32(); eye.normalize3fast(); - if (!group->isState(LLSpatialGroup::ALPHA_DIRTY)) + if (!group->hasState(LLSpatialGroup::ALPHA_DIRTY)) { if (!group->mSpatialPartition->isBridge()) { @@ -1343,7 +1135,7 @@ BOOL LLSpatialGroup::needsUpdate() BOOL LLSpatialGroup::changeLOD() { - if (isState(ALPHA_DIRTY | OBJECT_DIRTY)) + if (hasState(ALPHA_DIRTY | OBJECT_DIRTY)) { ///a rebuild is going to happen, update distance and LoD return TRUE; } @@ -1371,29 +1163,51 @@ BOOL LLSpatialGroup::changeLOD() return FALSE; } -void LLSpatialGroup::handleInsertion(const TreeNode* node, LLDrawable* drawablep) +void LLSpatialGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry* entry) { - addObject(drawablep, FALSE, TRUE); + if(mSpatialPartition->isVOCachePartition()) + { + LLviewerOctreeGroup::handleInsertion(node, entry); + return; + } + + addObject((LLDrawable*)entry->getDrawable()); unbound(); setState(OBJECT_DIRTY); } -void LLSpatialGroup::handleRemoval(const TreeNode* node, LLDrawable* drawable) +void LLSpatialGroup::handleRemoval(const TreeNode* node, LLViewerOctreeEntry* entry) { - removeObject(drawable, TRUE); - setState(OBJECT_DIRTY); + if(!mSpatialPartition->isVOCachePartition()) + { + removeObject((LLDrawable*)entry->getDrawable(), TRUE); + } + LLviewerOctreeGroup::handleRemoval(node, entry); } void LLSpatialGroup::handleDestruction(const TreeNode* node) { setState(DEAD); - + + if(mSpatialPartition->isVOCachePartition()) + { + LLviewerOctreeGroup::handleDestruction(node); + return; + } + for (element_iter i = getDataBegin(); i != getDataEnd(); ++i) { - LLDrawable* drawable = *i; - if (drawable->getSpatialGroup() == this) + LLViewerOctreeEntry* entry = *i; + if (entry->getGroup() == this) { - drawable->setSpatialGroup(NULL); + if(entry->hasDrawable()) + { + ((LLDrawable*)entry->getDrawable())->setGroup(NULL); + } + else + { + llerrs << "No Drawable found in the entry." << llendl; + } } } @@ -1415,16 +1229,6 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node) mOctreeNode = NULL; } -void LLSpatialGroup::handleStateChange(const TreeNode* node) -{ - //drop bounding box upon state change - if (mOctreeNode != node) - { - mOctreeNode = (OctreeNode*) node; - } - unbound(); -} - void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child) { if (child->getListenerCount() == 0) @@ -1441,11 +1245,6 @@ void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* c assert_states_valid(this); } -void LLSpatialGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNode* child) -{ - unbound(); -} - void LLSpatialGroup::destroyGL(bool keep_occlusion) { setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY); @@ -1476,7 +1275,11 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion) for (LLSpatialGroup::element_iter i = getDataBegin(); i != getDataEnd(); ++i) { - LLDrawable* drawable = *i; + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } for (S32 j = 0; j < drawable->getNumFaces(); j++) { LLFace* facep = drawable->getFace(j); @@ -1488,69 +1291,6 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion) } } -BOOL LLSpatialGroup::rebound() -{ - if (!isState(DIRTY)) - { //return TRUE if we're not empty - return TRUE; - } - - if (mOctreeNode->getChildCount() == 1 && mOctreeNode->getElementCount() == 0) - { - LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(0)->getListener(0); - group->rebound(); - - //copy single child's bounding box - mBounds[0] = group->mBounds[0]; - mBounds[1] = group->mBounds[1]; - mExtents[0] = group->mExtents[0]; - mExtents[1] = group->mExtents[1]; - - group->setState(SKIP_FRUSTUM_CHECK); - } - else if (mOctreeNode->isLeaf()) - { //copy object bounding box if this is a leaf - boundObjects(TRUE, mExtents[0], mExtents[1]); - mBounds[0] = mObjectBounds[0]; - mBounds[1] = mObjectBounds[1]; - } - else - { - LLVector4a& newMin = mExtents[0]; - LLVector4a& newMax = mExtents[1]; - LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(0)->getListener(0); - group->clearState(SKIP_FRUSTUM_CHECK); - group->rebound(); - //initialize to first child - newMin = group->mExtents[0]; - newMax = group->mExtents[1]; - - //first, rebound children - for (U32 i = 1; i < mOctreeNode->getChildCount(); i++) - { - group = (LLSpatialGroup*) mOctreeNode->getChild(i)->getListener(0); - group->clearState(SKIP_FRUSTUM_CHECK); - group->rebound(); - const LLVector4a& max = group->mExtents[1]; - const LLVector4a& min = group->mExtents[0]; - - newMax.setMax(newMax, max); - newMin.setMin(newMin, min); - } - - boundObjects(FALSE, newMin, newMax); - - mBounds[0].setAdd(newMin, newMax); - mBounds[0].mul(0.5f); - mBounds[1].setSub(newMax, newMin); - mBounds[1].mul(0.5f); - } - - clearState(DIRTY); - - return TRUE; -} - static LLFastTimer::DeclareTimer FTM_OCCLUSION_READBACK("Readback Occlusion"); static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Occlusion Wait"); @@ -1769,8 +1509,8 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) //============================================== -LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage) -: mRenderByGroup(render_by_group), mBridge(NULL) +LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage, LLViewerRegion* regionp) +: mRenderByGroup(render_by_group), mBridge(NULL), mRegionp(regionp) { mOcclusionEnabled = TRUE; mDrawableType = 0; @@ -1782,13 +1522,13 @@ LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mDepthMask = FALSE; mSlopRatio = 0.25f; mInfiniteFarClip = FALSE; + mVisitedTime = 0; LLVector4a center, size; center.splat(0.f); size.splat(1.f); - mOctree = new LLSpatialGroup::OctreeRoot(center,size, - NULL); + mOctree = new OctreeRoot(center,size, NULL); new LLSpatialGroup(mOctree, this); } @@ -1799,6 +1539,10 @@ LLSpatialPartition::~LLSpatialPartition() mOctree = NULL; } +BOOL LLSpatialPartition::isVOCachePartition() const +{ + return mPartitionType == LLViewerRegion::PARTITION_VO_CACHE; +} LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) { @@ -1806,12 +1550,16 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) //keep drawable from being garbage collected LLPointer ptr = drawablep; - - assert_octree_valid(mOctree); - mOctree->insert(drawablep); - assert_octree_valid(mOctree); + + if(!drawablep->getGroup()) + { + assert_octree_valid(mOctree); + mOctree->insert(drawablep->getEntry()); + assert_octree_valid(mOctree); + } LLSpatialGroup* group = drawablep->getSpatialGroup(); + llassert(group != NULL); if (group && was_visible && group->isOcclusionState(LLSpatialGroup::QUERY_PENDING)) { @@ -1829,7 +1577,7 @@ BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp) } else { - drawablep->setSpatialGroup(NULL); + drawablep->setGroup(NULL); } assert_octree_valid(mOctree); @@ -1881,13 +1629,13 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL put(drawablep, was_visible); } -class LLSpatialShift : public LLSpatialGroup::OctreeTraveler +class LLSpatialShift : public OctreeTraveler { public: const LLVector4a& mOffset; LLSpatialShift(const LLVector4a& offset) : mOffset(offset) { } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) + virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->shift(mOffset); } @@ -1899,17 +1647,17 @@ void LLSpatialPartition::shift(const LLVector4a &offset) shifter.traverse(mOctree); } -class LLOctreeCull : public LLSpatialGroup::OctreeTraveler +class LLOctreeCull : public LLViewerOctreeCull { public: - LLOctreeCull(LLCamera* camera) - : mCamera(camera), mRes(0) { } + LLOctreeCull(LLCamera* camera) : LLViewerOctreeCull(camera) {} - virtual bool earlyFail(LLSpatialGroup* group) + virtual bool earlyFail(LLviewerOctreeGroup* base_group) { + LLSpatialGroup* group = (LLSpatialGroup*)base_group; group->checkOcclusion(); - if (group->mOctreeNode->getParent() && //never occlusion cull the root node + if (group->getOctreeNode()->getParent() && //never occlusion cull the root node LLPipeline::sUseOcclusion && //ignore occlusion if disabled group->isOcclusionState(LLSpatialGroup::OCCLUDED)) { @@ -1919,79 +1667,30 @@ public: return false; } - - virtual void traverse(const LLSpatialGroup::OctreeNode* n) - { - LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - - if (earlyFail(group)) - { - return; - } - if (mRes == 2 || - (mRes && group->isState(LLSpatialGroup::SKIP_FRUSTUM_CHECK))) - { //fully in, just add everything - LLSpatialGroup::OctreeTraveler::traverse(n); - } - else - { - mRes = frustumCheck(group); - - if (mRes) - { //at least partially in, run on down - LLSpatialGroup::OctreeTraveler::traverse(n); - } - - mRes = 0; - } - } - - virtual S32 frustumCheck(const LLSpatialGroup* group) + virtual S32 frustumCheck(const LLviewerOctreeGroup* group) { - S32 res = mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]); + S32 res = AABBInFrustumNoFarClipGroupBounds(group); if (res != 0) { - res = llmin(res, AABBSphereIntersect(group->mExtents[0], group->mExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist)); + res = llmin(res, AABBSphereIntersectGroupExtents(group)); } return res; } - virtual S32 frustumCheckObjects(const LLSpatialGroup* group) + virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group) { - S32 res = mCamera->AABBInFrustumNoFarClip(group->mObjectBounds[0], group->mObjectBounds[1]); + S32 res = AABBInFrustumNoFarClipObjectBounds(group); if (res != 0) { - res = llmin(res, AABBSphereIntersect(group->mObjectExtents[0], group->mObjectExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist)); + res = llmin(res, AABBSphereIntersectObjectExtents(group)); } return res; } - virtual bool checkObjects(const LLSpatialGroup::OctreeNode* branch, const LLSpatialGroup* group) - { - if (branch->getElementCount() == 0) //no elements - { - return false; - } - else if (branch->getChildCount() == 0) //leaf state, already checked tightest bounding box - { - return true; - } - else if (mRes == 1 && !frustumCheckObjects(group)) //no objects in frustum - { - return false; - } - - return true; - } - - virtual void preprocess(LLSpatialGroup* group) - { - - } - - virtual void processGroup(LLSpatialGroup* group) + virtual void processGroup(LLviewerOctreeGroup* base_group) { + LLSpatialGroup* group = (LLSpatialGroup*)base_group; if (group->needsUpdate() || group->mVisible[LLViewerCamera::sCurCameraID] < LLDrawable::getCurrentFrame() - 1) { @@ -1999,21 +1698,6 @@ public: } gPipeline.markNotCulled(group, *mCamera); } - - virtual void visit(const LLSpatialGroup::OctreeNode* branch) - { - LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0); - - preprocess(group); - - if (checkObjects(branch, group)) - { - processGroup(group); - } - } - - LLCamera *mCamera; - S32 mRes; }; class LLOctreeCullNoFarClip : public LLOctreeCull @@ -2022,14 +1706,14 @@ public: LLOctreeCullNoFarClip(LLCamera* camera) : LLOctreeCull(camera) { } - virtual S32 frustumCheck(const LLSpatialGroup* group) + virtual S32 frustumCheck(const LLviewerOctreeGroup* group) { - return mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]); + return AABBInFrustumNoFarClipGroupBounds(group); } - virtual S32 frustumCheckObjects(const LLSpatialGroup* group) + virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group) { - S32 res = mCamera->AABBInFrustumNoFarClip(group->mObjectBounds[0], group->mObjectBounds[1]); + S32 res = AABBInFrustumNoFarClipObjectBounds(group); return res; } }; @@ -2040,14 +1724,14 @@ public: LLOctreeCullShadow(LLCamera* camera) : LLOctreeCull(camera) { } - virtual S32 frustumCheck(const LLSpatialGroup* group) + virtual S32 frustumCheck(const LLviewerOctreeGroup* group) { - return mCamera->AABBInFrustum(group->mBounds[0], group->mBounds[1]); + return AABBInFrustumGroupBounds(group); } - virtual S32 frustumCheckObjects(const LLSpatialGroup* group) + virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group) { - return mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]); + return AABBInFrustumObjectBounds(group); } }; @@ -2057,9 +1741,11 @@ public: LLOctreeCullVisExtents(LLCamera* camera, LLVector4a& min, LLVector4a& max) : LLOctreeCullShadow(camera), mMin(min), mMax(max), mEmpty(TRUE) { } - virtual bool earlyFail(LLSpatialGroup* group) + virtual bool earlyFail(LLviewerOctreeGroup* base_group) { - if (group->mOctreeNode->getParent() && //never occlusion cull the root node + LLSpatialGroup* group = (LLSpatialGroup*)base_group; + + if (group->getOctreeNode()->getParent() && //never occlusion cull the root node LLPipeline::sUseOcclusion && //ignore occlusion if disabled group->isOcclusionState(LLSpatialGroup::OCCLUDED)) { @@ -2069,7 +1755,7 @@ public: return false; } - virtual void traverse(const LLSpatialGroup::OctreeNode* n) + virtual void traverse(const OctreeNode* n) { LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); @@ -2078,10 +1764,10 @@ public: return; } - if ((mRes && group->isState(LLSpatialGroup::SKIP_FRUSTUM_CHECK)) || + if ((mRes && group->hasState(LLSpatialGroup::SKIP_FRUSTUM_CHECK)) || mRes == 2) { //don't need to do frustum check - LLSpatialGroup::OctreeTraveler::traverse(n); + OctreeTraveler::traverse(n); } else { @@ -2089,31 +1775,35 @@ public: if (mRes) { //at least partially in, run on down - LLSpatialGroup::OctreeTraveler::traverse(n); + OctreeTraveler::traverse(n); } mRes = 0; } } - virtual void processGroup(LLSpatialGroup* group) + virtual void processGroup(LLviewerOctreeGroup* base_group) { - llassert(!group->isState(LLSpatialGroup::DIRTY) && !group->isEmpty()) + LLSpatialGroup* group = (LLSpatialGroup*)base_group; + + llassert(!group->hasState(LLSpatialGroup::DIRTY) && !group->isEmpty()) if (mRes < 2) { - if (mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]) > 0) + if (AABBInFrustumObjectBounds(group) > 0) { mEmpty = FALSE; - update_min_max(mMin, mMax, group->mObjectExtents[0]); - update_min_max(mMin, mMax, group->mObjectExtents[1]); + const LLVector4a* exts = group->getObjectExtents(); + update_min_max(mMin, mMax, exts[0]); + update_min_max(mMin, mMax, exts[1]); } } else { mEmpty = FALSE; - update_min_max(mMin, mMax, group->mExtents[0]); - update_min_max(mMin, mMax, group->mExtents[1]); + const LLVector4a* exts = group->getExtents(); + update_min_max(mMin, mMax, exts[0]); + update_min_max(mMin, mMax, exts[1]); } } @@ -2128,10 +1818,12 @@ public: LLOctreeCullDetectVisible(LLCamera* camera) : LLOctreeCullShadow(camera), mResult(FALSE) { } - virtual bool earlyFail(LLSpatialGroup* group) + virtual bool earlyFail(LLviewerOctreeGroup* base_group) { + LLSpatialGroup* group = (LLSpatialGroup*)base_group; + if (mResult || //already found a node, don't check any more - (group->mOctreeNode->getParent() && //never occlusion cull the root node + (group->getOctreeNode()->getParent() && //never occlusion cull the root node LLPipeline::sUseOcclusion && //ignore occlusion if disabled group->isOcclusionState(LLSpatialGroup::OCCLUDED))) { @@ -2141,9 +1833,9 @@ public: return false; } - virtual void processGroup(LLSpatialGroup* group) + virtual void processGroup(LLviewerOctreeGroup* base_group) { - if (group->isVisible()) + if (base_group->isVisible()) { mResult = TRUE; } @@ -2158,17 +1850,21 @@ public: LLOctreeSelect(LLCamera* camera, std::vector* results) : LLOctreeCull(camera), mResults(results) { } - virtual bool earlyFail(LLSpatialGroup* group) { return false; } - virtual void preprocess(LLSpatialGroup* group) { } + virtual bool earlyFail(LLviewerOctreeGroup* group) { return false; } + virtual void preprocess(LLviewerOctreeGroup* group) { } - virtual void processGroup(LLSpatialGroup* group) + virtual void processGroup(LLviewerOctreeGroup* base_group) { - LLSpatialGroup::OctreeNode* branch = group->mOctreeNode; + LLSpatialGroup* group = (LLSpatialGroup*)base_group; + OctreeNode* branch = group->getOctreeNode(); - for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) + for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) { - LLDrawable* drawable = *i; - + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } if (!drawable->isDead()) { if (drawable->isSpatialBridge()) @@ -2281,17 +1977,21 @@ void drawBoxOutline(const LLVector4a& pos, const LLVector4a& size) drawBoxOutline(reinterpret_cast(pos), reinterpret_cast(size)); } -class LLOctreeDirty : public LLOctreeTraveler +class LLOctreeDirty : public OctreeTraveler { public: - virtual void visit(const LLOctreeNode* state) + virtual void visit(const OctreeNode* state) { LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); group->destroyGL(); for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - LLDrawable* drawable = *i; + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } if (drawable->getVObj().notNull() && !group->mSpatialPartition->mRenderByGroup) { gPipeline.markRebuild(drawable, LLDrawable::REBUILD_ALL, TRUE); @@ -2350,6 +2050,13 @@ BOOL LLSpatialPartition::visibleObjectsInFrustum(LLCamera& camera) S32 LLSpatialPartition::cull(LLCamera &camera, std::vector* results, BOOL for_select) { + bool is_vo_cache_part = (mPartitionType == LLViewerRegion::PARTITION_VO_CACHE); + + if(is_vo_cache_part && mVisitedTime == LLViewerOctreeEntryData::getCurrentFrame()) + { + return 0; //no need to visit more than once per frame + } + #if LL_OCTREE_PARANOIA_CHECK ((LLSpatialGroup*)mOctree->getListener(0))->checkStates(); #endif @@ -2364,18 +2071,18 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector* result #endif - if (for_select) + if (for_select && !is_vo_cache_part) { LLOctreeSelect selecter(&camera, results); selecter.traverse(mOctree); } - else if (LLPipeline::sShadowRender) + else if (LLPipeline::sShadowRender && !is_vo_cache_part) { LLFastTimer ftm(FTM_FRUSTUM_CULL); LLOctreeCullShadow culler(&camera); culler.traverse(mOctree); } - else if (mInfiniteFarClip || !LLPipeline::sUseFarClip) + else if ((mInfiniteFarClip || !LLPipeline::sUseFarClip) && !is_vo_cache_part) { LLFastTimer ftm(FTM_FRUSTUM_CULL); LLOctreeCullNoFarClip culler(&camera); @@ -2383,6 +2090,11 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector* result } else { + if(is_vo_cache_part) + { + mVisitedTime = LLViewerOctreeEntryData::getCurrentFrame(); + } + LLFastTimer ftm(FTM_FRUSTUM_CULL); LLOctreeCull culler(&camera); culler.traverse(mOctree); @@ -2402,9 +2114,10 @@ BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group) LLVector4a fudge; fudge.splat(vel); - const LLVector4a& c = group->mBounds[0]; + const LLVector4a* bounds = group->getBounds(); + const LLVector4a& c = bounds[0]; LLVector4a r; - r.setAdd(group->mBounds[1], fudge); + r.setAdd(bounds[1], fudge); /*if (r.magVecSquared() > 1024.0*1024.0) { @@ -2529,7 +2242,8 @@ void pushBufferVerts(LLSpatialGroup* group, U32 mask) } else { - drawBox(group->mBounds[0], group->mBounds[1]); + const LLVector4a* bounds = group->getBounds(); + drawBox(bounds[0], bounds[1]); } } @@ -2593,13 +2307,19 @@ void renderOctree(LLSpatialGroup* group) gGL.diffuseColor4f(1,0,0,group->mBuilt); gGL.flush(); glLineWidth(5.f); - drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]); + + const LLVector4a* bounds = group->getObjectBounds(); + drawBoxOutline(bounds[0], bounds[1]); gGL.flush(); glLineWidth(1.f); gGL.flush(); for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - LLDrawable* drawable = *i; + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } if (!group->mSpatialPartition->isBridge()) { gGL.pushMatrix(); @@ -2657,9 +2377,10 @@ void renderOctree(LLSpatialGroup* group) gGL.diffuseColor4fv(col.mV); LLVector4a fudge; fudge.splat(0.001f); - LLVector4a size = group->mObjectBounds[1]; - size.mul(1.01f); - size.add(fudge); + + //LLVector4a size = group->mObjectBounds[1]; + //size.mul(1.01f); + //size.add(fudge); //{ // LLGLDepthTest depth(GL_TRUE, GL_FALSE); @@ -2675,7 +2396,9 @@ void renderOctree(LLSpatialGroup* group) //drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]); gGL.diffuseColor4f(0,1,1,1); - drawBoxOutline(group->mBounds[0],group->mBounds[1]); + + const LLVector4a* bounds = group->getBounds(); + drawBoxOutline(bounds[0], bounds[1]); //draw bounding box for draw info /*if (group->mSpatialPartition->mRenderByGroup) @@ -3442,9 +3165,13 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume) void renderPhysicsShapes(LLSpatialGroup* group) { - for (LLSpatialGroup::OctreeNode::const_element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) + for (OctreeNode::const_element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - LLDrawable* drawable = *i; + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } LLVOVolume* volume = drawable->getVOVolume(); if (volume && !volume->isAttachment() && volume->getPhysicsShapeType() != LLViewerObject::PHYSICS_SHAPE_NONE ) { @@ -4001,17 +3728,18 @@ void renderAgentTarget(LLVOAvatar* avatar) } } -class LLOctreeRenderNonOccluded : public LLOctreeTraveler +class LLOctreeRenderNonOccluded : public OctreeTraveler { public: LLCamera* mCamera; LLOctreeRenderNonOccluded(LLCamera* camera): mCamera(camera) {} - virtual void traverse(const LLSpatialGroup::OctreeNode* node) + virtual void traverse(const OctreeNode* node) { LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - if (!mCamera || mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1])) + const LLVector4a* bounds = group->getBounds(); + if (!mCamera || mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1])) { node->accept(this); stop_glerror(); @@ -4051,17 +3779,17 @@ public: } } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) + virtual void visit(const OctreeNode* branch) { LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0); - - if (group->isState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]))) + const LLVector4a* bounds = group->getBounds(); + if (group->hasState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1]))) { return; } - LLVector4a nodeCenter = group->mBounds[0]; - LLVector4a octCenter = group->mOctreeNode->getCenter(); + LLVector4a nodeCenter = bounds[0]; + LLVector4a octCenter = group->getOctreeNode()->getCenter(); group->rebuildGeom(); group->rebuildMesh(); @@ -4071,15 +3799,20 @@ public: if (!group->isEmpty()) { gGL.diffuseColor3f(0,0,1); - drawBoxOutline(group->mObjectBounds[0], - group->mObjectBounds[1]); + + const LLVector4a* obj_bounds = group->getObjectBounds(); + drawBoxOutline(obj_bounds[0], obj_bounds[1]); } } - for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) + for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) { - LLDrawable* drawable = *i; - + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES)) { renderBoundingBox(drawable); @@ -4201,17 +3934,18 @@ public: }; -class LLOctreeRenderPhysicsShapes : public LLOctreeTraveler +class LLOctreeRenderPhysicsShapes : public OctreeTraveler { public: LLCamera* mCamera; LLOctreeRenderPhysicsShapes(LLCamera* camera): mCamera(camera) {} - virtual void traverse(const LLSpatialGroup::OctreeNode* node) + virtual void traverse(const OctreeNode* node) { LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - if (!mCamera || mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1])) + const LLVector4a* bounds = group->getBounds(); + if (!mCamera || mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1])) { node->accept(this); stop_glerror(); @@ -4229,23 +3963,24 @@ public: } } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) + virtual void visit(const OctreeNode* branch) { } }; -class LLOctreePushBBoxVerts : public LLOctreeTraveler +class LLOctreePushBBoxVerts : public OctreeTraveler { public: LLCamera* mCamera; LLOctreePushBBoxVerts(LLCamera* camera): mCamera(camera) {} - virtual void traverse(const LLSpatialGroup::OctreeNode* node) + virtual void traverse(const OctreeNode* node) { LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - if (!mCamera || mCamera->AABBInFrustum(group->mBounds[0], group->mBounds[1])) + const LLVector4a* bounds = group->getBounds(); + if (!mCamera || mCamera->AABBInFrustum(bounds[0], bounds[1])) { node->accept(this); @@ -4256,19 +3991,23 @@ public: } } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) + virtual void visit(const OctreeNode* branch) { LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0); - if (group->isState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]))) + const LLVector4a* bounds = group->getBounds(); + if (group->hasState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1]))) { return; } - for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) + for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) { - LLDrawable* drawable = *i; - + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(!drawable) + { + continue; + } renderBoundingBox(drawable, FALSE); } } @@ -4280,7 +4019,7 @@ void LLSpatialPartition::renderIntersectingBBoxes(LLCamera* camera) pusher.traverse(mOctree); } -class LLOctreeStateCheck : public LLOctreeTraveler +class LLOctreeStateCheck : public OctreeTraveler { public: U32 mInheritedMask[LLViewerCamera::NUM_CAMERAS]; @@ -4293,7 +4032,7 @@ public: } } - virtual void traverse(const LLSpatialGroup::OctreeNode* node) + virtual void traverse(const OctreeNode* node) { LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); @@ -4320,7 +4059,7 @@ public: } - virtual void visit(const LLOctreeNode* state) + virtual void visit(const OctreeNode* state) { LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); @@ -4332,7 +4071,7 @@ public: } } - if (group->isState(LLSpatialGroup::DIRTY)) + if (group->hasState(LLSpatialGroup::DIRTY)) { assert_parent_state(group, LLSpatialGroup::DIRTY); } @@ -4343,7 +4082,7 @@ public: LLSpatialGroup* parent = group->getParent(); while (parent) { - if (!parent->isState(state)) + if (!parent->hasState(state)) { llerrs << "Spatial group failed parent state check." << llendl; } @@ -4458,7 +4197,7 @@ BOOL LLSpatialPartition::isVisible(const LLVector3& v) return TRUE; } -class LLOctreeIntersect : public LLSpatialGroup::OctreeTraveler +class LLOctreeIntersect : public OctreeTraveler { public: LLVector3 mStart; @@ -4485,21 +4224,21 @@ public: { } - virtual void visit(const LLSpatialGroup::OctreeNode* branch) + virtual void visit(const OctreeNode* branch) { - for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) + for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) { check(*i); } } - virtual LLDrawable* check(const LLSpatialGroup::OctreeNode* node) + virtual LLDrawable* check(const OctreeNode* node) { node->accept(this); for (U32 i = 0; i < node->getChildCount(); i++) { - const LLSpatialGroup::OctreeNode* child = node->getChild(i); + const OctreeNode* child = node->getChild(i); LLVector3 res; LLSpatialGroup* group = (LLSpatialGroup*) child->getListener(0); @@ -4507,8 +4246,9 @@ public: LLVector4a size; LLVector4a center; - size = group->mBounds[1]; - center = group->mBounds[0]; + const LLVector4a* bounds = group->getBounds(); + size = bounds[1]; + center = bounds[0]; LLVector3 local_start = mStart; LLVector3 local_end = mEnd; @@ -4535,8 +4275,9 @@ public: return mHit; } - virtual bool check(LLDrawable* drawable) + virtual bool check(LLViewerOctreeEntry* entry) { + LLDrawable* drawable = (LLDrawable*)entry->getDrawable(); LLVector3 local_start = mStart; LLVector3 local_end = mEnd; @@ -4922,5 +4663,21 @@ void LLCullResult::assertDrawMapsEmpty() } } +LLVOCachePartition::LLVOCachePartition(LLViewerRegion* regionp) : LLSpatialPartition(0, FALSE, 0, regionp) +{ + mPartitionType = LLViewerRegion::PARTITION_VO_CACHE; +} + +void LLVOCachePartition::addEntry(LLViewerOctreeEntry* entry) +{ + llassert(entry->hasVOCacheEntry()); + mOctree->insert(entry); +} + +void LLVOCachePartition::removeEntry(LLViewerOctreeEntry* entry) +{ + entry->getVOCacheEntry()->setGroup(NULL); + llassert(!entry->getGroup()); +} diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index f050df2b39..dd189d751d 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -50,12 +50,8 @@ class LLSpatialBridge; class LLSpatialGroup; class LLTextureAtlas; class LLTextureAtlasSlot; +class LLViewerRegion; -S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad); -S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &radius_squared); - -S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad); -S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &radius_squared); void pushVerts(LLFace* face, U32 mask); // get index buffer for binary encoded axis vertex buffer given a box at center being viewed by given camera @@ -192,13 +188,13 @@ public: }; LL_ALIGN_PREFIX(16) -class LLSpatialGroup : public LLOctreeListener +class LLSpatialGroup : public LLviewerOctreeGroup { friend class LLSpatialPartition; friend class LLOctreeStateCheck; public: - LLSpatialGroup(const LLSpatialGroup& rhs) + LLSpatialGroup(const LLSpatialGroup& rhs) : LLviewerOctreeGroup(rhs) { *this = rhs; } @@ -231,14 +227,8 @@ public: typedef std::map buffer_texture_map_t; typedef std::map buffer_map_t; - typedef LLOctreeListener BaseType; - typedef LLOctreeListener OctreeListener; - typedef LLTreeNode TreeNode; - typedef LLOctreeNode OctreeNode; - typedef LLOctreeRoot OctreeRoot; - typedef LLOctreeTraveler OctreeTraveler; - typedef LLOctreeNode::element_iter element_iter; - typedef LLOctreeNode::element_list element_list; + typedef LLOctreeNode::element_iter element_iter; + typedef LLOctreeNode::element_list element_list; struct CompareDistanceGreater { @@ -275,18 +265,15 @@ public: typedef enum { - DEAD = 0x00000001, - DIRTY = 0x00000002, - OBJECT_DIRTY = 0x00000004, - GEOM_DIRTY = 0x00000008, - ALPHA_DIRTY = 0x00000010, - SKIP_FRUSTUM_CHECK = 0x00000020, - IN_IMAGE_QUEUE = 0x00000040, - IMAGE_DIRTY = 0x00000080, - MESH_DIRTY = 0x00000100, - NEW_DRAWINFO = 0x00000200, - IN_BUILD_Q1 = 0x00000400, - IN_BUILD_Q2 = 0x00000800, + DEAD = LLviewerOctreeGroup::INVALID_STATE, + GEOM_DIRTY = (DEAD << 1), + ALPHA_DIRTY = (GEOM_DIRTY << 1), + IN_IMAGE_QUEUE = (ALPHA_DIRTY << 1), + IMAGE_DIRTY = (IN_IMAGE_QUEUE << 1), + MESH_DIRTY = (IMAGE_DIRTY << 1), + NEW_DRAWINFO = (MESH_DIRTY << 1), + IN_BUILD_Q1 = (NEW_DRAWINFO << 1), + IN_BUILD_Q2 = (IN_BUILD_Q1 << 1), STATE_MASK = 0x0000FFFF, } eSpatialState; @@ -301,12 +288,8 @@ public: LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part); BOOL isHUDGroup() ; - BOOL isDead() { return isState(DEAD); } - BOOL isState(U32 state) const; + BOOL isDead() { return hasState(DEAD); } BOOL isOcclusionState(U32 state) const { return mOcclusionState[LLViewerCamera::sCurCameraID] & state ? TRUE : FALSE; } - U32 getState() { return mState; } - void setState(U32 state); - void clearState(U32 state); void clearDrawMap(); void validate(); @@ -315,23 +298,20 @@ public: void setState(U32 state, S32 mode); void clearState(U32 state, S32 mode); + void clearState(U32 state) {mState &= ~state;} void setOcclusionState(U32 state, S32 mode = STATE_MODE_SINGLE); void clearOcclusionState(U32 state, S32 mode = STATE_MODE_SINGLE); LLSpatialGroup* getParent(); - - BOOL addObject(LLDrawable *drawablep, BOOL add_all = FALSE, BOOL from_octree = FALSE); + BOOL addObject(LLDrawable *drawablep); BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE); BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group BOOL isVisible() const; BOOL isRecentlyVisible() const; void setVisible(); void shift(const LLVector4a &offset); - BOOL boundObjects(BOOL empty, LLVector4a& newMin, LLVector4a& newMax); - void unbound(); - BOOL rebound(); void checkOcclusion(); //read back last occlusion query (if any) void doOcclusion(LLCamera* camera); //issue occlusion query void destroyGL(bool keep_occlusion = false); @@ -343,6 +323,7 @@ public: void rebuildGeom(); void rebuildMesh(); + void setState(U32 state) {mState |= state;} void dirtyGeom() { setState(GEOM_DIRTY); } void dirtyMesh() { setState(MESH_DIRTY); } @@ -356,13 +337,11 @@ public: void drawObjectBox(LLColor4 col); //LISTENER FUNCTIONS - virtual void handleInsertion(const TreeNode* node, LLDrawable* face); - virtual void handleRemoval(const TreeNode* node, LLDrawable* face); + virtual void handleInsertion(const TreeNode* node, LLViewerOctreeEntry* face); + virtual void handleRemoval(const TreeNode* node, LLViewerOctreeEntry* face); virtual void handleDestruction(const TreeNode* node); - virtual void handleStateChange(const TreeNode* node); virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child); - virtual void handleChildRemoval(const OctreeNode* parent, const OctreeNode* child); - + //------------------- //for atlas use //------------------- @@ -384,21 +363,6 @@ public: public: - typedef enum - { - BOUNDS = 0, - EXTENTS = 2, - OBJECT_BOUNDS = 4, - OBJECT_EXTENTS = 6, - VIEW_ANGLE = 8, - LAST_VIEW_ANGLE = 9, - V4_COUNT = 10 - } eV4Index; - - LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects) - LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children - LL_ALIGN_16(LLVector4a mObjectExtents[2]); // extents (min, max) of objects in this node - LL_ALIGN_16(LLVector4a mObjectBounds[2]); // bounding box (center, size) of objects in this node LL_ALIGN_16(LLVector4a mViewAngle); LL_ALIGN_16(LLVector4a mLastUpdateViewAngle); @@ -419,7 +383,6 @@ private: protected: virtual ~LLSpatialGroup(); - U32 mState; U32 mOcclusionState[LLViewerCamera::NUM_CAMERAS]; U32 mOcclusionIssued[LLViewerCamera::NUM_CAMERAS]; @@ -434,7 +397,6 @@ public: F32 mSurfaceArea; //used by volumes to track estimated surface area of geometry in this node F32 mBuilt; - OctreeNode* mOctreeNode; LLSpatialPartition* mSpatialPartition; LLPointer mVertexBuffer; @@ -469,7 +431,7 @@ public: class LLSpatialPartition: public LLGeometryManager { public: - LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mBufferUsage); + LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mBufferUsage, LLViewerRegion* regionp); virtual ~LLSpatialPartition(); LLSpatialGroup *put(LLDrawable *drawablep, BOOL was_visible = FALSE); @@ -511,9 +473,10 @@ public: void resetVertexBuffers(); BOOL isOcclusionEnabled(); BOOL getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax); + BOOL isVOCachePartition() const; public: - LLSpatialGroup::OctreeNode* mOctree; + 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 @@ -528,6 +491,8 @@ public: BOOL mDepthMask; //if TRUE, objects in this partition will be written to depth during alpha rendering U32 mDrawableType; U32 mPartitionType; + U32 mVisitedTime; + LLViewerRegion* mRegionp; // the region this partition belongs to. }; // class for creating bridges between spatial partitions @@ -539,7 +504,7 @@ protected: public: typedef std::vector > bridge_vector_t; - LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask); + LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask, LLViewerRegion* regionp); void destroyTree(); @@ -562,7 +527,7 @@ public: }; -class LLCullResult +class LLCullResult { public: LLCullResult(); @@ -661,7 +626,7 @@ private: class LLWaterPartition : public LLSpatialPartition { public: - LLWaterPartition(); + LLWaterPartition(LLViewerRegion* regionp); virtual void getGeometry(LLSpatialGroup* group) { } virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { } }; @@ -670,14 +635,27 @@ public: class LLVoidWaterPartition : public LLWaterPartition { public: - LLVoidWaterPartition(); + LLVoidWaterPartition(LLViewerRegion* regionp); +}; + +//spatial partition for hole and edge water (implemented in LLVOWater.cpp) +class LLVOCachePartition : public LLSpatialPartition +{ +public: + LLVOCachePartition(LLViewerRegion* regionp); + + void addEntry(LLViewerOctreeEntry* entry); + void removeEntry(LLViewerOctreeEntry* entry); + + virtual void getGeometry(LLSpatialGroup* group) { } + virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { } }; //spatial partition for terrain (impelmented in LLVOSurfacePatch.cpp) class LLTerrainPartition : public LLSpatialPartition { public: - LLTerrainPartition(); + LLTerrainPartition(LLViewerRegion* regionp); virtual void getGeometry(LLSpatialGroup* group); virtual LLVertexBuffer* createVertexBuffer(U32 type_mask, U32 usage); }; @@ -686,7 +664,7 @@ public: class LLTreePartition : public LLSpatialPartition { public: - LLTreePartition(); + LLTreePartition(LLViewerRegion* regionp); virtual void getGeometry(LLSpatialGroup* group) { } virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { } @@ -696,7 +674,7 @@ public: class LLParticlePartition : public LLSpatialPartition { public: - LLParticlePartition(); + LLParticlePartition(LLViewerRegion* regionp); virtual void rebuildGeom(LLSpatialGroup* group); virtual void getGeometry(LLSpatialGroup* group); virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count); @@ -708,14 +686,14 @@ protected: class LLHUDParticlePartition : public LLParticlePartition { public: - LLHUDParticlePartition(); + LLHUDParticlePartition(LLViewerRegion* regionp); }; //spatial partition for grass (implemented in LLVOGrass.cpp) class LLGrassPartition : public LLSpatialPartition { public: - LLGrassPartition(); + LLGrassPartition(LLViewerRegion* regionp); virtual void getGeometry(LLSpatialGroup* group); virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count); protected: @@ -745,7 +723,7 @@ class LLVolumeGeometryManager: public LLGeometryManager class LLVolumePartition : public LLSpatialPartition, public LLVolumeGeometryManager { public: - LLVolumePartition(); + LLVolumePartition(LLViewerRegion* regionp); virtual void rebuildGeom(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildGeom(group); } virtual void getGeometry(LLSpatialGroup* group) { LLVolumeGeometryManager::getGeometry(group); } virtual void rebuildMesh(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildMesh(group); } @@ -756,7 +734,7 @@ public: class LLVolumeBridge : public LLSpatialBridge, public LLVolumeGeometryManager { public: - LLVolumeBridge(LLDrawable* drawable); + LLVolumeBridge(LLDrawable* drawable, LLViewerRegion* regionp); virtual void rebuildGeom(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildGeom(group); } virtual void getGeometry(LLSpatialGroup* group) { LLVolumeGeometryManager::getGeometry(group); } virtual void rebuildMesh(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildMesh(group); } @@ -766,7 +744,7 @@ public: class LLHUDBridge : public LLVolumeBridge { public: - LLHUDBridge(LLDrawable* drawablep); + LLHUDBridge(LLDrawable* drawablep, LLViewerRegion* regionp); virtual void shiftPos(const LLVector4a& vec); virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera); }; @@ -775,7 +753,7 @@ public: class LLBridgePartition : public LLSpatialPartition { public: - LLBridgePartition(); + LLBridgePartition(LLViewerRegion* regionp); virtual void getGeometry(LLSpatialGroup* group) { } virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { } }; @@ -783,7 +761,7 @@ public: class LLHUDPartition : public LLBridgePartition { public: - LLHUDPartition(); + LLHUDPartition(LLViewerRegion* regionp); virtual void shift(const LLVector4a &offset); }; diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index c60b4155a0..a5ccf97d1e 100755 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -49,6 +49,8 @@ #include "llviewertexturelist.h" #include "llvovolume.h" #include "llviewerstats.h" +#include "llworld.h" +#include "llviewerobjectlist.h" // For avatar texture view #include "llvoavatarself.h" @@ -515,6 +517,9 @@ void LLGLTexMemBar::draw() F32 total_texture_downloaded = (F32)gTotalTextureBytes / (1024 * 1024); F32 total_object_downloaded = (F32)gTotalObjectBytes / (1024 * 1024); U32 total_http_requests = LLAppViewer::getTextureFetch()->getCurlRequest().getTotalIssuedRequests() ; + U32 total_active_cached_objects = LLWorld::getInstance()->getNumOfActiveCachedObjects(); + U32 total_objects = gObjectList.getNumObjects(); + //---------------------------------------------------------------------------- LLGLSUIDefault gls_ui; LLColor4 text_color(1.f, 1.f, 1.f, 0.75f); @@ -536,8 +541,8 @@ void LLGLTexMemBar::draw() LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*4, text_color, LLFontGL::LEFT, LLFontGL::TOP); - text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d", - total_texture_downloaded, total_object_downloaded, total_http_requests); + text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB #Objs/#cached: %d/%d Tot Htp: %d", + total_texture_downloaded, total_object_downloaded, total_objects, total_active_cached_objects, total_http_requests); //, cache_entries, cache_max_entries LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3, text_color, LLFontGL::LEFT, LLFontGL::TOP); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index ec7d91ec4f..67d400af2d 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -4490,12 +4490,22 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data) LLUUID id; U32 local_id; - S32 i; + S32 i = 0; S32 num_objects; num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData); - for (i = 0; i < num_objects; i++) + mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i); + LLViewerRegion* regionp = NULL; + bool remove_from_cache = !local_id; //if the first local id is 0, physically remove all objects from VO cache. + if(remove_from_cache) + { + i++; + + LLHost host(gMessageSystem->getSenderIP(), gMessageSystem->getSenderPort()); + regionp = LLWorld::getInstance()->getRegion(host); + } + for (; i < num_objects; i++) { mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i); @@ -4530,10 +4540,15 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data) // Do the kill gObjectList.killObject(objectp); } - else + //else + //{ + // LL_WARNS("Messaging") << "Object in UUID lookup, but not on object list in kill!" << LL_ENDL; + // gObjectList.mNumUnknownKills++; + //} + + if(remove_from_cache) { - LL_WARNS("Messaging") << "Object in UUID lookup, but not on object list in kill!" << LL_ENDL; - gObjectList.mNumUnknownKills++; + regionp->killCacheEntry(local_id); } } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index aba1d131e1..dbccb2a4d9 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -100,6 +100,7 @@ #include "lltrans.h" #include "llsdutil.h" #include "llmediaentry.h" +#include "llvocache.h" //#define DEBUG_UPDATE_TYPE @@ -344,7 +345,7 @@ void LLViewerObject::markDead() childp = mChildList.back(); if (childp->getPCode() != LL_PCODE_LEGACY_AVATAR) { - //llinfos << "Marking child " << childp->getLocalID() << " as dead." << llendl; + //llinfos << "Marking child " << childp->getLocalID() << " as dead." << llendl; childp->setParent(NULL); // LLViewerObject::markDead 1 childp->markDead(); } @@ -885,10 +886,11 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, } // Coordinates of objects on simulators are region-local. - U64 region_handle; - mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle); + U64 region_handle = 0; + if(mesgsys != NULL) { + mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle); LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle); if(regionp != mRegionp && regionp && mRegionp)//region cross { @@ -914,11 +916,14 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, return retval; } - U16 time_dilation16; - mesgsys->getU16Fast(_PREHASH_RegionData, _PREHASH_TimeDilation, time_dilation16); - F32 time_dilation = ((F32) time_dilation16) / 65535.f; - mTimeDilation = time_dilation; - mRegionp->setTimeDilation(time_dilation); + if(mesgsys != NULL) + { + U16 time_dilation16; + mesgsys->getU16Fast(_PREHASH_RegionData, _PREHASH_TimeDilation, time_dilation16); + F32 time_dilation = ((F32) time_dilation16) / 65535.f; + mTimeDilation = time_dilation; + mRegionp->setTimeDilation(time_dilation); + } // this will be used to determine if we've really changed position // Use getPosition, not getPositionRegion, since this is what we're comparing directly against. @@ -1692,13 +1697,16 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, // Preload these five flags for every object. // Finer shades require the object to be selected, and the selection manager // stores the extended permission info. - U32 flags; - mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num); - // keep local flags and overwrite remote-controlled flags - mFlags = (mFlags & FLAGS_LOCAL) | flags; + if(mesgsys != NULL) + { + U32 flags; + mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num); + // keep local flags and overwrite remote-controlled flags + mFlags = (mFlags & FLAGS_LOCAL) | flags; // ...new objects that should come in selected need to be added to the selected list - mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0); + mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0); + } } break; @@ -1726,10 +1734,21 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, { // No parent now, new parent in message -> attach to that parent if possible LLUUID parent_uuid; - LLViewerObjectList::getUUIDFromLocal(parent_uuid, + + if(mesgsys != NULL) + { + LLViewerObjectList::getUUIDFromLocal(parent_uuid, parent_id, mesgsys->getSenderIP(), mesgsys->getSenderPort()); + } + else + { + LLViewerObjectList::getUUIDFromLocal(parent_uuid, + parent_id, + mRegionp->getHost().getAddress(), + mRegionp->getHost().getPort()); + } LLViewerObject *sent_parentp = gObjectList.findObject(parent_uuid); @@ -1805,9 +1824,18 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, // //parent_id - U32 ip = mesgsys->getSenderIP(); - U32 port = mesgsys->getSenderPort(); + U32 ip, port; + if(mesgsys != NULL) + { + ip = mesgsys->getSenderIP(); + port = mesgsys->getSenderPort(); + } + else + { + ip = mRegionp->getHost().getAddress(); + port = mRegionp->getHost().getPort(); + } gObjectList.orphanize(this, parent_id, ip, port); // Hide particles, icon and HUD @@ -1845,10 +1873,21 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, else { LLUUID parent_uuid; - LLViewerObjectList::getUUIDFromLocal(parent_uuid, + + if(mesgsys != NULL) + { + LLViewerObjectList::getUUIDFromLocal(parent_uuid, parent_id, gMessageSystem->getSenderIP(), gMessageSystem->getSenderPort()); + } + else + { + LLViewerObjectList::getUUIDFromLocal(parent_uuid, + parent_id, + mRegionp->getHost().getAddress(), + mRegionp->getHost().getPort()); + } sent_parentp = gObjectList.findObject(parent_uuid); if (isAvatar()) @@ -1869,8 +1908,18 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, // // Switching parents, but we don't know the new parent. // - U32 ip = mesgsys->getSenderIP(); - U32 port = mesgsys->getSenderPort(); + U32 ip, port; + + if(mesgsys != NULL) + { + ip = mesgsys->getSenderIP(); + port = mesgsys->getSenderPort(); + } + else + { + ip = mRegionp->getHost().getAddress(); + port = mRegionp->getHost().getPort(); + } // We're an orphan, flag things appropriately. gObjectList.orphanize(this, parent_id, ip, port); @@ -1954,7 +2003,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, new_rot.normQuat(); - if (sPingInterpolate) + if (sPingInterpolate && mesgsys != NULL) { LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mesgsys->getSender()); if (cdp) @@ -1977,16 +2026,18 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, // If we're going to skip this message, why are we // doing all the parenting, etc above? - U32 packet_id = mesgsys->getCurrentRecvPacketID(); - if (packet_id < mLatestRecvPacketID && - mLatestRecvPacketID - packet_id < 65536) + if(mesgsys != NULL) { - //skip application of this message, it's old - return retval; + U32 packet_id = mesgsys->getCurrentRecvPacketID(); + if (packet_id < mLatestRecvPacketID && + mLatestRecvPacketID - packet_id < 65536) + { + //skip application of this message, it's old + return retval; + } + mLatestRecvPacketID = packet_id; } - mLatestRecvPacketID = packet_id; - // Set the change flags for scale if (new_scale != getScale()) { diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 88bb087742..a1db1f7237 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -76,6 +76,7 @@ #include "object_flags.h" #include "llappviewer.h" +#include "llvocache.h" extern F32 gMinObjectDistance; extern BOOL gAnimateTextures; @@ -228,9 +229,15 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, U32 i, const EObjectUpdateType update_type, LLDataPacker* dpp, - BOOL just_created) + bool just_created, + bool from_cache) { - LLMessageSystem* msg = gMessageSystem; + LLMessageSystem* msg = NULL; + + if(!from_cache) + { + msg = gMessageSystem; + } // ignore returned flags objectp->processUpdateMessage(msg, user_data, i, update_type, dpp); @@ -254,7 +261,18 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, // RN: this must be called after we have a drawable // (from gPipeline.addObject) // so that the drawable parent is set properly - findOrphans(objectp, msg->getSenderIP(), msg->getSenderPort()); + if(msg != NULL) + { + findOrphans(objectp, msg->getSenderIP(), msg->getSenderPort()); + } + else + { + LLViewerRegion* regionp = objectp->getRegion(); + if(regionp != NULL) + { + findOrphans(objectp, regionp->getHost().getAddress(), regionp->getHost().getPort()); + } + } // If we're just wandering around, don't create new objects selected. if (just_created @@ -277,6 +295,82 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Objects"); +LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry* entry, LLViewerRegion* regionp) +{ + LLDataPacker *cached_dpp = entry->getDP(); + + if (!cached_dpp) + { + return NULL; //nothing cached. + } + + LLViewerObject *objectp; + U32 local_id; + LLPCode pcode = 0; + LLUUID fullid; + LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instance(); + + // Cache Hit. + cached_dpp->reset(); + cached_dpp->unpackUUID(fullid, "ID"); + cached_dpp->unpackU32(local_id, "LocalID"); + cached_dpp->unpackU8(pcode, "PCode"); + + objectp = findObject(fullid); + + if (objectp) + { + if(!objectp->isDead() && (objectp->mLocalID != entry->getLocalID() || + objectp->getRegion() != regionp)) + { + removeFromLocalIDTable(objectp); + setUUIDAndLocal(fullid, entry->getLocalID(), + regionp->getHost().getAddress(), + regionp->getHost().getPort()); + + if (objectp->mLocalID != entry->getLocalID()) + { // Update local ID in object with the one sent from the region + objectp->mLocalID = entry->getLocalID(); + } + + if (objectp->getRegion() != regionp) + { // Object changed region, so update it + objectp->updateRegion(regionp); // for LLVOAvatar + } + } + + //return TRUE; //already loaded. + } + + bool justCreated = false; + if (!objectp) + { + objectp = createObjectFromCache(pcode, regionp, fullid, entry->getLocalID()); + + if (!objectp) + { + llinfos << "createObject failure for object: " << fullid << llendl; + recorder.objectUpdateFailure(entry->getLocalID(), OUT_FULL_CACHED, 0); + return NULL; + } + justCreated = true; + mNumNewObjects++; + sCacheHitRate.addValue(100.f); + } + + if (objectp->isDead()) + { + llwarns << "Dead object " << objectp->mID << " in UUID map 1!" << llendl; + } + + processUpdateCore(objectp, NULL, 0, OUT_FULL_CACHED, cached_dpp, justCreated, true); + + recorder.log(0.2f); + LLVOAvatar::cullAvatarsByPixelArea(); + + return objectp; +} + void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, void **user_data, const EObjectUpdateType update_type, @@ -382,14 +476,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, } else if (compressed) { - S32 uncompressed_length = 2048; - compressed_dp.reset(); - - U32 flags = 0; - if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only? - { - mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i); - } + S32 uncompressed_length = 2048; + compressed_dp.reset(); uncompressed_length = mesgsys->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_Data); mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compressed_dpbuffer, 0, i); @@ -540,9 +628,15 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, processUpdateCore(objectp, user_data, i, update_type, &compressed_dp, justCreated); if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only? { - bCached = true; - LLViewerRegion::eCacheUpdateResult result = objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp); - recorder.cacheFullUpdate(local_id, update_type, result, objectp, msg_size); + U32 flags = 0; + mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i); + + if(!(flags & FLAGS_TEMPORARY_ON_REZ)) + { + bCached = true; + LLViewerRegion::eCacheUpdateResult result = objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp); + recorder.cacheFullUpdate(local_id, update_type, result, objectp, msg_size); + } } } else if (cached) // Cache hit only? @@ -1887,7 +1981,30 @@ LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLVi return objectp; } +LLViewerObject *LLViewerObjectList::createObjectFromCache(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id) +{ + llassert_always(uuid.notNull()); + LLViewerObject *objectp = LLViewerObject::createObject(uuid, pcode, regionp); + if (!objectp) + { +// llwarns << "Couldn't create object of type " << LLPrimitive::pCodeToString(pcode) << " id:" << fullid << llendl; + return NULL; + } + + objectp->mLocalID = local_id; + mUUIDObjectMap[uuid] = objectp; + setUUIDAndLocal(uuid, + local_id, + regionp->getHost().getAddress(), + regionp->getHost().getPort()); + mObjects.push_back(objectp); + + updateActive(objectp); + + return objectp; +} + LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id, const LLHost &sender) { diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 9936432a71..1476f44215 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -40,6 +40,7 @@ class LLCamera; class LLNetMap; class LLDebugBeacon; +class LLVOCacheEntry; const U32 CLOSE_BIN_SIZE = 10; const U32 NUM_BINS = 128; @@ -65,6 +66,7 @@ public: inline LLViewerObject *findObject(const LLUUID &id); LLViewerObject *createObjectViewer(const LLPCode pcode, LLViewerRegion *regionp); // Create a viewer-side object + LLViewerObject *createObjectFromCache(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id); LLViewerObject *createObject(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id, const LLHost &sender); @@ -78,7 +80,9 @@ public: void cleanDeadObjects(const BOOL use_timer = TRUE); // Clean up the dead object list. // Simulator and viewer side object updates... - void processUpdateCore(LLViewerObject* objectp, void** data, U32 block, const EObjectUpdateType update_type, LLDataPacker* dpp, BOOL justCreated); + void processUpdateCore(LLViewerObject* objectp, void** data, U32 block, const EObjectUpdateType update_type, + LLDataPacker* dpp, bool justCreated, bool from_cache = false); + LLViewerObject* processObjectUpdateFromCache(LLVOCacheEntry* entry, LLViewerRegion* regionp); void processObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type, bool cached=false, bool compressed=false); void processCompressedObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type); void processCachedObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type); diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp new file mode 100644 index 0000000000..05f977036c --- /dev/null +++ b/indra/newview/llvieweroctree.cpp @@ -0,0 +1,704 @@ +/** + * @file llvieweroctree.cpp + * @brief LLViewerOctreeGroup class implementation and supporting functions + * + * $LicenseInfo:firstyear=2003&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, 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" +#include "llvieweroctree.h" + +//----------------------------------------------------------------------------------- +//static variables definitions +//----------------------------------------------------------------------------------- +U32 LLViewerOctreeEntryData::sCurVisible = 0; + +//----------------------------------------------------------------------------------- +//some global functions definitions +//----------------------------------------------------------------------------------- +S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad) +{ + return AABBSphereIntersectR2(min, max, origin, rad*rad); +} + +S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &r) +{ + F32 d = 0.f; + F32 t; + + if ((min-origin).magVecSquared() < r && + (max-origin).magVecSquared() < r) + { + return 2; + } + + for (U32 i = 0; i < 3; i++) + { + if (origin.mV[i] < min.mV[i]) + { + t = min.mV[i] - origin.mV[i]; + d += t*t; + } + else if (origin.mV[i] > max.mV[i]) + { + t = origin.mV[i] - max.mV[i]; + d += t*t; + } + + if (d > r) + { + return 0; + } + } + + return 1; +} + + +S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad) +{ + return AABBSphereIntersectR2(min, max, origin, rad*rad); +} + +S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &r) +{ + F32 d = 0.f; + F32 t; + + LLVector4a origina; + origina.load3(origin.mV); + + LLVector4a v; + v.setSub(min, origina); + + if (v.dot3(v) < r) + { + v.setSub(max, origina); + if (v.dot3(v) < r) + { + return 2; + } + } + + + for (U32 i = 0; i < 3; i++) + { + if (origin.mV[i] < min[i]) + { + t = min[i] - origin.mV[i]; + d += t*t; + } + else if (origin.mV[i] > max[i]) + { + t = origin.mV[i] - max[i]; + d += t*t; + } + + if (d > r) + { + return 0; + } + } + + return 1; +} + +//----------------------------------------------------------------------------------- +//class LLViewerOctreeEntry definitions +//----------------------------------------------------------------------------------- +LLViewerOctreeEntry::LLViewerOctreeEntry() : mGroup(NULL) +{ + mPositionGroup.clear(); + mExtents[0].clear(); + mExtents[1].clear(); + mBinRadius = 0.f; + mBinIndex = -1; + + for(S32 i = 0; i < NUM_DATA_TYPE; i++) + { + mData[i] = NULL; + } +} + +LLViewerOctreeEntry::~LLViewerOctreeEntry() +{ + llassert(!mGroup); +} + +void LLViewerOctreeEntry::addData(LLViewerOctreeEntryData* data) +{ + //llassert(mData[data->getDataType()] == NULL); + llassert(data != NULL); + + mData[data->getDataType()] = data; +} + +void LLViewerOctreeEntry::removeData(LLViewerOctreeEntryData* data) +{ + //llassert(data->getDataType() != LLVOCACHEENTRY); //can not remove VOCache entry + + if(!mData[data->getDataType()]) + { + return; + } + + mData[data->getDataType()] = NULL; + + if(mGroup != NULL && !mData[LLDRAWABLE]) + { + LLviewerOctreeGroup* group = mGroup; + mGroup = NULL; + group->removeFromGroup(data); + + llassert(mBinIndex == -1); + } +} + +//called by group handleDestruction() ONLY when group is destroyed by octree. +void LLViewerOctreeEntry::nullGroup() +{ + mGroup = NULL; +} + +void LLViewerOctreeEntry::setGroup(LLviewerOctreeGroup* group) +{ + if(mGroup == group) + { + return; + } + + if(mGroup) + { + LLviewerOctreeGroup* group = mGroup; + mGroup = NULL; + group->removeFromGroup(this); + + llassert(mBinIndex == -1); + } + + mGroup = group; +} + +//----------------------------------------------------------------------------------- +//class LLViewerOctreeEntryData definitions +//----------------------------------------------------------------------------------- +LLViewerOctreeEntryData::~LLViewerOctreeEntryData() +{ + if(mEntry) + { + mEntry->removeData(this); + } +} + +LLViewerOctreeEntryData::LLViewerOctreeEntryData(LLViewerOctreeEntry::eEntryDataType_t data_type) + : mDataType(data_type), + mEntry(NULL) +{ +} + +//virtual +void LLViewerOctreeEntryData::setOctreeEntry(LLViewerOctreeEntry* entry) +{ + if(mEntry.notNull()) + { + return; + } + + if(!entry) + { + mEntry = new LLViewerOctreeEntry(); + } + else + { + mEntry = entry; + } + mEntry->addData(this); +} + +void LLViewerOctreeEntryData::setSpatialExtents(const LLVector3& min, const LLVector3& max) +{ + mEntry->mExtents[0].load3(min.mV); + mEntry->mExtents[1].load3(max.mV); +} + +void LLViewerOctreeEntryData::setSpatialExtents(const LLVector4a& min, const LLVector4a& max) +{ + mEntry->mExtents[0] = min; + mEntry->mExtents[1] = max; +} + +void LLViewerOctreeEntryData::setPositionGroup(const LLVector4a& pos) +{ + mEntry->mPositionGroup = pos; +} + +const LLVector4a* LLViewerOctreeEntryData::getSpatialExtents() const +{ + return mEntry->getSpatialExtents(); +} + +//virtual +void LLViewerOctreeEntryData::setGroup(LLviewerOctreeGroup* group) +{ + mEntry->setGroup(group); +} + +void LLViewerOctreeEntryData::shift(const LLVector4a &shift_vector) +{ + mEntry->mExtents[0].add(shift_vector); + mEntry->mExtents[1].add(shift_vector); + mEntry->mPositionGroup.add(shift_vector); +} + +LLviewerOctreeGroup* LLViewerOctreeEntryData::getGroup()const +{ + return mEntry.notNull() ? mEntry->mGroup : NULL; +} + +const LLVector4a& LLViewerOctreeEntryData::getPositionGroup() const +{ + return mEntry->getPositionGroup(); +} + +//virtual +bool LLViewerOctreeEntryData::isVisible() const +{ + if(mEntry) + { + return mEntry->mVisible == sCurVisible; + } + return false; +} + +//virtual +bool LLViewerOctreeEntryData::isRecentlyVisible() const +{ + if(!mEntry) + { + return false; + } + + if(isVisible()) + { + return true; + } + if(getGroup() && getGroup()->isRecentlyVisible()) + { + setVisible(); + return true; + } + + return (sCurVisible - mEntry->mVisible < getMinVisFrameRange()); +} + +void LLViewerOctreeEntryData::setVisible() const +{ + if(mEntry) + { + mEntry->mVisible = sCurVisible; + } +} + +//----------------------------------------------------------------------------------- +//class LLviewerOctreeGroup definitions +//----------------------------------------------------------------------------------- + +LLviewerOctreeGroup::~LLviewerOctreeGroup() +{ +} + +LLviewerOctreeGroup::LLviewerOctreeGroup(OctreeNode* node) : + mOctreeNode(node), + mState(CLEAN) +{ + LLVector4a tmp; + tmp.splat(0.f); + mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[0] = mObjectBounds[1] = + mObjectExtents[0] = mObjectExtents[1] = tmp; + + mBounds[0] = node->getCenter(); + mBounds[1] = node->getSize(); + + mOctreeNode->addListener(this); +} + +bool LLviewerOctreeGroup::removeFromGroup(LLViewerOctreeEntryData* data) +{ + return removeFromGroup(data->getEntry()); +} + +bool LLviewerOctreeGroup::removeFromGroup(LLViewerOctreeEntry* entry) +{ + llassert(entry != NULL); + llassert(!entry->getGroup()); + + unbound(); + if (mOctreeNode) + { + if (!mOctreeNode->remove(entry)) + { + OCT_ERRS << "Could not remove LLVOCacheEntry from LLVOCacheOctreeGroup" << llendl; + return false; + } + } + setState(OBJECT_DIRTY); + + return true; +} + +//virtual +void LLviewerOctreeGroup::unbound() +{ + if (isDirty()) + { + return; + } + + setState(DIRTY); + + //all the parent nodes need to rebound this child + if (mOctreeNode) + { + OctreeNode* parent = (OctreeNode*) mOctreeNode->getParent(); + while (parent != NULL) + { + LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) parent->getListener(0); + if (!group || group->isDirty()) + { + return; + } + + group->setState(DIRTY); + parent = (OctreeNode*) parent->getParent(); + } + } +} + +//virtual +void LLviewerOctreeGroup::rebound() +{ + if (!isDirty()) + { + return; + } + + if (mOctreeNode->getChildCount() == 1 && mOctreeNode->getElementCount() == 0) + { + LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) mOctreeNode->getChild(0)->getListener(0); + group->rebound(); + + //copy single child's bounding box + mBounds[0] = group->mBounds[0]; + mBounds[1] = group->mBounds[1]; + mExtents[0] = group->mExtents[0]; + mExtents[1] = group->mExtents[1]; + + group->setState(SKIP_FRUSTUM_CHECK); + } + else if (mOctreeNode->isLeaf()) + { //copy object bounding box if this is a leaf + boundObjects(TRUE, mExtents[0], mExtents[1]); + mBounds[0] = mObjectBounds[0]; + mBounds[1] = mObjectBounds[1]; + } + else + { + LLVector4a& newMin = mExtents[0]; + LLVector4a& newMax = mExtents[1]; + LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) mOctreeNode->getChild(0)->getListener(0); + group->clearState(SKIP_FRUSTUM_CHECK); + group->rebound(); + //initialize to first child + newMin = group->mExtents[0]; + newMax = group->mExtents[1]; + + //first, rebound children + for (U32 i = 1; i < mOctreeNode->getChildCount(); i++) + { + group = (LLviewerOctreeGroup*) mOctreeNode->getChild(i)->getListener(0); + group->clearState(SKIP_FRUSTUM_CHECK); + group->rebound(); + const LLVector4a& max = group->mExtents[1]; + const LLVector4a& min = group->mExtents[0]; + + newMax.setMax(newMax, max); + newMin.setMin(newMin, min); + } + + boundObjects(FALSE, newMin, newMax); + + mBounds[0].setAdd(newMin, newMax); + mBounds[0].mul(0.5f); + mBounds[1].setSub(newMax, newMin); + mBounds[1].mul(0.5f); + } + + clearState(DIRTY); + + return; +} + +//virtual +void LLviewerOctreeGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry* obj) +{ + obj->setGroup(this); + unbound(); + setState(OBJECT_DIRTY); +} + +//virtual +void LLviewerOctreeGroup::handleRemoval(const TreeNode* node, LLViewerOctreeEntry* obj) +{ + obj->setGroup(NULL); + unbound(); + setState(OBJECT_DIRTY); +} + +//virtual +void LLviewerOctreeGroup::handleDestruction(const TreeNode* node) +{ + for (OctreeNode::element_iter i = mOctreeNode->getDataBegin(); i != mOctreeNode->getDataEnd(); ++i) + { + LLViewerOctreeEntry* obj = *i; + if (obj && obj->getGroup() == this) + { + obj->nullGroup(); + } + } +} + +//virtual +void LLviewerOctreeGroup::handleStateChange(const TreeNode* node) +{ + //drop bounding box upon state change + if (mOctreeNode != node) + { + mOctreeNode = (OctreeNode*) node; + } + unbound(); +} + +//virtual +void LLviewerOctreeGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child) +{ + llerrs << "can not access here. It is an abstract class." << llendl; + + //((LLviewerOctreeGroup*)child->getListener(0))->unbound(); +} + +//virtual +void LLviewerOctreeGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNode* child) +{ + unbound(); +} + +LLviewerOctreeGroup* LLviewerOctreeGroup::getParent() +{ + if(!mOctreeNode) + { + return NULL; + } + + OctreeNode* parent = mOctreeNode->getOctParent(); + + if (parent) + { + return (LLviewerOctreeGroup*) parent->getListener(0); + } + + return NULL; +} + +//virtual +bool LLviewerOctreeGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut) +{ + const OctreeNode* node = mOctreeNode; + + if (node->isEmpty()) + { //don't do anything if there are no objects + if (empty && mOctreeNode->getParent()) + { //only root is allowed to be empty + OCT_ERRS << "Empty leaf found in octree." << llendl; + } + return false; + } + + LLVector4a& newMin = mObjectExtents[0]; + LLVector4a& newMax = mObjectExtents[1]; + + if (hasState(OBJECT_DIRTY)) + { //calculate new bounding box + clearState(OBJECT_DIRTY); + + //initialize bounding box to first element + OctreeNode::const_element_iter i = node->getDataBegin(); + LLViewerOctreeEntry* entry = *i; + const LLVector4a* minMax = entry->getSpatialExtents(); + + newMin = minMax[0]; + newMax = minMax[1]; + + for (++i; i != node->getDataEnd(); ++i) + { + entry = *i; + minMax = entry->getSpatialExtents(); + + update_min_max(newMin, newMax, minMax[0]); + update_min_max(newMin, newMax, minMax[1]); + } + + mObjectBounds[0].setAdd(newMin, newMax); + mObjectBounds[0].mul(0.5f); + mObjectBounds[1].setSub(newMax, newMin); + mObjectBounds[1].mul(0.5f); + } + + if (empty) + { + minOut = newMin; + maxOut = newMax; + } + else + { + minOut.setMin(minOut, newMin); + maxOut.setMax(maxOut, newMax); + } + + return TRUE; +} + +//virtual +BOOL LLviewerOctreeGroup::isVisible() const +{ + return TRUE; +} + +//----------------------------------------------------------------------------------- +//class LLViewerOctreeCull definitions +//----------------------------------------------------------------------------------- + +//virtual +bool LLViewerOctreeCull::earlyFail(LLviewerOctreeGroup* group) +{ + return false; +} + +//virtual +void LLViewerOctreeCull::traverse(const OctreeNode* n) +{ + LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) n->getListener(0); + + if (earlyFail(group)) + { + return; + } + + if (mRes == 2 || + (mRes && group->hasState(LLviewerOctreeGroup::SKIP_FRUSTUM_CHECK))) + { //fully in, just add everything + OctreeTraveler::traverse(n); + } + else + { + mRes = frustumCheck(group); + + if (mRes) + { //at least partially in, run on down + OctreeTraveler::traverse(n); + } + + mRes = 0; + } +} + +S32 LLViewerOctreeCull::AABBInFrustumNoFarClipGroupBounds(const LLviewerOctreeGroup* group) +{ + return mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]); +} + +S32 LLViewerOctreeCull::AABBSphereIntersectGroupExtents(const LLviewerOctreeGroup* group) +{ + return AABBSphereIntersect(group->mExtents[0], group->mExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist); +} + +S32 LLViewerOctreeCull::AABBInFrustumNoFarClipObjectBounds(const LLviewerOctreeGroup* group) +{ + return mCamera->AABBInFrustumNoFarClip(group->mObjectBounds[0], group->mObjectBounds[1]); +} + +S32 LLViewerOctreeCull::AABBSphereIntersectObjectExtents(const LLviewerOctreeGroup* group) +{ + return AABBSphereIntersect(group->mObjectExtents[0], group->mObjectExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist); +} + +S32 LLViewerOctreeCull::AABBInFrustumGroupBounds(const LLviewerOctreeGroup* group) +{ + return mCamera->AABBInFrustum(group->mBounds[0], group->mBounds[1]); +} + +S32 LLViewerOctreeCull::AABBInFrustumObjectBounds(const LLviewerOctreeGroup* group) +{ + return mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]); +} + +//virtual +bool LLViewerOctreeCull::checkObjects(const OctreeNode* branch, const LLviewerOctreeGroup* group) +{ + if (branch->getElementCount() == 0) //no elements + { + return false; + } + else if (branch->getChildCount() == 0) //leaf state, already checked tightest bounding box + { + return true; + } + else if (mRes == 1 && !frustumCheckObjects(group)) //no objects in frustum + { + return false; + } + + return true; +} + +//virtual +void LLViewerOctreeCull::preprocess(LLviewerOctreeGroup* group) +{ +} + +//virtual +void LLViewerOctreeCull::processGroup(LLviewerOctreeGroup* group) +{ +} + +//virtual +void LLViewerOctreeCull::visit(const OctreeNode* branch) +{ + LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) branch->getListener(0); + + preprocess(group); + + if (checkObjects(branch, group)) + { + processGroup(group); + } +} + diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h new file mode 100644 index 0000000000..c063e96ea5 --- /dev/null +++ b/indra/newview/llvieweroctree.h @@ -0,0 +1,274 @@ +/** + * @file llvieweroctree.h + * @brief LLViewerObjectOctree.cpp header file, defining all supporting classes. + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, 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$ + */ + +#ifndef LL_VIEWEROCTREE_H +#define LL_VIEWEROCTREE_H + +#include +#include + +#include "v2math.h" +#include "v3math.h" +#include "v4math.h" +#include "m4math.h" +#include "llvector4a.h" +#include "llquaternion.h" +#include "lloctree.h" +#include "llcamera.h" + +class LLViewerOctreeEntryData; +class LLviewerOctreeGroup; +class LLViewerOctreeEntry; + +typedef LLOctreeListener OctreeListener; +typedef LLTreeNode TreeNode; +typedef LLOctreeNode OctreeNode; +typedef LLOctreeRoot OctreeRoot; +typedef LLOctreeTraveler OctreeTraveler; + +S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad); +S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &radius_squared); + +S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad); +S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &radius_squared); + +//defines data needed for octree of an entry +LL_ALIGN_PREFIX(16) +class LLViewerOctreeEntry : public LLRefCount +{ + friend class LLViewerOctreeEntryData; + +public: + typedef enum + { + LLDRAWABLE = 0, + LLVOCACHEENTRY, + NUM_DATA_TYPE + }eEntryDataType_t; + + ~LLViewerOctreeEntry(); +public: + LLViewerOctreeEntry(); + + void nullGroup(); //called by group handleDestruction() only + void setGroup(LLviewerOctreeGroup* group); + void removeData(LLViewerOctreeEntryData* data); + + LLViewerOctreeEntryData* getData(U32 data_type)const {return mData[data_type];} + bool hasData(U32 data_type)const {return mData[data_type] != NULL;} + + LLViewerOctreeEntryData* getDrawable() const {return mData[LLDRAWABLE];} + bool hasDrawable() const {return mData[LLDRAWABLE] != NULL;} + LLViewerOctreeEntryData* getVOCacheEntry() const {return mData[LLVOCACHEENTRY];} + bool hasVOCacheEntry() const {return mData[LLVOCACHEENTRY] != NULL;} + + const LLVector4a* getSpatialExtents() const {return mExtents;} + const LLVector4a& getPositionGroup() const {return mPositionGroup;} + LLviewerOctreeGroup* getGroup()const {return mGroup;} + + F32 getBinRadius() const {return mBinRadius;} + S32 getBinIndex() const {return mBinIndex; } + void setBinIndex(S32 index) const {mBinIndex = index; } + +private: + void addData(LLViewerOctreeEntryData* data); + +private: + LLViewerOctreeEntryData* mData[NUM_DATA_TYPE]; //do not use LLPointer here. + LLviewerOctreeGroup* mGroup; + + //aligned members + LL_ALIGN_16(LLVector4a mExtents[2]); + LL_ALIGN_16(LLVector4a mPositionGroup); + F32 mBinRadius; + mutable S32 mBinIndex; + mutable U32 mVisible; + +} LL_ALIGN_POSTFIX(16); + +//defines an abstract class for entry data +LL_ALIGN_PREFIX(16) +class LLViewerOctreeEntryData : public LLRefCount +{ +protected: + ~LLViewerOctreeEntryData(); + +public: + LLViewerOctreeEntryData(const LLViewerOctreeEntryData& rhs) + { + *this = rhs; + } + LLViewerOctreeEntryData(LLViewerOctreeEntry::eEntryDataType_t data_type); + + LLViewerOctreeEntry::eEntryDataType_t getDataType() const {return mDataType;} + LLViewerOctreeEntry* getEntry() {return mEntry;} + + virtual void setOctreeEntry(LLViewerOctreeEntry* entry); + + virtual S32 getMinVisFrameRange()const = 0; + + F32 getBinRadius() const {return mEntry->getBinRadius();} + const LLVector4a* getSpatialExtents() const; + LLviewerOctreeGroup* getGroup()const; + const LLVector4a& getPositionGroup() const; + + void setBinRadius(F32 rad) {mEntry->mBinRadius = rad;} + void setSpatialExtents(const LLVector3& min, const LLVector3& max); + void setSpatialExtents(const LLVector4a& min, const LLVector4a& max); + void setPositionGroup(const LLVector4a& pos); + + virtual void setGroup(LLviewerOctreeGroup* group); + void shift(const LLVector4a &shift_vector); + + U32 getVisible() const {return mEntry ? mEntry->mVisible : 0;} + void setVisible() const; + virtual bool isVisible() const; + virtual bool isRecentlyVisible() const; + + static S32 getCurrentFrame() { return sCurVisible; } + +protected: + LLVector4a& getGroupPosition() {return mEntry->mPositionGroup;} + void initVisible(U32 visible) {mEntry->mVisible = visible;} + + static void incrementVisible() {sCurVisible++;} +protected: + LLPointer mEntry; + LLViewerOctreeEntry::eEntryDataType_t mDataType; + static U32 sCurVisible; // Counter for what value of mVisible means currently visible +}LL_ALIGN_POSTFIX(16); + + +//defines an octree group for an octree node, which contains multiple entries. +LL_ALIGN_PREFIX(16) +class LLviewerOctreeGroup : public LLOctreeListener +{ + friend class LLViewerOctreeCull; +protected: + ~LLviewerOctreeGroup(); + +public: + enum + { + CLEAN = 0x00000000, + DIRTY = 0x00000001, + OBJECT_DIRTY = 0x00000002, + SKIP_FRUSTUM_CHECK = 0x00000004, + INVALID_STATE = 0x00000008, + }; + +public: + LLviewerOctreeGroup(OctreeNode* node); + LLviewerOctreeGroup(const LLviewerOctreeGroup& rhs) + { + *this = rhs; + } + + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + + bool removeFromGroup(LLViewerOctreeEntryData* data); + bool removeFromGroup(LLViewerOctreeEntry* entry); + + virtual void unbound(); + virtual void rebound(); + + virtual BOOL isVisible() const; + virtual BOOL isRecentlyVisible() const = 0; + + U32 getState() {return mState; } + bool isDirty() const {return mState & DIRTY;} + bool hasState(U32 state) const {return mState & state;} + void setState(U32 state) {mState |= state;} + void clearState(U32 state) {mState &= ~state;} + + //LISTENER FUNCTIONS + virtual void handleInsertion(const TreeNode* node, LLViewerOctreeEntry* obj); + virtual void handleRemoval(const TreeNode* node, LLViewerOctreeEntry* obj); + virtual void handleDestruction(const TreeNode* node); + virtual void handleStateChange(const TreeNode* node); + virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child); + virtual void handleChildRemoval(const OctreeNode* parent, const OctreeNode* child); + + OctreeNode* getOctreeNode() {return mOctreeNode;} + LLviewerOctreeGroup* getParent(); + + const LLVector4a* getBounds() const {return mBounds;} + const LLVector4a* getExtents() const {return mExtents;} + const LLVector4a* getObjectBounds() const {return mObjectBounds;} + const LLVector4a* getObjectExtents() const {return mObjectExtents;} + +private: + virtual bool boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut); + +protected: + U32 mState; + OctreeNode* mOctreeNode; + + LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects) + LL_ALIGN_16(LLVector4a mObjectBounds[2]); // bounding box (center, size) of objects in this node + LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children + LL_ALIGN_16(LLVector4a mObjectExtents[2]); // extents (min, max) of objects in this node + +}LL_ALIGN_POSTFIX(16); + +class LLViewerOctreeCull : public OctreeTraveler +{ +public: + LLViewerOctreeCull(LLCamera* camera) + : mCamera(camera), mRes(0) { } + + virtual bool earlyFail(LLviewerOctreeGroup* group); + virtual void traverse(const OctreeNode* n); + + S32 AABBInFrustumNoFarClipGroupBounds(const LLviewerOctreeGroup* group); + S32 AABBSphereIntersectGroupExtents(const LLviewerOctreeGroup* group); + S32 AABBInFrustumNoFarClipObjectBounds(const LLviewerOctreeGroup* group); + S32 AABBSphereIntersectObjectExtents(const LLviewerOctreeGroup* group); + S32 AABBInFrustumGroupBounds(const LLviewerOctreeGroup* group); + S32 AABBInFrustumObjectBounds(const LLviewerOctreeGroup* group); + + virtual S32 frustumCheck(const LLviewerOctreeGroup* group) = 0; + virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group) = 0; + + virtual bool checkObjects(const OctreeNode* branch, const LLviewerOctreeGroup* group); + virtual void preprocess(LLviewerOctreeGroup* group); + virtual void processGroup(LLviewerOctreeGroup* group); + virtual void visit(const OctreeNode* branch); + +protected: + LLCamera *mCamera; + S32 mRes; +}; + +#endif \ No newline at end of file diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index 6bd9f66b9c..8acdc08b00 100644 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -151,8 +151,8 @@ LLViewerPartGroup::LLViewerPartGroup(const LLVector3 ¢er_agent, const F32 bo if (group != NULL) { - LLVector3 center(group->mOctreeNode->getCenter().getF32ptr()); - LLVector3 size(group->mOctreeNode->getSize().getF32ptr()); + LLVector3 center(group->getOctreeNode()->getCenter().getF32ptr()); + LLVector3 size(group->getOctreeNode()->getSize().getF32ptr()); size += LLVector3(0.01f, 0.01f, 0.01f); mMinObjPos = center - size; mMaxObjPos = center + size; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 31e3820a21..15c95aa30a 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -70,6 +70,7 @@ #include "stringize.h" #include "llviewercontrol.h" #include "llsdserialize.h" +#include "llvieweroctree.h" #ifdef LL_WINDOWS #pragma warning(disable:4355) @@ -133,7 +134,14 @@ public: // Misc LLVLComposition *mCompositionp; // Composition layer for the surface - LLVOCacheEntry::vocache_entry_map_t mCacheMap; + LLVOCacheEntry::vocache_entry_map_t mCacheMap; //all cached entries + LLVOCacheEntry::vocache_entry_set_t mActiveSet; //all active entries; + LLVOCacheEntry::vocache_entry_set_t mWaitingSet; //entries waiting for LLDrawable to be generated. + LLVOCacheEntry::vocache_entry_set_t mVisibleEntries; //visible root entries of a linked set. + std::set< LLPointer > mDummyEntries; //dummy vo cache entries, for LLSpatialBridge use. + std::set< LLSpatialGroup* > mVisibleGroups; //visible llspatialgroup + LLVOCachePartition* mVOCachePartition; + // time? // LRU info? @@ -291,7 +299,8 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, mCacheLoaded(FALSE), mCacheDirty(FALSE), mReleaseNotesRequested(FALSE), - mCapabilitiesReceived(false) + mCapabilitiesReceived(false), + mDead(FALSE) { mWidth = region_width_meters; mImpl->mOriginGlobal = from_region_handle(handle); @@ -323,17 +332,20 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, //create object partitions //MUST MATCH declaration of eObjectPartitions - mImpl->mObjectPartition.push_back(new LLHUDPartition()); //PARTITION_HUD - mImpl->mObjectPartition.push_back(new LLTerrainPartition()); //PARTITION_TERRAIN - mImpl->mObjectPartition.push_back(new LLVoidWaterPartition()); //PARTITION_VOIDWATER - mImpl->mObjectPartition.push_back(new LLWaterPartition()); //PARTITION_WATER - mImpl->mObjectPartition.push_back(new LLTreePartition()); //PARTITION_TREE - mImpl->mObjectPartition.push_back(new LLParticlePartition()); //PARTITION_PARTICLE - mImpl->mObjectPartition.push_back(new LLGrassPartition()); //PARTITION_GRASS - mImpl->mObjectPartition.push_back(new LLVolumePartition()); //PARTITION_VOLUME - mImpl->mObjectPartition.push_back(new LLBridgePartition()); //PARTITION_BRIDGE - mImpl->mObjectPartition.push_back(new LLHUDParticlePartition());//PARTITION_HUD_PARTICLE + mImpl->mObjectPartition.push_back(new LLHUDPartition(this)); //PARTITION_HUD + mImpl->mObjectPartition.push_back(new LLTerrainPartition(this)); //PARTITION_TERRAIN + mImpl->mObjectPartition.push_back(new LLVoidWaterPartition(this)); //PARTITION_VOIDWATER + mImpl->mObjectPartition.push_back(new LLWaterPartition(this)); //PARTITION_WATER + mImpl->mObjectPartition.push_back(new LLTreePartition(this)); //PARTITION_TREE + mImpl->mObjectPartition.push_back(new LLParticlePartition(this)); //PARTITION_PARTICLE + mImpl->mObjectPartition.push_back(new LLGrassPartition(this)); //PARTITION_GRASS + mImpl->mObjectPartition.push_back(new LLVolumePartition(this)); //PARTITION_VOLUME + mImpl->mObjectPartition.push_back(new LLBridgePartition(this)); //PARTITION_BRIDGE + mImpl->mObjectPartition.push_back(new LLHUDParticlePartition(this));//PARTITION_HUD_PARTICLE + mImpl->mObjectPartition.push_back(new LLVOCachePartition(this)); //PARTITION_VO_CACHE mImpl->mObjectPartition.push_back(NULL); //PARTITION_NONE + + mImpl->mVOCachePartition = (LLVOCachePartition*)getSpatialPartition(PARTITION_VO_CACHE); } @@ -354,6 +366,12 @@ void LLViewerRegion::initStats() LLViewerRegion::~LLViewerRegion() { + mDead = TRUE; + mImpl->mActiveSet.clear(); + mImpl->mVisibleEntries.clear(); + mImpl->mVisibleGroups.clear(); + mImpl->mWaitingSet.clear(); + gVLManager.cleanupData(this); // Can't do this on destruction, because the neighbor pointers might be invalid. // This should be reference counted... @@ -437,10 +455,6 @@ void LLViewerRegion::saveObjectCache() mCacheDirty = FALSE; } - for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.begin(); iter != mImpl->mCacheMap.end(); ++iter) - { - delete iter->second; - } mImpl->mCacheMap.clear(); } @@ -718,8 +732,199 @@ void LLViewerRegion::dirtyHeights() } } +void LLViewerRegion::replaceCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry) +{ + LLPointer oct_entry; + U32 state = LLVOCacheEntry::INACTIVE; + + if(old_entry) + { + oct_entry = old_entry->getEntry(); + state = old_entry->getState(); + + while(old_entry->getNumOfChildren() > 0) + { + new_entry->addChild(old_entry->getNextChild()); + } + + killCacheEntry(old_entry); + } + + mImpl->mCacheMap[new_entry->getLocalID()] = new_entry; + if(oct_entry.notNull()) + { + new_entry->setOctreeEntry(oct_entry); + } + + if(state == LLVOCacheEntry::ACTIVE) + { + llassert(new_entry->getEntry()->hasDrawable()); + mImpl->mActiveSet.insert(new_entry); + } + else if(state == LLVOCacheEntry::WAITING) + { + mImpl->mWaitingSet.insert(new_entry); + } + else if(old_entry && oct_entry) + { + addToVOCacheTree(new_entry); + } + new_entry->setState(state); +} + +//physically delete the cache entry +void LLViewerRegion::killCacheEntry(LLVOCacheEntry* entry) +{ + if(!entry) + { + return; + } + + //1, remove from active list and waiting list + if(entry->isState(LLVOCacheEntry::ACTIVE)) + { + mImpl->mActiveSet.erase(entry); + } + else if(entry->isState(LLVOCacheEntry::WAITING)) + { + mImpl->mWaitingSet.erase(entry); + } + + //2, kill LLViewerObject if exists + //this should be done by the rendering pipeline automatically. + + //3, remove from mVOCachePartition + if(entry->isState(LLVOCacheEntry::INACTIVE) && entry->getEntry()) + { + removeFromVOCacheTree(entry); + } + + entry->setState(LLVOCacheEntry::INACTIVE); + //4, remove from mCacheMap, real deletion + mImpl->mCacheMap.erase(entry->getLocalID()); +} + +//physically delete the cache entry +void LLViewerRegion::killCacheEntry(U32 local_id) +{ + killCacheEntry(getCacheEntry(local_id)); +} + +U32 LLViewerRegion::getNumOfActiveCachedObjects() const +{ + return mImpl->mActiveSet.size(); +} + +void LLViewerRegion::addActiveCacheEntry(LLVOCacheEntry* entry) +{ + if(!entry || mDead) + { + return; + } + + if(entry->isState(LLVOCacheEntry::WAITING)) + { + mImpl->mWaitingSet.erase(entry); + } + + entry->setState(LLVOCacheEntry::ACTIVE); + entry->setVisible(); + + llassert(entry->getEntry()->hasDrawable()); + mImpl->mActiveSet.insert(entry); +} + +void LLViewerRegion::removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep) +{ + if(mDead) + { + return; + } + if(entry->isDummy()) + { + mImpl->mDummyEntries.insert(entry); //keep a copy to prevent from being deleted. + addToVOCacheTree(entry); + } + else if(!drawablep->getParent()) //root node + { + addToVOCacheTree(entry); + mImpl->mVisibleEntries.erase(entry); + } + else //child node + { + LLViewerOctreeEntry* parent_oct_entry = drawablep->getParent()->getEntry(); + if(parent_oct_entry && parent_oct_entry->hasVOCacheEntry()) + { + LLVOCacheEntry* parent = (LLVOCacheEntry*)parent_oct_entry->getVOCacheEntry(); + parent->addChild(entry); + } + } + + mImpl->mActiveSet.erase(entry); + mImpl->mWaitingSet.erase(entry); + entry->setState(LLVOCacheEntry::INACTIVE); +} + +void LLViewerRegion::addVisibleGroup(LLSpatialGroup* group) +{ + if(mDead || group->isEmpty() || group->isDead()) + { + return; + } + + mImpl->mVisibleGroups.insert(group); +} + +void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry) +{ + static BOOL vo_cache_culling_enabled = gSavedSettings.getBOOL("ObjectCacheViewCullingEnabled"); + + if(mDead || !entry || !entry->getEntry()) + { + return; + } + llassert(!entry->getGroup()); + + mImpl->mVOCachePartition->addEntry(entry->getEntry()); +} + +void LLViewerRegion::removeFromVOCacheTree(LLVOCacheEntry* entry) +{ + if(mDead || !entry || !entry->getEntry()) + { + return; + } + + mImpl->mVOCachePartition->removeEntry(entry->getEntry()); +} + +//add the visible root entry of a linked set +void LLViewerRegion::addVisibleCacheEntry(LLVOCacheEntry* entry) +{ + if(mDead || !entry || !entry->getNumOfChildren()) + { + return; //no child entries + } + + mImpl->mVisibleEntries.insert(entry); +} + +void LLViewerRegion::clearVisibleGroup(LLSpatialGroup* group) +{ + if(mDead) + { + return; + } + + llassert(!group->getOctreeNode() || group->isEmpty()); + + mImpl->mVisibleGroups.erase(group); +} + BOOL LLViewerRegion::idleUpdate(F32 max_update_time) { + LLTimer update_timer; + // did_update returns TRUE if we did at least one significant update BOOL did_update = mImpl->mLandp->idleUpdate(max_update_time); @@ -729,9 +934,168 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) mParcelOverlay->idleUpdate(); } + if(update_timer.getElapsedTimeF32() > max_update_time) + { + return did_update; + } + + //kill invisible objects + std::vector delete_list; + for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.begin(); + iter != mImpl->mActiveSet.end(); ++iter) + { + if(!(*iter)->isRecentlyVisible()) + { + killObject((*iter), delete_list); + } + } + for(S32 i = 0; i < delete_list.size(); i++) + { + gObjectList.killObject(delete_list[i]->getVObj()); + } + delete_list.clear(); + + bool timeout = false; + S32 new_object_count = 64; //minimum number of new objects to be added + //add childrens of visible objects to the rendering pipeline + for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mVisibleEntries.begin(); iter != mImpl->mVisibleEntries.end();) + { + LLVOCacheEntry* entry = *iter; + LLVOCacheEntry* child = entry->getNextChild(); + while(child != NULL) + { + if(child->isState(LLVOCacheEntry::INACTIVE)) + { + addNewObject(child); + + if(new_object_count-- < 0 && update_timer.getElapsedTimeF32() > max_update_time) + { + timeout = true; + break; + } + } + child = entry->getNextChild(); + } + if(!child) + { + if(entry->isDummy()) + { + mImpl->mDummyEntries.erase(entry); + } + + iter = mImpl->mVisibleEntries.erase(iter); + } + else + { + break; //timeout + } + } + if(timeout) + { + mImpl->mVisibleGroups.clear(); + return did_update; + } + + //add objects in the visible groups to the rendering pipeline + std::set< LLSpatialGroup* >::iterator group_iter = mImpl->mVisibleGroups.begin(); + while(group_iter != mImpl->mVisibleGroups.end()) + { + LLSpatialGroup* group = *group_iter; + if(!group->getOctreeNode() || group->isEmpty()) + { + mImpl->mVisibleGroups.erase(group_iter); + group_iter = mImpl->mVisibleGroups.begin(); + continue; + } + + std::vector entry_list; + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) + { + //group data contents could change during creating new objects, so copy all contents first. + entry_list.push_back(*i); + } + + for(S32 i = 0; i < entry_list.size(); i++) + { + LLViewerOctreeEntry* entry = entry_list[i]; + if(entry && entry->hasVOCacheEntry()) + { + LLVOCacheEntry* vo_entry = (LLVOCacheEntry*)entry->getVOCacheEntry(); + if(vo_entry->isDummy()) + { + addVisibleCacheEntry(vo_entry); //for LLSpatialBridge. + } + else if(vo_entry->isState(LLVOCacheEntry::INACTIVE)) + { + addNewObject(vo_entry); + if(new_object_count-- < 0 && update_timer.getElapsedTimeF32() > max_update_time) + { + timeout = true; + break; + } + } + } + } + entry_list.clear(); + + if(timeout) + { + break; + } + mImpl->mVisibleGroups.erase(group); + group_iter = mImpl->mVisibleGroups.begin(); + } + mImpl->mVisibleGroups.clear(); + return did_update; } +void LLViewerRegion::killObject(LLVOCacheEntry* entry, std::vector& delete_list) +{ + //kill the object. + LLDrawable* drawablep = (LLDrawable*)entry->getEntry()->getDrawable(); + llassert(drawablep); + + if(!drawablep->getParent()) + { + LLViewerObject::const_child_list_t& child_list = drawablep->getVObj()->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); iter++) + { + LLViewerObject* child = *iter; + if(child->mDrawable->isRecentlyVisible()) + { + //set the parent group visible if any of its children visible. + drawablep->getSpatialGroup()->setVisible(); + return; + } + } + delete_list.push_back(drawablep); + } +} + +LLViewerObject* LLViewerRegion::addNewObject(LLVOCacheEntry* entry) +{ + LLViewerObject* obj = NULL; + if(!entry->getEntry()->hasDrawable()) //not added to the rendering pipeline yet + { + //add the object + obj = gObjectList.processObjectUpdateFromCache(entry, this); + if(obj) + { + if(!entry->isState(LLVOCacheEntry::ACTIVE)) + { + mImpl->mWaitingSet.insert(entry); + entry->setState(LLVOCacheEntry::WAITING); + } + } + } + else + { + llerrs << "Object is already created." << llendl; + } + return obj; +} // As above, but forcibly do the update. void LLViewerRegion::forceUpdate() @@ -1191,8 +1555,9 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec { U32 local_id = objectp->getLocalID(); U32 crc = objectp->getCRC(); + eCacheUpdateResult result; - LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL); + LLVOCacheEntry* entry = getCacheEntry(local_id); if (entry) { @@ -1201,41 +1566,79 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec { // Record a hit entry->recordDupe(); - return CACHE_UPDATE_DUPE; + result = CACHE_UPDATE_DUPE; } + else + { + // Update the cache entry + LLPointer new_entry = new LLVOCacheEntry(local_id, crc, dp); + replaceCacheEntry(entry, new_entry); + entry = new_entry; - // Update the cache entry - mImpl->mCacheMap.erase(local_id); - delete entry; + result = CACHE_UPDATE_CHANGED; + } + } + else + { + // we haven't seen this object before + // Create new entry and add to map + result = CACHE_UPDATE_ADDED; + //if (mImpl->mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES) + //{ + // delete mImpl->mCacheMap.begin()->second ; + // mImpl->mCacheMap.erase(mImpl->mCacheMap.begin()); + // result = CACHE_UPDATE_REPLACED; + // + //} entry = new LLVOCacheEntry(local_id, crc, dp); + mImpl->mCacheMap[local_id] = entry; - return CACHE_UPDATE_CHANGED; } - // we haven't seen this object before - - // Create new entry and add to map - eCacheUpdateResult result = CACHE_UPDATE_ADDED; - if (mImpl->mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES) + if(objectp->mDrawable.notNull() && !entry->getEntry()) { - delete mImpl->mCacheMap.begin()->second ; - mImpl->mCacheMap.erase(mImpl->mCacheMap.begin()); - result = CACHE_UPDATE_REPLACED; - + entry->setOctreeEntry(objectp->mDrawable->getEntry()); + } + if(entry->getEntry() && entry->getEntry()->hasDrawable() && entry->isState(LLVOCacheEntry::INACTIVE)) + { + addActiveCacheEntry(entry); } - entry = new LLVOCacheEntry(local_id, crc, dp); - mImpl->mCacheMap[local_id] = entry; return result; } +LLVOCacheEntry* LLViewerRegion::getCacheEntryForOctree(U32 local_id) +{ + static BOOL vo_cache_culling_enabled = gSavedSettings.getBOOL("ObjectCacheViewCullingEnabled"); + + if(!vo_cache_culling_enabled) + { + return NULL; + } + + LLVOCacheEntry* entry = getCacheEntry(local_id); + removeFromVOCacheTree(entry); + + return entry; +} + +LLVOCacheEntry* LLViewerRegion::getCacheEntry(U32 local_id) +{ + LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.find(local_id); + if(iter != mImpl->mCacheMap.end()) + { + return iter->second; + } + return NULL; +} + // Get data packer for this object, if we have cached data // AND the CRC matches. JC LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type) { //llassert(mCacheLoaded); This assert failes often, changing to early-out -- davep, 2010/10/18 - LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL); + LLVOCacheEntry* entry = getCacheEntry(local_id); if (entry) { @@ -1244,20 +1647,21 @@ LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type) { // Record a hit entry->recordHit(); - cache_miss_type = CACHE_MISS_TYPE_NONE; + cache_miss_type = CACHE_MISS_TYPE_NONE; + return entry->getDP(crc); } else { // llinfos << "CRC miss for " << local_id << llendl; - cache_miss_type = CACHE_MISS_TYPE_CRC; + cache_miss_type = CACHE_MISS_TYPE_CRC; mCacheMissCRC.put(local_id); } } else { // llinfos << "Cache miss for " << local_id << llendl; - cache_miss_type = CACHE_MISS_TYPE_FULL; + cache_miss_type = CACHE_MISS_TYPE_FULL; mCacheMissFull.put(local_id); } diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index c9fffaf30e..17654a8bc7 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -66,7 +66,8 @@ class LLDataPacker; class LLDataPackerBinaryBuffer; class LLHost; class LLBBox; - +class LLSpatialGroup; +class LLDrawable; class LLViewerRegionImpl; class LLViewerRegion: public LLCapabilityProvider // implements this interface @@ -85,6 +86,7 @@ public: PARTITION_VOLUME, PARTITION_BRIDGE, PARTITION_HUD_PARTICLE, + PARTITION_VO_CACHE, PARTITION_NONE, NUM_PARTITIONS } eObjectPartitions; @@ -216,6 +218,12 @@ public: F32 getWidth() const { return mWidth; } BOOL idleUpdate(F32 max_update_time); + void addVisibleGroup(LLSpatialGroup* group); + void addVisibleCacheEntry(LLVOCacheEntry* entry); + void addActiveCacheEntry(LLVOCacheEntry* entry); + void removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep); + void killCacheEntry(U32 local_id); //physically delete the cache entry + void clearVisibleGroup(LLSpatialGroup* group); // Like idleUpdate, but forces everything to complete regardless of // how long it takes. @@ -305,7 +313,8 @@ public: } eCacheUpdateResult; // handle a full update message - eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp); + eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp); + LLVOCacheEntry* getCacheEntryForOctree(U32 local_id); LLDataPacker *getDP(U32 local_id, U32 crc, U8 &cache_miss_type); void requestCacheMisses(); void addCacheMissFull(const U32 local_id); @@ -322,6 +331,7 @@ public: virtual std::string getDescription() const; std::string getHttpUrl() const { return mHttpUrl ;} + U32 getNumOfActiveCachedObjects() const; LLSpatialPartition* getSpatialPartition(U32 type); bool objectIsReturnable(const LLVector3& pos, const std::vector& boxes) const; @@ -331,6 +341,15 @@ public: void getNeighboringRegions( std::vector& uniqueRegions ); void getNeighboringRegionsStatus( std::vector& regions ); +private: + void addToVOCacheTree(LLVOCacheEntry* entry); + LLViewerObject* addNewObject(LLVOCacheEntry* entry); + void killObject(LLVOCacheEntry* entry, std::vector& delete_list); + LLVOCacheEntry* getCacheEntry(U32 local_id); + void removeFromVOCacheTree(LLVOCacheEntry* entry); + void replaceCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry); + void killCacheEntry(LLVOCacheEntry* entry); //physically delete the cache entry + public: struct CompareDistance { @@ -408,18 +427,17 @@ private: // Maps local ids to cache entries. // Regions can have order 10,000 objects, so assume // a structure of size 2^14 = 16,000 - BOOL mCacheLoaded; - BOOL mCacheDirty; + BOOL mCacheLoaded; + BOOL mCacheDirty; + BOOL mAlive; // can become false if circuit disconnects + BOOL mCapabilitiesReceived; + BOOL mReleaseNotesRequested; + BOOL mDead; //if true, this region is in the process of deleting. LLDynamicArray mCacheMissFull; LLDynamicArray mCacheMissCRC; - - bool mAlive; // can become false if circuit disconnects - bool mCapabilitiesReceived; - caps_received_signal_t mCapabilitiesReceivedSignal; - - BOOL mReleaseNotesRequested; + caps_received_signal_t mCapabilitiesReceivedSignal; LLSD mSimulatorFeatures; }; diff --git a/indra/newview/llviewerstatsrecorder.cpp b/indra/newview/llviewerstatsrecorder.cpp index 91e485d01b..2d5292b5f3 100644 --- a/indra/newview/llviewerstatsrecorder.cpp +++ b/indra/newview/llviewerstatsrecorder.cpp @@ -220,7 +220,7 @@ void LLViewerStatsRecorder::writeToLog( F32 interval ) } else { - llwarns << "Couldn't open " << STATS_FILE_NAME << " for logging." << llendl; + //llwarns << "Couldn't open " << STATS_FILE_NAME << " for logging." << llendl; return; } } diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index fd892db3d3..a11653b77d 100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -808,8 +808,10 @@ U32 LLVOAvatarSelf::processUpdateMessage(LLMessageSystem *mesgsys, updateMeshTextures(); // unpack the texture UUIDs to the texture slots - retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num); - + if(mesgsys != NULL) + { + retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num); + } // need to trigger a few operations to get the avatar to use the new bakes for (U32 i = 0; i < mBakedTextureDatas.size(); i++) { diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 7db19c5c1b..17e0ef3bdb 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -29,6 +29,8 @@ #include "llerror.h" #include "llregionhandle.h" #include "llviewercontrol.h" +#include "llviewerobjectlist.h" +#include "lldrawable.h" BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes) { @@ -46,12 +48,13 @@ BOOL check_write(LLAPRFile* apr_file, void* src, S32 n_bytes) //--------------------------------------------------------------------------- LLVOCacheEntry::LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp) - : + : LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY), mLocalID(local_id), mCRC(crc), mHitCount(0), mDupeCount(0), - mCRCChangeCount(0) + mCRCChangeCount(0), + mState(INACTIVE) { mBuffer = new U8[dp.getBufferSize()]; mDP.assignBuffer(mBuffer, dp.getBufferSize()); @@ -59,19 +62,22 @@ LLVOCacheEntry::LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer & } LLVOCacheEntry::LLVOCacheEntry() - : + : LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY), mLocalID(0), mCRC(0), mHitCount(0), mDupeCount(0), mCRCChangeCount(0), - mBuffer(NULL) + mBuffer(NULL), + mState(INACTIVE) { mDP.assignBuffer(mBuffer, 0); } LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file) - : mBuffer(NULL) + : LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY), + mBuffer(NULL), + mState(INACTIVE) { S32 size = -1; BOOL success; @@ -138,8 +144,57 @@ LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file) LLVOCacheEntry::~LLVOCacheEntry() { mDP.freeBuffer(); + //llassert(mState == INACTIVE); } +//virtual +void LLVOCacheEntry::setOctreeEntry(LLViewerOctreeEntry* entry) +{ + if(!entry && mDP.getBufferSize() > 0) + { + LLUUID fullid; + mDP.reset(); + mDP.unpackUUID(fullid, "ID"); + mDP.reset(); + + LLViewerObject* obj = gObjectList.findObject(fullid); + if(obj && obj->mDrawable) + { + entry = obj->mDrawable->getEntry(); + } + } + + LLViewerOctreeEntryData::setOctreeEntry(entry); +} + +//virtual +S32 LLVOCacheEntry::getMinVisFrameRange()const +{ + const S32 MIN_RANGE = 128; //frames + + return MIN_RANGE; +} + +void LLVOCacheEntry::addChild(LLVOCacheEntry* entry) +{ + llassert(entry != NULL); + + mChildrenList.push_back(entry); +} + +LLVOCacheEntry* LLVOCacheEntry::getNextChild() +{ + S32 size = mChildrenList.size(); + if(!size) + { + return NULL; + } + + LLVOCacheEntry* entry = mChildrenList[size - 1]; + mChildrenList.pop_back(); //remove the entry; + + return entry; +} // New CRC means the object has changed. void LLVOCacheEntry::assignCRC(U32 crc, LLDataPackerBinaryBuffer &dp) @@ -170,6 +225,16 @@ LLDataPackerBinaryBuffer *LLVOCacheEntry::getDP(U32 crc) return &mDP; } +LLDataPackerBinaryBuffer *LLVOCacheEntry::getDP() +{ + if (mDP.getBufferSize() == 0) + { + //llinfos << "Not getting cache entry, invalid!" << llendl; + return NULL; + } + + return &mDP; +} void LLVOCacheEntry::recordHit() { @@ -625,11 +690,10 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca { for (S32 i = 0; i < num_entries; i++) { - LLVOCacheEntry* entry = new LLVOCacheEntry(&apr_file); + LLPointer entry = new LLVOCacheEntry(&apr_file); if (!entry->getLocalID()) { llwarns << "Aborting cache file load for " << filename << ", cache file corruption!" << llendl; - delete entry ; success = false ; break ; } diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h index 14e3b4c793..85538e8043 100644 --- a/indra/newview/llvocache.h +++ b/indra/newview/llvocache.h @@ -31,34 +31,57 @@ #include "lldatapacker.h" #include "lldlinked.h" #include "lldir.h" - +#include "llvieweroctree.h" //--------------------------------------------------------------------------- // Cache entries class LLVOCacheEntry; -class LLVOCacheEntry +class LLVOCacheEntry : public LLViewerOctreeEntryData { +public: + enum + { + INACTIVE = 0, + WAITING, + ACTIVE + }; + +protected: + ~LLVOCacheEntry(); public: LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp); LLVOCacheEntry(LLAPRFile* apr_file); - LLVOCacheEntry(); - ~LLVOCacheEntry(); + LLVOCacheEntry(); + + void setState(U32 state) {mState = state;} + bool isState(U32 state) {return mState == state;} + U32 getState() const {return mState;} U32 getLocalID() const { return mLocalID; } U32 getCRC() const { return mCRC; } S32 getHitCount() const { return mHitCount; } S32 getCRCChangeCount() const { return mCRCChangeCount; } + S32 getMinVisFrameRange()const; void dump() const; BOOL writeToFile(LLAPRFile* apr_file) const; void assignCRC(U32 crc, LLDataPackerBinaryBuffer &dp); LLDataPackerBinaryBuffer *getDP(U32 crc); + LLDataPackerBinaryBuffer *getDP(); void recordHit(); void recordDupe() { mDupeCount++; } + + /*virtual*/ void setOctreeEntry(LLViewerOctreeEntry* entry); + + void addChild(LLVOCacheEntry* entry); + LLVOCacheEntry* getNextChild(); + S32 getNumOfChildren() {return mChildrenList.size();} + bool isDummy() {return !mBuffer;} public: - typedef std::map vocache_entry_map_t; + typedef std::map > vocache_entry_map_t; + typedef std::set vocache_entry_set_t; protected: U32 mLocalID; @@ -68,6 +91,9 @@ protected: S32 mCRCChangeCount; LLDataPackerBinaryBuffer mDP; U8 *mBuffer; + + U32 mState; + std::vector mChildrenList; //children entries in a linked set. }; // diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index 4dca87652d..d378ed2577 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -603,8 +603,8 @@ U32 LLVOGrass::getPartitionType() const return LLViewerRegion::PARTITION_GRASS; } -LLGrassPartition::LLGrassPartition() -: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB) +LLGrassPartition::LLGrassPartition(LLViewerRegion* regionp) +: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB, regionp) { mDrawableType = LLPipeline::RENDER_TYPE_GRASS; mPartitionType = LLViewerRegion::PARTITION_GRASS; @@ -624,9 +624,9 @@ void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count LLViewerCamera* camera = LLViewerCamera::getInstance(); for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - LLDrawable* drawablep = *i; + LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable(); - if (drawablep->isDead()) + if (!drawablep || drawablep->isDead()) { continue; } @@ -738,8 +738,10 @@ void LLGrassPartition::getGeometry(LLSpatialGroup* group) LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(), //facep->getTexture(), buffer, fullbright); - info->mExtents[0] = group->mObjectExtents[0]; - info->mExtents[1] = group->mObjectExtents[1]; + + const LLVector4a* exts = group->getObjectExtents(); + info->mExtents[0] = exts[0]; + info->mExtents[1] = exts[1]; info->mVSize = vsize; draw_vec.push_back(info); //for alpha sorting diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index fa34a6f1f5..29c78f85f2 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -489,8 +489,8 @@ U32 LLVOPartGroup::getPartitionType() const return LLViewerRegion::PARTITION_PARTICLE; } -LLParticlePartition::LLParticlePartition() -: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB) +LLParticlePartition::LLParticlePartition(LLViewerRegion* regionp) +: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB, regionp) { mRenderPass = LLRenderPass::PASS_ALPHA; mDrawableType = LLPipeline::RENDER_TYPE_PARTICLES; @@ -499,8 +499,8 @@ LLParticlePartition::LLParticlePartition() mLODPeriod = 1; } -LLHUDParticlePartition::LLHUDParticlePartition() : - LLParticlePartition() +LLHUDParticlePartition::LLHUDParticlePartition(LLViewerRegion* regionp) : + LLParticlePartition(regionp) { mDrawableType = LLPipeline::RENDER_TYPE_HUD_PARTICLES; mPartitionType = LLViewerRegion::PARTITION_HUD_PARTICLE; @@ -510,7 +510,7 @@ static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_VBO("Particle VBO"); void LLParticlePartition::rebuildGeom(LLSpatialGroup* group) { - if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY)) + if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY)) { return; } @@ -558,9 +558,9 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co LLViewerCamera* camera = LLViewerCamera::getInstance(); for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - LLDrawable* drawablep = *i; + LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable(); - if (drawablep->isDead()) + if (!drawablep || drawablep->isDead()) { continue; } @@ -699,8 +699,10 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(), //facep->getTexture(), buffer, fullbright); - info->mExtents[0] = group->mObjectExtents[0]; - info->mExtents[1] = group->mObjectExtents[1]; + + const LLVector4a* exts = group->getObjectExtents(); + info->mExtents[0] = exts[0]; + info->mExtents[1] = exts[1]; info->mVSize = vsize; draw_vec.push_back(info); //for alpha sorting diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index cb905d02da..d5b3f2fd14 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -1058,8 +1058,8 @@ U32 LLVOSurfacePatch::getPartitionType() const return LLViewerRegion::PARTITION_TERRAIN; } -LLTerrainPartition::LLTerrainPartition() -: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, GL_DYNAMIC_DRAW_ARB) +LLTerrainPartition::LLTerrainPartition(LLViewerRegion* regionp) +: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, GL_DYNAMIC_DRAW_ARB, regionp) { mOcclusionEnabled = FALSE; mInfiniteFarClip = TRUE; diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 6687ce432f..fe1ef10f7f 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -1290,8 +1290,8 @@ U32 LLVOTree::getPartitionType() const return LLViewerRegion::PARTITION_TREE; } -LLTreePartition::LLTreePartition() -: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB) +LLTreePartition::LLTreePartition(LLViewerRegion* regionp) +: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB, regionp) { mDrawableType = LLPipeline::RENDER_TYPE_TREE; mPartitionType = LLViewerRegion::PARTITION_TREE; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 813fa72cc3..51a3ace61b 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3912,8 +3912,8 @@ U32 LLVOVolume::getPartitionType() const return LLViewerRegion::PARTITION_VOLUME; } -LLVolumePartition::LLVolumePartition() -: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB) +LLVolumePartition::LLVolumePartition(LLViewerRegion* regionp) +: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB, regionp) { mLODPeriod = 32; mDepthMask = FALSE; @@ -3923,8 +3923,8 @@ LLVolumePartition::LLVolumePartition() mBufferUsage = GL_DYNAMIC_DRAW_ARB; } -LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep) -: LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK) +LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep, LLViewerRegion* regionp) +: LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK, regionp) { mDepthMask = FALSE; mLODPeriod = 32; @@ -4146,9 +4146,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) group->mLastUpdateViewAngle = group->mViewAngle; - if (!group->isState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY)) + if (!group->hasState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY)) { - if (group->isState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate) + if (group->hasState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate) { rebuildMesh(group); } @@ -4186,7 +4186,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) group->mSurfaceArea = 0; //cache object box size since it might be used for determining visibility - group->mObjectBoxSize = group->mObjectBounds[1].getLength3().getF32(); + const LLVector4a* bounds = group->getObjectBounds(); + group->mObjectBoxSize = bounds[1].getLength3().getF32(); group->clearDrawMap(); @@ -4213,9 +4214,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) //get all the faces into a list for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { - LLDrawable* drawablep = *drawable_iter; + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) + if (!drawablep || drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) { continue; } @@ -4619,8 +4620,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) //drawables have been rebuilt, clear rebuild status for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { - LLDrawable* drawablep = *drawable_iter; - drawablep->clearState(LLDrawable::REBUILD_ALL); + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); + if(drawablep) + { + drawablep->clearState(LLDrawable::REBUILD_ALL); + } } } @@ -4646,7 +4650,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) { llassert(group); - if (group && group->isState(LLSpatialGroup::MESH_DIRTY) && !group->isState(LLSpatialGroup::GEOM_DIRTY)) + if (group && group->hasState(LLSpatialGroup::MESH_DIRTY) && !group->hasState(LLSpatialGroup::GEOM_DIRTY)) { LLFastTimer ftm(FTM_REBUILD_VOLUME_VB); LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers @@ -4659,9 +4663,9 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { - LLDrawable* drawablep = *drawable_iter; + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) ) + if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) ) { LLVOVolume* vobj = drawablep->getVOVolume(); vobj->preRebuild(); @@ -4727,7 +4731,11 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) llwarns << "Not all mapped vertex buffers are unmapped!" << llendl ; for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { - LLDrawable* drawablep = *drawable_iter; + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); + if(!drawablep) + { + continue; + } for (S32 i = 0; i < drawablep->getNumFaces(); ++i) { LLFace* face = drawablep->getFace(i); @@ -5200,9 +5208,9 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { - LLDrawable* drawablep = *drawable_iter; + LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - if (drawablep->isDead()) + if (!drawablep || drawablep->isDead()) { continue; } @@ -5240,7 +5248,7 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun group->mBufferUsage = usage; } -LLHUDPartition::LLHUDPartition() +LLHUDPartition::LLHUDPartition(LLViewerRegion* regionp) : LLBridgePartition(regionp) { mPartitionType = LLViewerRegion::PARTITION_HUD; mDrawableType = LLPipeline::RENDER_TYPE_HUD; diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index e8a1c3d1d6..50e7ed7bb5 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -298,15 +298,15 @@ U32 LLVOVoidWater::getPartitionType() const return LLViewerRegion::PARTITION_VOIDWATER; } -LLWaterPartition::LLWaterPartition() -: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB) +LLWaterPartition::LLWaterPartition(LLViewerRegion* regionp) +: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB, regionp) { mInfiniteFarClip = TRUE; mDrawableType = LLPipeline::RENDER_TYPE_WATER; mPartitionType = LLViewerRegion::PARTITION_WATER; } -LLVoidWaterPartition::LLVoidWaterPartition() +LLVoidWaterPartition::LLVoidWaterPartition(LLViewerRegion* regionp) : LLWaterPartition(regionp) { mOcclusionEnabled = FALSE; mDrawableType = LLPipeline::RENDER_TYPE_VOIDWATER; diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 9e495c46b1..0a622997f7 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -133,6 +133,9 @@ void LLWorld::destroyClass() { mEdgeWaterObjects[i] = NULL; } + + //make all visible drawbles invisible. + LLDrawable::incrementVisible(); } @@ -599,7 +602,8 @@ void LLWorld::updateVisibilities() if (part) { LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0); - if (LLViewerCamera::getInstance()->AABBInFrustum(group->mBounds[0], group->mBounds[1])) + const LLVector4a* bounds = group->getBounds(); + if (LLViewerCamera::getInstance()->AABBInFrustum(bounds[0], bounds[1])) { mCulledRegionList.erase(curiter); mVisibleRegionList.push_back(regionp); @@ -622,7 +626,8 @@ void LLWorld::updateVisibilities() if (part) { LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0); - if (LLViewerCamera::getInstance()->AABBInFrustum(group->mBounds[0], group->mBounds[1])) + const LLVector4a* bounds = group->getBounds(); + if (LLViewerCamera::getInstance()->AABBInFrustum(bounds[0], bounds[1])) { regionp->calculateCameraDistance(); regionp->getLand().updatePatchVisibilities(gAgent); @@ -644,8 +649,8 @@ void LLWorld::updateVisibilities() void LLWorld::updateRegions(F32 max_update_time) { LLTimer update_timer; - BOOL did_one = FALSE; - + 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) @@ -660,6 +665,13 @@ void LLWorld::updateRegions(F32 max_update_time) did_one = TRUE; } } + + mNumOfActiveCachedObjects = 0; + for (region_list_t::iterator iter = mRegionList.begin(); + iter != mRegionList.end(); ++iter) + { + mNumOfActiveCachedObjects += (*iter)->getNumOfActiveCachedObjects(); + } } void LLWorld::updateParticles() diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index f350009d10..8187142b2b 100644 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -144,6 +144,7 @@ public: U64 getSpaceTimeUSec() const; void getInfo(LLSD& info); + U32 getNumOfActiveCachedObjects() const {return mNumOfActiveCachedObjects;} public: typedef std::list region_list_t; @@ -181,7 +182,7 @@ private: S32 mLastPacketsIn; S32 mLastPacketsOut; S32 mLastPacketsLost; - + U32 mNumOfActiveCachedObjects; U64 mSpaceTimeUSec; BOOL mClassicCloudsEnabled; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 4582de805f..e06577c512 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1378,18 +1378,18 @@ S32 LLPipeline::setLightingDetail(S32 level) return mLightingDetail; } -class LLOctreeDirtyTexture : public LLOctreeTraveler +class LLOctreeDirtyTexture : public OctreeTraveler { public: const std::set& mTextures; LLOctreeDirtyTexture(const std::set& textures) : mTextures(textures) { } - virtual void visit(const LLOctreeNode* node) + virtual void visit(const OctreeNode* node) { LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && !group->isEmpty()) + if (!group->hasState(LLSpatialGroup::GEOM_DIRTY) && !group->isEmpty()) { for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) { @@ -1578,11 +1578,9 @@ void LLPipeline::addPool(LLDrawPool *new_poolp) void LLPipeline::allocDrawable(LLViewerObject *vobj) { - LLDrawable *drawable = new LLDrawable(); + LLDrawable *drawable = new LLDrawable(vobj); vobj->mDrawable = drawable; - drawable->mVObjp = vobj; - //encompass completely sheared objects by taking //the most extreme point possible (<1,1,0.5>) drawable->setRadius(LLVector3(1,1,0.5f).scaleVec(vobj->getScale()).length()); @@ -2006,7 +2004,7 @@ void check_references(LLSpatialGroup* group, LLDrawable* drawable) { for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - if (drawable == *i) + if (drawable == (LLDrawable*)(*i)->getDrawable()) { llerrs << "LLDrawable deleted while actively reference by LLPipeline." << llendl; } @@ -2028,8 +2026,11 @@ void check_references(LLSpatialGroup* group, LLFace* face) { for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - LLDrawable* drawable = *i; - check_references(drawable, face); + LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); + if(drawable) + { + check_references(drawable, face); + } } } @@ -2351,6 +2352,10 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl { part->cull(camera); } + else if(part->mPartitionType == LLViewerRegion::PARTITION_VO_CACHE) + { + part->cull(camera); + } } } } @@ -2420,15 +2425,20 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) return; } + const LLVector4a* bounds = group->getBounds(); if (sMinRenderSize > 0.f && - llmax(llmax(group->mBounds[1][0], group->mBounds[1][1]), group->mBounds[1][2]) < sMinRenderSize) + llmax(llmax(bounds[1][0], bounds[1][1]), bounds[1][2]) < sMinRenderSize) { return; } assertInitialized(); - if (!group->mSpatialPartition->mRenderByGroup) + if(group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_VO_CACHE) + { + group->mSpatialPartition->mRegionp->addVisibleGroup(group); + } + else if (!group->mSpatialPartition->mRenderByGroup) { //render by drawable sCull->pushDrawableGroup(group); } @@ -2980,14 +2990,14 @@ void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) if (priority) { - if (!group->isState(LLSpatialGroup::IN_BUILD_Q1)) + if (!group->hasState(LLSpatialGroup::IN_BUILD_Q1)) { llassert_always(!mGroupQ1Locked); mGroupQ1.push_back(group); group->setState(LLSpatialGroup::IN_BUILD_Q1); - if (group->isState(LLSpatialGroup::IN_BUILD_Q2)) + if (group->hasState(LLSpatialGroup::IN_BUILD_Q2)) { LLSpatialGroup::sg_vector_t::iterator iter = std::find(mGroupQ2.begin(), mGroupQ2.end(), group); if (iter != mGroupQ2.end()) @@ -2998,7 +3008,7 @@ void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) } } } - else if (!group->isState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1)) + else if (!group->hasState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1)) { llassert_always(!mGroupQ2Locked); mGroupQ2.push_back(group); @@ -3073,7 +3083,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) group->setVisible(); for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - markVisible(*i, camera); + markVisible((LLDrawable*)(*i)->getDrawable(), camera); } if (!sDelayVBUpdate) @@ -3160,8 +3170,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) { for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - LLDrawable* drawablep = *i; - stateSort(drawablep, camera); + stateSort((LLDrawable*)(*i)->getDrawable(), camera); } if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) @@ -3280,7 +3289,10 @@ void forAllDrawables(LLCullResult::sg_iterator begin, { for (LLSpatialGroup::element_iter j = (*i)->getDataBegin(); j != (*i)->getDataEnd(); ++j) { - func(*j); + if((*j)->hasDrawable()) + { + func((LLDrawable*)(*j)->getDrawable()); + } } } } @@ -3508,7 +3520,7 @@ void LLPipeline::postSort(LLCamera& camera) continue; } - if (group->isState(LLSpatialGroup::NEW_DRAWINFO) && group->isState(LLSpatialGroup::GEOM_DIRTY)) + if (group->hasState(LLSpatialGroup::NEW_DRAWINFO) && group->hasState(LLSpatialGroup::GEOM_DIRTY)) { //no way this group is going to be drawable without a rebuild group->rebuildGeom(); } -- cgit v1.3 From a52d203a4f1d2988e8ffba16258f3f132f22f56d Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 17 Oct 2012 20:00:07 -0700 Subject: SH-3405 WIP convert existing stats to lltrace system started conversion of llviewerassetstats removed old, dead LLViewerStats code made units tracing require units declaration clean up of units handling --- indra/llcommon/lltrace.h | 44 +++---- indra/llcommon/lltracerecording.h | 95 ++++++++++++--- indra/llcommon/llunit.h | 34 ++++-- indra/llui/llstatbar.cpp | 3 +- indra/llui/llstatbar.h | 2 +- indra/llui/llstatgraph.h | 10 +- indra/newview/llagent.cpp | 2 - indra/newview/llappviewer.cpp | 5 +- indra/newview/llappviewer.h | 3 +- indra/newview/llcompilequeue.cpp | 2 - indra/newview/llfloaterjoystick.cpp | 2 +- indra/newview/llfloaterregioninfo.cpp | 2 - indra/newview/llfloatersnapshot.cpp | 1 - indra/newview/llgesturemgr.cpp | 2 - indra/newview/lllandmarklist.cpp | 1 - indra/newview/llnearbychatbar.cpp | 1 - indra/newview/llpanelface.cpp | 1 - indra/newview/llpanelpermissions.cpp | 1 - indra/newview/llpreviewgesture.cpp | 2 - indra/newview/llpreviewnotecard.cpp | 2 - indra/newview/llpreviewscript.cpp | 6 - indra/newview/llselectmgr.cpp | 1 - indra/newview/llsidepaneltaskinfo.cpp | 1 - indra/newview/llspatialpartition.cpp | 4 +- indra/newview/llstartup.cpp | 1 - indra/newview/lltexlayer.cpp | 1 - indra/newview/lltextureview.cpp | 6 +- indra/newview/lltooldraganddrop.cpp | 3 - indra/newview/lltoolplacer.cpp | 1 - indra/newview/llviewerassetstats.cpp | 27 +++++ indra/newview/llviewerassetstats.h | 7 ++ indra/newview/llviewerdisplay.cpp | 4 +- indra/newview/llviewerjoystick.cpp | 6 +- indra/newview/llviewermenufile.cpp | 9 -- indra/newview/llviewermessage.cpp | 155 ++---------------------- indra/newview/llviewerobject.cpp | 1 - indra/newview/llviewerobjectlist.cpp | 4 - indra/newview/llviewerstats.cpp | 95 +++++---------- indra/newview/llviewerstats.h | 8 +- indra/newview/llviewertexturelist.cpp | 6 +- indra/newview/llviewerwindow.cpp | 12 +- indra/newview/llvoavatar.cpp | 4 +- indra/newview/llvoavatarself.cpp | 13 +- indra/newview/llwearablelist.cpp | 1 - indra/newview/pipeline.cpp | 16 +-- indra/newview/tests/llviewerassetstats_test.cpp | 13 +- 46 files changed, 255 insertions(+), 365 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 1c6726605a..2a479b31d7 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -192,10 +192,12 @@ namespace LLTrace template class LL_COMMON_API TraceType + : public LLInstanceTracker, std::string> { public: TraceType(const char* name, const char* description = NULL) - : mName(name), + : LLInstanceTracker(name), + mName(name), mDescription(description ? description : "") { mAccumulatorIndex = AccumulatorBuffer::getDefaultBuffer().reserveSlot(); @@ -355,18 +357,17 @@ namespace LLTrace U32 mNumSamples; }; + typedef TraceType > measurement_common_t; + template class LL_COMMON_API Measurement - : public TraceType >, - public LLInstanceTracker, std::string> + : public TraceType > { public: typedef T storage_t; - typedef T base_unit_t; Measurement(const char* name, const char* description = NULL) - : TraceType(name), - LLInstanceTracker(name) + : TraceType(name, description) {} void sample(T value) @@ -376,37 +377,37 @@ namespace LLTrace }; template - class LL_COMMON_API Measurement - : public Measurement + class LL_COMMON_API Measurement + : public TraceType > { public: typedef typename T::storage_t storage_t; - typedef typename T::base_unit_t base_unit_t; typedef Measurement base_measurement_t; Measurement(const char* name, const char* description = NULL) - : Measurement(name, description) + : TraceType(name, description) {} template void sample(UNIT_T value) { - base_measurement_t::sample(((T)value).value()); + T converted_value; + converted_value.assignFrom(value); + getPrimaryAccumulator().sample(converted_value.value()); } }; + typedef TraceType > count_common_t; + template class LL_COMMON_API Count - : public TraceType >, - public LLInstanceTracker, std::string> + : public TraceType > { public: typedef T storage_t; - typedef T base_unit_t; Count(const char* name, const char* description = NULL) - : TraceType(name), - LLInstanceTracker(name) + : TraceType(name) {} void add(T value) @@ -416,22 +417,23 @@ namespace LLTrace }; template - class LL_COMMON_API Count - : public Count + class LL_COMMON_API Count + : public TraceType > { public: typedef typename T::storage_t storage_t; - typedef typename T::base_unit_t base_unit_t; typedef Count base_count_t; Count(const char* name, const char* description = NULL) - : Count(name) + : TraceType(name) {} template void add(UNIT_T value) { - base_count_t::add(((T)value).value()); + T converted_value; + converted_value.assignFrom(value); + getPrimaryAccumulator().add(converted_value.value()); } }; diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index 5e7b0752c6..25f4f5c721 100644 --- a/indra/llcommon/lltracerecording.h +++ b/indra/llcommon/lltracerecording.h @@ -112,64 +112,121 @@ namespace LLTrace void update(); // Count accessors + template + T getSum(const TraceType >& stat) const + { + return (T)stat.getAccumulator(mCounts).getSum(); + } + template - typename Count::base_unit_t getSum(const Count& stat) const + T getSum(const Count& stat) const + { + return (T)stat.getAccumulator(mCounts).getSum(); + } + + template + T getPerSec(const TraceType >& stat) const { - return (typename Count::base_unit_t)stat.getAccumulator(mCounts).getSum(); + return (T)stat.getAccumulator(mCounts).getSum() / mElapsedSeconds; } template - typename Count::base_unit_t getPerSec(const Count& stat) const + T getPerSec(const Count& stat) const { - return (typename Count::base_unit_t)stat.getAccumulator(mCounts).getSum() / mElapsedSeconds; + return (T)stat.getAccumulator(mCounts).getSum() / mElapsedSeconds; } // Measurement accessors + template + T getSum(const TraceType >& stat) const + { + return (T)stat.getAccumulator(mMeasurements).getSum(); + + } + template - typename Measurement::base_unit_t getSum(const Measurement& stat) const + T getSum(const Measurement& stat) const { - return (typename Measurement::base_unit_t)stat.getAccumulator(mMeasurements).getSum(); + return (T)stat.getAccumulator(mMeasurements).getSum(); + + } + template + T getPerSec(const TraceType >& stat) const + { + return (T)stat.getAccumulator(mMeasurements).getSum() / mElapsedSeconds; } template - typename Measurement::base_unit_t getPerSec(const Measurement& stat) const + T getPerSec(const Measurement& stat) const { return (typename Count::base_unit_t)stat.getAccumulator(mMeasurements).getSum() / mElapsedSeconds; } - template - typename Measurement::base_unit_t getMin(const Measurement& stat) const + template + T getMin(const TraceType >& stat) const { - return (typename Measurement::base_unit_t)stat.getAccumulator(mMeasurements).getMin(); + return (T)stat.getAccumulator(mMeasurements).getMin(); } template - typename Measurement::base_unit_t getMax(const Measurement& stat) const + T getMin(const Measurement& stat) const { - return (typename Measurement::base_unit_t)stat.getAccumulator(mMeasurements).getMax(); + return (T)stat.getAccumulator(mMeasurements).getMin(); + } + + + template + T getMax(const TraceType >& stat) const + { + return (T)stat.getAccumulator(mMeasurements).getMax(); } template - typename Measurement::base_unit_t getMean(Measurement& stat) const + T getMax(const Measurement& stat) const + { + return (T)stat.getAccumulator(mMeasurements).getMax(); + } + + template + T getMean(const TraceType >& stat) const { - return (typename Measurement::base_unit_t)stat.getAccumulator(mMeasurements).getMean(); + return (T)stat.getAccumulator(mMeasurements).getMean(); } template - typename Measurement::base_unit_t getStandardDeviation(const Measurement& stat) const + T getMean(Measurement& stat) const + { + return (T)stat.getAccumulator(mMeasurements).getMean(); + } + + template + T getStandardDeviation(const TraceType >& stat) const { - return (typename Measurement::base_unit_t)stat.getAccumulator(mMeasurements).getStandardDeviation(); + return (T)stat.getAccumulator(mMeasurements).getStandardDeviation(); } template - typename Measurement::base_unit_t getLastValue(const Measurement& stat) const + T getStandardDeviation(const Measurement& stat) const { - return (typename Measurement::base_unit_t)stat.getAccumulator(mMeasurements).getLastValue(); + return (T)stat.getAccumulator(mMeasurements).getStandardDeviation(); + } + + template + T getLastValue(const TraceType >& stat) const + { + return (T)stat.getAccumulator(mMeasurements).getLastValue(); } template - U32 getSampleCount(const Measurement& stat) const + T getLastValue(const Measurement& stat) const + { + return (T)stat.getAccumulator(mMeasurements).getLastValue(); + } + + + template + U32 getSampleCount(const TraceType >& stat) const { return stat.getAccumulator(mMeasurements).getSampleCount(); } diff --git a/indra/llcommon/llunit.h b/indra/llcommon/llunit.h index d980989c91..e778383959 100644 --- a/indra/llcommon/llunit.h +++ b/indra/llcommon/llunit.h @@ -36,7 +36,7 @@ struct LLUnitType : public BASE_UNIT typedef DERIVED_UNIT unit_t; typedef typename STORAGE_TYPE storage_t; - typedef void is_unit_t; + typedef void is_unit_tag_t; LLUnitType() {} @@ -57,7 +57,7 @@ struct LLUnitType : public BASE_UNIT } template - storage_t value() const + storage_t as() const { return CONVERTED_TYPE(*this).value(); } @@ -80,8 +80,7 @@ struct LLUnitType { typedef T unit_t; typedef STORAGE_TYPE storage_t; - typedef void is_unit_t; - typedef T base_unit_t; + typedef void is_unit_tag_t; LLUnitType() : mBaseValue() @@ -105,6 +104,13 @@ struct LLUnitType storage_t value() const { return mBaseValue; } + template + storage_t as() const + { + return CONVERTED_TYPE(*this).value(); + } + + static storage_t convertToBase(storage_t derived_value) { return (storage_t)derived_value; @@ -354,10 +360,16 @@ bool operator != (LLUnitType first, LLUni template \ unit_name(LLUnitType, SOURCE_TYPE> source) \ { \ - setBaseValue((storage_t)source.unit_name::unit_t::value()); \ + assignFrom(source); \ } \ \ - }; + template \ + void assignFrom(LLUnitType, SOURCE_TYPE> source) \ + { \ + setBaseValue((storage_t)source.unit_name::unit_t::value()); \ + } \ + \ + }; \ #define LL_DECLARE_DERIVED_UNIT(base_unit, derived_unit, conversion_factor) \ template \ @@ -372,12 +384,18 @@ bool operator != (LLUnitType first, LLUni template \ derived_unit(LLUnitType, SOURCE_TYPE> source) \ { \ - setBaseValue((storage_t)source.base_unit::unit_t::value()); \ + assignFrom(source); \ + } \ + \ + template \ + void assignFrom(LLUnitType, SOURCE_TYPE> source) \ + { \ + setBaseValue((storage_t)source.base_unit::unit_t::value()); \ } \ \ static F32 conversionToBaseFactor() { return (F32)(conversion_factor); } \ \ - }; + }; \ namespace LLUnit { diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp index c60e5431ae..535c6f96e3 100644 --- a/indra/llui/llstatbar.cpp +++ b/indra/llui/llstatbar.cpp @@ -56,8 +56,7 @@ LLStatBar::LLStatBar(const Params& p) mDisplayBar(p.show_bar), mDisplayHistory(p.show_history), mDisplayMean(p.show_mean) -{ -} +{} BOOL LLStatBar::handleMouseDown(S32 x, S32 y, MASK mask) { diff --git a/indra/llui/llstatbar.h b/indra/llui/llstatbar.h index e4b0c61c42..d510f0e3fe 100644 --- a/indra/llui/llstatbar.h +++ b/indra/llui/llstatbar.h @@ -99,7 +99,7 @@ private: LLTrace::PeriodicRecording* mFrameRecording; LLStat* mStatp; - LLTrace::Count<>* mNewStatp; + LLTrace::count_common_t* mNewStatp; LLFrameTimer mUpdateTimer; LLUIString mLabel; diff --git a/indra/llui/llstatgraph.h b/indra/llui/llstatgraph.h index 5bbd9e9d24..b20966d608 100644 --- a/indra/llui/llstatgraph.h +++ b/indra/llui/llstatgraph.h @@ -59,9 +59,9 @@ public: struct StatParams : public LLInitParam::ChoiceBlock { - Alternative legacy_stat; - Alternative* > count_stat; - Alternative* > measurement_stat; + Alternative legacy_stat; + Alternative count_stat; + Alternative measurement_stat; }; struct Params : public LLInitParam::Block @@ -106,8 +106,8 @@ public: /*virtual*/ void setValue(const LLSD& value); private: - LLStat* mStatp; - LLTrace::Count<>* mNewStatp; + LLStat* mStatp; + LLTrace::count_common_t* mNewStatp; BOOL mPerSec; diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index a41efbe0b2..ac33f09718 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -754,7 +754,6 @@ void LLAgent::setFlying(BOOL fly) if( !was_flying ) { LLStatViewer::FLY.add(1); - //LLViewerStats::getInstance()->incStat(LLViewerStats::ST_FLY_COUNT); } setControlFlags(AGENT_CONTROL_FLY); } @@ -3811,7 +3810,6 @@ bool LLAgent::teleportCore(bool is_local) // local logic LLStatViewer::TELEPORT.add(1); - //LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TELEPORT_COUNT); if (is_local) { gAgent.setTeleportState( LLAgent::TELEPORT_LOCAL ); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 6e0b298b2a..4ab0e3336a 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -277,7 +277,7 @@ LLPumpIO* gServicePump = NULL; U64 gFrameTime = 0; F32 gFrameTimeSeconds = 0.f; -F32 gFrameIntervalSeconds = 0.f; +LLUnit::Seconds gFrameIntervalSeconds = 0.f; F32 gFPSClamped = 10.f; // Pretend we start at target rate. F32 gFrameDTClamped = 0.f; // Time between adjacent checks to network for packets U64 gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds @@ -1395,7 +1395,7 @@ bool LLAppViewer::mainLoop() { S32 work_pending = 0; S32 io_pending = 0; - F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f); + F32 max_time = llmin(gFrameIntervalSeconds.value() *10.f, 1.f); { LLFastTimer ftm(FTM_TEXTURE_CACHE); @@ -4811,7 +4811,6 @@ void LLAppViewer::idleNetwork() } } LLStatViewer::NUM_NEW_OBJECTS.sample(gObjectList.mNumNewObjects); - //LLViewerStats::getInstance()->mNumNewObjectsStat.addValue(gObjectList.mNumNewObjects); // Retransmit unacknowledged packets. gXferManager->retransmitUnackedPackets(); diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index cdf4426469..d9d888c626 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -31,6 +31,7 @@ #include "llcontrol.h" #include "llsys.h" // for LLOSInfo #include "lltimer.h" +#include "llunit.h" class LLCommandLineParser; class LLFrameTimer; @@ -321,7 +322,7 @@ extern LLPumpIO* gServicePump; extern U64 gFrameTime; // The timestamp of the most-recently-processed frame extern F32 gFrameTimeSeconds; // Loses msec precision after ~4.5 hours... -extern F32 gFrameIntervalSeconds; // Elapsed time between current and previous gFrameTimeSeconds +extern LLUnit::Seconds gFrameIntervalSeconds; // Elapsed time between current and previous gFrameTimeSeconds extern F32 gFPSClamped; // Frames per second, smoothed, weighted toward last frame extern F32 gFrameDTClamped; extern U64 gStartTime; diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp index 6739910c38..033c8f4865 100644 --- a/indra/newview/llcompilequeue.cpp +++ b/indra/newview/llcompilequeue.cpp @@ -436,8 +436,6 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id, } else { - //LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); - if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ) { LLSD args; diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp index d0c22d25f2..f7b2670b8e 100644 --- a/indra/newview/llfloaterjoystick.cpp +++ b/indra/newview/llfloaterjoystick.cpp @@ -61,7 +61,7 @@ void LLFloaterJoystick::draw() for (U32 i = 0; i < 6; i++) { F32 value = joystick->getJoystickAxis(i); - mAxisStats[i]->addValue(value * gFrameIntervalSeconds); + mAxisStats[i]->addValue(value * gFrameIntervalSeconds.value()); if (mAxisStatsBar[i]) { F32 minbar, maxbar; diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 8234841966..6cce013105 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -2491,8 +2491,6 @@ void LLPanelEstateCovenant::onLoadComplete(LLVFS *vfs, } else { - //LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); - if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || LL_ERR_FILE_EMPTY == status) { diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 4a58e0186c..0d90037e7b 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -993,7 +993,6 @@ void LLSnapshotLivePreview::saveTexture() } LLStatViewer::SNAPSHOT.add(1); - //LLViewerStats::getInstance()->incStat(LLViewerStats::ST_SNAPSHOT_COUNT ); mDataSize = 0; } diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index 63ef8c3d21..27a29d3ace 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -1137,8 +1137,6 @@ void LLGestureMgr::onLoadComplete(LLVFS *vfs, } else { - //LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); - if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || LL_ERR_FILE_EMPTY == status) { diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp index 1666425cbe..2a131eff58 100644 --- a/indra/newview/lllandmarklist.cpp +++ b/indra/newview/lllandmarklist.cpp @@ -141,7 +141,6 @@ void LLLandmarkList::processGetAssetReply( } else { - //LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); // SJB: No use case for a notification here. Use lldebugs instead if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ) { diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index 0aced5c575..23cbfae044 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -639,7 +639,6 @@ void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 gAgent.sendReliableMessage(); LLStatViewer::CHAT_COUNT.add(1); - //LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT); } class LLChatCommandHandler : public LLCommandHandler diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 52ed24f06d..39ded21183 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1050,7 +1050,6 @@ BOOL LLPanelFace::onDragTexture(LLUICtrl*, LLInventoryItem* item) void LLPanelFace::onCommitTexture( const LLSD& data ) { LLStatViewer::EDIT_TEXTURE.add(1); - //LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); sendTexture(); } diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index 51ab7649a4..8027783bd8 100644 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -915,7 +915,6 @@ bool callback_deed_to_group(const LLSD& notification, const LLSD& response) if(group_id.notNull() && groups_identical && (gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED))) { LLSelectMgr::getInstance()->sendOwner(LLUUID::null, group_id, FALSE); -// LLViewerStats::getInstance()->incStat(LLViewerStats::ST_RELEASE_COUNT); } } return false; diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index 4082d272f2..cbb4d5f964 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -883,8 +883,6 @@ void LLPreviewGesture::onLoadComplete(LLVFS *vfs, } else { - //LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); - if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || LL_ERR_FILE_EMPTY == status) { diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index b93b97f1e0..97c9de4b72 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -339,8 +339,6 @@ void LLPreviewNotecard::onLoadComplete(LLVFS *vfs, } else { - //LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); - if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || LL_ERR_FILE_EMPTY == status) { diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 059d5d4061..7607df5a55 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -943,7 +943,6 @@ void LLScriptEdCore::onBtnInsertFunction(LLUICtrl *ui, void* userdata) void LLScriptEdCore::doSave( BOOL close_after_save ) { LLStatViewer::LSL_SAVES.add(1); - //LLViewerStats::getInstance()->incStat( LLViewerStats::ST_LSL_SAVE_COUNT ); if( mSaveCallback ) { @@ -1148,7 +1147,6 @@ void LLScriptEdCore::onBtnLoadFromFile( void* data ) void LLScriptEdCore::onBtnSaveToFile( void* userdata ) { LLStatViewer::LSL_SAVES.add(1); - //LLViewerStats::getInstance()->incStat( LLViewerStats::ST_LSL_SAVE_COUNT ); LLScriptEdCore* self = (LLScriptEdCore*) userdata; @@ -1671,8 +1669,6 @@ void LLPreviewLSL::onLoadComplete( LLVFS *vfs, const LLUUID& asset_uuid, LLAsset } else { - //LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); - if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || LL_ERR_FILE_EMPTY == status) { @@ -1903,8 +1899,6 @@ void LLLiveLSLEditor::onLoadComplete(LLVFS *vfs, const LLUUID& asset_id, } else { - //LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); - if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || LL_ERR_FILE_EMPTY == status) { diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index fd03d7c0be..36ce7bb60e 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1551,7 +1551,6 @@ void LLObjectSelection::applyNoCopyTextureToTEs(LLViewerInventoryItem* item) // apply texture for the selected faces LLStatViewer::EDIT_TEXTURE.add(1); - //LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); object->setTEImage(te, image); dialog_refresh_all(); diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp index c351b1a128..8fb56eb6d8 100644 --- a/indra/newview/llsidepaneltaskinfo.cpp +++ b/indra/newview/llsidepaneltaskinfo.cpp @@ -945,7 +945,6 @@ static bool callback_deed_to_group(const LLSD& notification, const LLSD& respons if (group_id.notNull() && groups_identical && (gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED))) { LLSelectMgr::getInstance()->sendOwner(LLUUID::null, group_id, FALSE); -// LLViewerStats::getInstance()->incStat(LLViewerStats::ST_RELEASE_COUNT); } } return FALSE; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 5083478392..c4c9b0bd4c 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -1580,7 +1580,7 @@ void LLSpatialGroup::checkOcclusion() LLFastTimer t(FTM_OCCLUSION_WAIT); while (!available && max_loop-- > 0) { - F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f); + F32 max_time = llmin(gFrameIntervalSeconds.value()*10.f, 1.f); //do some usefu work while we wait LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread @@ -2574,7 +2574,7 @@ void renderOctree(LLSpatialGroup* group) LLVector4 col; if (group->mBuilt > 0.f) { - group->mBuilt -= 2.f * gFrameIntervalSeconds; + group->mBuilt -= 2.f * gFrameIntervalSeconds.value(); if (group->mBufferUsage == GL_STATIC_DRAW_ARB) { col.setVec(1.0f, 0, 0, group->mBuilt*0.5f); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index cb3c90ea2a..bf47bd44c3 100755 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -2072,7 +2072,6 @@ bool idle_startup() { LLNotificationsUtil::add("ClothingLoading"); LLStatViewer::LOADING_WEARABLES_LONG_DELAY.add(1); - //LLViewerStats::getInstance()->incStat(LLViewerStats::ST_WEARABLES_TOO_LONG); LLStartUp::setStartupState( STATE_CLEANUP ); return TRUE; } diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index e354a5c59d..909745c5b6 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -461,7 +461,6 @@ void LLTexLayerSetBuffer::doUpload() { llinfos << "Uploading baked " << mTexLayerSet->getBodyRegionName() << llendl; LLStatViewer::TEX_BAKES.add(1); - //LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_BAKES); // Don't need caches since we're baked now. (note: we won't *really* be baked // until this image is sent to the server and the Avatar Appearance message is received.) diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index a88233e120..d734620f10 100755 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -512,8 +512,8 @@ void LLGLTexMemBar::draw() F32 cache_max_usage = (F32)LLTrace::Megabytes(LLAppViewer::getTextureCache()->getMaxUsage()).value() ; S32 line_height = LLFontGL::getFontMonospace()->getLineHeight(); S32 v_offset = 0;//(S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f); - F32 total_texture_downloaded = (F32)gTotalTextureBytes / (1024 * 1024); - F32 total_object_downloaded = (F32)gTotalObjectBytes / (1024 * 1024); + LLUnit::Megabytes total_texture_downloaded = gTotalTextureData; + LLUnit::Megabytes total_object_downloaded = gTotalObjectData; U32 total_http_requests = LLAppViewer::getTextureFetch()->getCurlRequest().getTotalIssuedRequests() ; //---------------------------------------------------------------------------- LLGLSUIDefault gls_ui; @@ -537,7 +537,7 @@ void LLGLTexMemBar::draw() text_color, LLFontGL::LEFT, LLFontGL::TOP); text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d", - total_texture_downloaded, total_object_downloaded, total_http_requests); + total_texture_downloaded.value(), total_object_downloaded.value(), total_http_requests); //, cache_entries, cache_max_entries LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3, text_color, LLFontGL::LEFT, LLFontGL::TOP); diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 791da59a1a..652847aac9 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1063,7 +1063,6 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj, } LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); LLStatViewer::EDIT_TEXTURE.add(1); - //LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); S32 num_faces = hit_obj->getNumTEs(); for( S32 face = 0; face < num_faces; face++ ) { @@ -1132,7 +1131,6 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, // update viewer side image in anticipation of update from simulator LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); LLStatViewer::EDIT_TEXTURE.add(1); - //LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); hit_obj->setTEImage(hit_face, image); dialog_refresh_all(); @@ -1357,7 +1355,6 @@ void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target, effectp->setColor(LLColor4U(gAgent.getEffectColor())); LLStatViewer::OBJECT_REZ.add(1); - //LLViewerStats::getInstance()->incStat(LLViewerStats::ST_REZ_COUNT); } void LLToolDragAndDrop::dropInventory(LLViewerObject* hit_obj, diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp index cf5a6e3762..329249eee8 100644 --- a/indra/newview/lltoolplacer.cpp +++ b/indra/newview/lltoolplacer.cpp @@ -434,7 +434,6 @@ BOOL LLToolPlacer::addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics ) effectp->setColor(LLColor4U(gAgent.getEffectColor())); LLStatViewer::OBJECT_CREATE.add(1); - //LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CREATE_COUNT); return TRUE; } diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp index e556743cbf..44e4c54142 100755 --- a/indra/newview/llviewerassetstats.cpp +++ b/indra/newview/llviewerassetstats.cpp @@ -84,6 +84,30 @@ // ------------------------------------------------------ LLViewerAssetStats * gViewerAssetStatsMain(0); LLViewerAssetStats * gViewerAssetStatsThread1(0); +LLTrace::Count<> LLViewerAssetStats::sEnqueued[EVACCount] = {LLTrace::Count<>("enqueuedassetrequeststemptexturehttp", "Number of temporary texture asset http requests enqueued"), + LLTrace::Count<>("enqueuedassetrequeststemptextureudp", "Number of temporary texture asset udp requests enqueued"), + LLTrace::Count<>("enqueuedassetrequestsnontemptexturehttp", "Number of texture asset http requests enqueued"), + LLTrace::Count<>("enqueuedassetrequestsnontemptextureudp", "Number of texture asset udp requests enqueued"), + LLTrace::Count<>("enqueuedassetrequestswearableudp", "Number of wearable asset requests enqueued"), + LLTrace::Count<>("enqueuedassetrequestssoundudp", "Number of sound asset requests enqueued"), + LLTrace::Count<>("enqueuedassetrequestsgestureudp", "Number of gesture asset requests enqueued"), + LLTrace::Count<>("enqueuedassetrequestsother", "Number of other asset requests enqueued")}; +LLTrace::Count<> LLViewerAssetStats::sDequeued[EVACCount] = {LLTrace::Count<>("dequeuedassetrequeststemptexturehttp", "Number of temporary texture asset http requests dequeued"), + LLTrace::Count<>("dequeuedassetrequeststemptextureudp", "Number of temporary texture asset udp requests dequeued"), + LLTrace::Count<>("dequeuedassetrequestsnontemptexturehttp", "Number of texture asset http requests dequeued"), + LLTrace::Count<>("dequeuedassetrequestsnontemptextureudp", "Number of texture asset udp requests dequeued"), + LLTrace::Count<>("dequeuedassetrequestswearableudp", "Number of wearable asset requests dequeued"), + LLTrace::Count<>("dequeuedassetrequestssoundudp", "Number of sound asset requests dequeued"), + LLTrace::Count<>("dequeuedassetrequestsgestureudp", "Number of gesture asset requests dequeued"), + LLTrace::Count<>("dequeuedassetrequestsother", "Number of other asset requests dequeued")}; +LLTrace::Measurement LLViewerAssetStats::sResponse[EVACCount] = {LLTrace::Measurement("assetresponsetimestemptexturehttp", "Time spent responding to temporary texture asset http requests"), + LLTrace::Measurement("assetresponsetimestemptextureudp", "Time spent responding to temporary texture asset udp requests"), + LLTrace::Measurement("assetresponsetimesnontemptexturehttp", "Time spent responding to texture asset http requests"), + LLTrace::Measurement("assetresponsetimesnontemptextureudp", "Time spent responding to texture asset udp requests"), + LLTrace::Measurement("assetresponsetimeswearableudp", "Time spent responding to wearable asset requests"), + LLTrace::Measurement("assetresponsetimessoundudp", "Time spent responding to sound asset requests"), + LLTrace::Measurement("assetresponsetimesgestureudp", "Time spent responding to gesture asset requests"), + LLTrace::Measurement("assetresponsetimesother", "Time spent responding to other asset requests")}; // ------------------------------------------------------ @@ -234,6 +258,7 @@ LLViewerAssetStats::recordGetEnqueued(LLViewerAssetType::EType at, bool with_htt const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); ++(mCurRegionStats->mRequests[int(eac)].mEnqueued); + sEnqueued[int(eac)].add(1); } void @@ -242,6 +267,7 @@ LLViewerAssetStats::recordGetDequeued(LLViewerAssetType::EType at, bool with_htt const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); ++(mCurRegionStats->mRequests[int(eac)].mDequeued); + sDequeued[int(eac)].add(1); } void @@ -250,6 +276,7 @@ LLViewerAssetStats::recordGetServiced(LLViewerAssetType::EType at, bool with_htt const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); mCurRegionStats->mRequests[int(eac)].mResponse.record(duration); + sResponse[int(eac)].sample(duration); } void diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h index 8319752230..a750db2cc2 100755 --- a/indra/newview/llviewerassetstats.h +++ b/indra/newview/llviewerassetstats.h @@ -37,6 +37,7 @@ #include "llsimplestat.h" #include "llsd.h" #include "llvoavatar.h" +#include "lltrace.h" /** * @class LLViewerAssetStats @@ -240,6 +241,7 @@ public: protected: typedef std::map > PerRegionContainer; + typedef std::map PerRegionRecordingContainer; // Region of the currently-active region. Always valid but may // be zero after construction or when explicitly set. Unchanged @@ -251,8 +253,13 @@ protected: // Always points to a collection contained in mRegionStats. LLPointer mCurRegionStats; + static LLTrace::Count<> sEnqueued[EVACCount]; + static LLTrace::Count<> sDequeued[EVACCount]; + static LLTrace::Measurement sResponse[EVACCount]; + // Metrics data for all regions during one collection cycle PerRegionContainer mRegionStats; + PerRegionRecordingContainer mRegionRecordings; // Time of last reset duration_t mResetTimestamp; diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index ffeea2f4df..169b45c14e 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -607,7 +607,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LLFastTimer t(FTM_DISPLAY_UPDATE_GEOM); - const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time + const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds.value(); // 50 ms/second update time gPipeline.createObjects(max_geom_update_time); gPipeline.processPartitionQ(); gPipeline.updateGeom(max_geom_update_time); @@ -760,7 +760,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LLFastTimer t(FTM_IMAGE_UPDATE_LIST); - F32 max_image_decode_time = 0.050f*gFrameIntervalSeconds; // 50 ms/second decode time + F32 max_image_decode_time = 0.050f*gFrameIntervalSeconds.value(); // 50 ms/second decode time max_image_decode_time = llclamp(max_image_decode_time, 0.002f, 0.005f ); // min 2ms/frame, max 5ms/frame) gTextureList.updateImages(max_image_decode_time); } diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp index f6e840adcd..f4155df4d1 100644 --- a/indra/newview/llviewerjoystick.cpp +++ b/indra/newview/llviewerjoystick.cpp @@ -501,7 +501,7 @@ void LLViewerJoystick::moveObjects(bool reset) }; F32 cur_delta[6]; - F32 time = gFrameIntervalSeconds; + F32 time = gFrameIntervalSeconds.value(); // avoid making ridicously big movements if there's a big drop in fps if (time > .2f) @@ -665,7 +665,7 @@ void LLViewerJoystick::moveAvatar(bool reset) }; // time interval in seconds between this frame and the previous - F32 time = gFrameIntervalSeconds; + F32 time = gFrameIntervalSeconds.value(); // avoid making ridicously big movements if there's a big drop in fps if (time > .2f) @@ -878,7 +878,7 @@ void LLViewerJoystick::moveFlycam(bool reset) gSavedSettings.getF32("FlycamAxisDeadZone6") }; - F32 time = gFrameIntervalSeconds; + F32 time = gFrameIntervalSeconds.value(); // avoid making ridiculously big movements if there's a big drop in fps if (time > .2f) diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 7ce8cdcfd8..50ca8db267 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -1097,19 +1097,16 @@ void upload_new_resource( if( LLAssetType::AT_SOUND == asset_type ) { LLStatViewer::UPLOAD_SOUND.add(1); - //LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_SOUND_COUNT ); } else if( LLAssetType::AT_TEXTURE == asset_type ) { LLStatViewer::UPLOAD_TEXTURE.add(1); - //LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_TEXTURE_COUNT ); } else if( LLAssetType::AT_ANIMATION == asset_type) { LLStatViewer::ANIMATION_UPLOADS.add(1); - //LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_ANIM_COUNT ); } if(LLInventoryType::IT_NONE == inv_type) @@ -1235,20 +1232,14 @@ void increase_new_upload_stats(LLAssetType::EType asset_type) if ( LLAssetType::AT_SOUND == asset_type ) { LLStatViewer::UPLOAD_SOUND.add(1); - //LLViewerStats::getInstance()->incStat( - // LLViewerStats::ST_UPLOAD_SOUND_COUNT ); } else if ( LLAssetType::AT_TEXTURE == asset_type ) { LLStatViewer::UPLOAD_TEXTURE.add(1); - //LLViewerStats::getInstance()->incStat( - // LLViewerStats::ST_UPLOAD_TEXTURE_COUNT ); } else if ( LLAssetType::AT_ANIMATION == asset_type ) { LLStatViewer::ANIMATION_UPLOADS.add(1); - //LLViewerStats::getInstance()->incStat( - // LLViewerStats::ST_UPLOAD_ANIM_COUNT ); } } diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index b3e1c9bdbe..82caa05983 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -4416,18 +4416,18 @@ void send_agent_update(BOOL force_send, BOOL send_reliable) // *TODO: Remove this dependency, or figure out a better way to handle // this hack. -extern U32 gObjectBits; +extern LLUnit::Bits gObjectData; void process_object_update(LLMessageSystem *mesgsys, void **user_data) { // Update the data counters if (mesgsys->getReceiveCompressedSize()) { - gObjectBits += mesgsys->getReceiveCompressedSize() * 8; + gObjectData += (LLUnit::Bytes)mesgsys->getReceiveCompressedSize(); } else { - gObjectBits += mesgsys->getReceiveSize() * 8; + gObjectData += (LLUnit::Bytes)mesgsys->getReceiveSize(); } // Update the object... @@ -4439,11 +4439,11 @@ void process_compressed_object_update(LLMessageSystem *mesgsys, void **user_data // Update the data counters if (mesgsys->getReceiveCompressedSize()) { - gObjectBits += mesgsys->getReceiveCompressedSize() * 8; + gObjectData += (LLUnit::Bytes)mesgsys->getReceiveCompressedSize(); } else { - gObjectBits += mesgsys->getReceiveSize() * 8; + gObjectData += (LLUnit::Bytes)mesgsys->getReceiveSize(); } // Update the object... @@ -4455,11 +4455,11 @@ void process_cached_object_update(LLMessageSystem *mesgsys, void **user_data) // Update the data counters if (mesgsys->getReceiveCompressedSize()) { - gObjectBits += mesgsys->getReceiveCompressedSize() * 8; + gObjectData += (LLUnit::Bytes)mesgsys->getReceiveCompressedSize(); } else { - gObjectBits += mesgsys->getReceiveSize() * 8; + gObjectData += (LLUnit::Bytes)mesgsys->getReceiveSize(); } // Update the object... @@ -4471,11 +4471,11 @@ void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_ { if (mesgsys->getReceiveCompressedSize()) { - gObjectBits += mesgsys->getReceiveCompressedSize() * 8; + gObjectData += (LLUnit::Bytes)mesgsys->getReceiveCompressedSize(); } else { - gObjectBits += mesgsys->getReceiveSize() * 8; + gObjectData += (LLUnit::Bytes)mesgsys->getReceiveSize(); } gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_TERSE_IMPROVED); @@ -4763,140 +4763,6 @@ void process_sim_stats(LLMessageSystem *msg, void **user_data) { llwarns << "Unknown sim stat identifier: " << stat_id << llendl; } - //switch (stat_id) - //{ - //case LL_SIM_STAT_TIME_DILATION: - // LLStatViewer::SIM_TIME_DILATION.sample(stat_value); - // //LLViewerStats::getInstance()->mSimTimeDilation.addValue(stat_value); - // break; - //case LL_SIM_STAT_FPS: - // LLStatViewer::SIM_FPS.sample(stat_value); - // //LLViewerStats::getInstance()->mSimFPS.addValue(stat_value); - // break; - //case LL_SIM_STAT_PHYSFPS: - // LLStatViewer::SIM_PHYSICS_FPS.sample(stat_value); - // //LLViewerStats::getInstance()->mSimPhysicsFPS.addValue(stat_value); - // break; - //case LL_SIM_STAT_AGENTUPS: - // LLStatViewer::SIM_AGENT_UPS.sample(stat_value); - // //LLViewerStats::getInstance()->mSimAgentUPS.addValue(stat_value); - // break; - //case LL_SIM_STAT_FRAMEMS: - // LLStatViewer::SIM_FRAME_TIME.sample(stat_value); - // //LLViewerStats::getInstance()->mSimFrameMsec.addValue(stat_value); - // break; - //case LL_SIM_STAT_NETMS: - // LLStatViewer::SIM_NET_TIME.sample(stat_value); - // //LLViewerStats::getInstance()->mSimNetMsec.addValue(stat_value); - // break; - //case LL_SIM_STAT_SIMOTHERMS: - // LLStatViewer::SIM_PHYSICS_OTHER_TIME.sample(stat_value); - // //LLViewerStats::getInstance()->mSimSimOtherMsec.addValue(stat_value); - // break; - //case LL_SIM_STAT_SIMPHYSICSMS: - // LLStatViewer::SIM_PHYSICS_TIME.sample(stat_value); - // //LLViewerStats::getInstance()->mSimSimPhysicsMsec.addValue(stat_value); - // break; - //case LL_SIM_STAT_AGENTMS: - // LLStatViewer::SIM_AGENTS_TIME.sample(stat_value); - // //LLViewerStats::getInstance()->mSimAgentMsec.addValue(stat_value); - // break; - //case LL_SIM_STAT_IMAGESMS: - // LLStatViewer::SIM_IMAGES_TIME.sample(stat_value); - // //LLViewerStats::getInstance()->mSimImagesMsec.addValue(stat_value); - // break; - //case LL_SIM_STAT_SCRIPTMS: - // LLStatViewer::SIM_SCRIPTS_TIME.sample(stat_value); - // //LLViewerStats::getInstance()->mSimScriptMsec.addValue(stat_value); - // break; - //case LL_SIM_STAT_NUMTASKS: - // LLStatViewer::SIM_OBJECTS.sample(stat_value); - // //LLViewerStats::getInstance()->mSimObjects.addValue(stat_value); - // break; - //case LL_SIM_STAT_NUMTASKSACTIVE: - // LLStatViewer::SIM_ACTIVE_OBJECTS.sample(stat_value); - // //LLViewerStats::getInstance()->mSimActiveObjects.addValue(stat_value); - // break; - //case LL_SIM_STAT_NUMAGENTMAIN: - // LLStatViewer::SIM_MAIN_AGENTS.sample(stat_value); - // //LLViewerStats::getInstance()->mSimMainAgents.addValue(stat_value); - // break; - //case LL_SIM_STAT_NUMAGENTCHILD: - // LLStatViewer::SIM_CHILD_AGENTS.sample(stat_value); - // //LLViewerStats::getInstance()->mSimChildAgents.addValue(stat_value); - // break; - //case LL_SIM_STAT_NUMSCRIPTSACTIVE: - // LLStatViewer::SIM_ACTIVE_SCRIPTS.sample(stat_value); - // //LLViewerStats::getInstance()->mSimActiveScripts.addValue(stat_value); - // break; - //case LL_SIM_STAT_SCRIPT_EPS: - // LLStatViewer::SIM_SCRIPT_EPS.sample(stat_value); - // //LLViewerStats::getInstance()->mSimScriptEPS.addValue(stat_value); - // break; - //case LL_SIM_STAT_INPPS: - // LLStatViewer::SIM_IN_PACKETS_PER_SEC.sample(stat_value); - // //LLViewerStats::getInstance()->mSimInPPS.addValue(stat_value); - // break; - //case LL_SIM_STAT_OUTPPS: - // LLStatViewer::SIM_OUT_PACKETS_PER_SEC.sample(stat_value); - // //LLViewerStats::getInstance()->mSimOutPPS.addValue(stat_value); - // break; - //case LL_SIM_STAT_PENDING_DOWNLOADS: - // LLViewerStats::getInstance()->mSimPendingDownloads.addValue(stat_value); - // break; - //case LL_SIM_STAT_PENDING_UPLOADS: - // LLViewerStats::getInstance()->mSimPendingUploads.addValue(stat_value); - // break; - //case LL_SIM_STAT_PENDING_LOCAL_UPLOADS: - // LLViewerStats::getInstance()->mSimPendingLocalUploads.addValue(stat_value); - // break; - //case LL_SIM_STAT_TOTAL_UNACKED_BYTES: - // LLViewerStats::getInstance()->mSimTotalUnackedBytes.addValue(stat_value / 1024.f); - // break; - //case LL_SIM_STAT_PHYSICS_PINNED_TASKS: - // LLViewerStats::getInstance()->mPhysicsPinnedTasks.addValue(stat_value); - // break; - //case LL_SIM_STAT_PHYSICS_LOD_TASKS: - // LLViewerStats::getInstance()->mPhysicsLODTasks.addValue(stat_value); - // break; - //case LL_SIM_STAT_SIMPHYSICSSTEPMS: - // LLViewerStats::getInstance()->mSimSimPhysicsStepMsec.addValue(stat_value); - // break; - //case LL_SIM_STAT_SIMPHYSICSSHAPEMS: - // LLViewerStats::getInstance()->mSimSimPhysicsShapeUpdateMsec.addValue(stat_value); - // break; - //case LL_SIM_STAT_SIMPHYSICSOTHERMS: - // LLViewerStats::getInstance()->mSimSimPhysicsOtherMsec.addValue(stat_value); - // break; - //case LL_SIM_STAT_SIMPHYSICSMEMORY: - // LLViewerStats::getInstance()->mPhysicsMemoryAllocated.addValue(stat_value); - // break; - //case LL_SIM_STAT_SIMSPARETIME: - // LLViewerStats::getInstance()->mSimSpareMsec.addValue(stat_value); - // break; - //case LL_SIM_STAT_SIMSLEEPTIME: - // LLViewerStats::getInstance()->mSimSleepMsec.addValue(stat_value); - // break; - //case LL_SIM_STAT_IOPUMPTIME: - // LLViewerStats::getInstance()->mSimPumpIOMsec.addValue(stat_value); - // break; - //case LL_SIM_STAT_PCTSCRIPTSRUN: - // LLViewerStats::getInstance()->mSimPctScriptsRun.addValue(stat_value); - // break; - //case LL_SIM_STAT_SIMAISTEPTIMEMS: - // LLViewerStats::getInstance()->mSimSimAIStepMsec.addValue(stat_value); - // break; - //case LL_SIM_STAT_SKIPPEDAISILSTEPS_PS: - // LLViewerStats::getInstance()->mSimSimSkippedSilhouetteSteps.addValue(stat_value); - // break; - //case LL_SIM_STAT_PCTSTEPPEDCHARACTERS: - // LLViewerStats::getInstance()->mSimSimPctSteppedCharacters.addValue(stat_value); - // break; - //default: - // // Used to be a commented out warning. - // LL_DEBUGS("Messaging") << "Unknown stat id" << stat_id << LL_ENDL; - // break; - //} } /* @@ -5968,7 +5834,6 @@ void process_alert_core(const std::string& message, BOOL modal) if ( message == "You died and have been teleported to your home location") { LLStatViewer::KILLED.add(1); - //LLViewerStats::getInstance()->incStat(LLViewerStats::ST_KILLED_COUNT); } else if( message == "Home position set." ) { @@ -7395,8 +7260,6 @@ void onCovenantLoadComplete(LLVFS *vfs, } else { - //LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); - if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || LL_ERR_FILE_EMPTY == status) { diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 747dfd3250..ca404858cf 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -2034,7 +2034,6 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, if ( asAvatar() && asAvatar()->isSelf() && (mag_sqr > 0.25f) ) { LLStatViewer::AGENT_POSITION_SNAP.sample(diff.length()); - //LLViewerStats::getInstance()->mAgentPositionSnaps.push( diff.length() ); } } diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 2f171f89d7..14a2ac3384 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1033,10 +1033,6 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) LLStatViewer::NUM_ACTIVE_OBJECTS.sample(idle_count); LLStatViewer::NUM_SIZE_CULLED.sample(mNumSizeCulled); LLStatViewer::NUM_VIS_CULLED.sample(mNumVisCulled); - //LLViewerStats::getInstance()->mNumObjectsStat.addValue((S32) mObjects.size()); - //LLViewerStats::getInstance()->mNumActiveObjectsStat.addValue(idle_count); - //LLViewerStats::getInstance()->mNumSizeCulledStat.addValue(mNumSizeCulled); - //LLViewerStats::getInstance()->mNumVisCulledStat.addValue(mNumVisCulled); } void LLViewerObjectList::fetchObjectCosts() diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index ccc0c9ba59..963d2ebb81 100755 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -206,72 +206,53 @@ void LLViewerStats::resetStats() void LLViewerStats::updateFrameStats(const F64 time_diff) { + LLTrace::Seconds time_diff_seconds(time_diff); if (getRecording().getLastValue(LLStatViewer::PACKETS_LOST_PERCENT) > 5.0) { - LLStatViewer::LOSS_5_PERCENT_TIME.add(time_diff); - //incStat(ST_LOSS_05_SECONDS, time_diff); + LLStatViewer::LOSS_5_PERCENT_TIME.add(time_diff_seconds); } F32 sim_fps = getRecording().getLastValue(LLStatViewer::SIM_FPS); if (0.f < sim_fps && sim_fps < 20.f) { - LLStatViewer::SIM_20_FPS_TIME.add(time_diff); - //incStat(ST_SIM_FPS_20_SECONDS, time_diff); + LLStatViewer::SIM_20_FPS_TIME.add(time_diff_seconds); } F32 sim_physics_fps = getRecording().getLastValue(LLStatViewer::SIM_PHYSICS_FPS); if (0.f < sim_physics_fps && sim_physics_fps < 20.f) { - LLStatViewer::SIM_PHYSICS_20_FPS_TIME.add(time_diff); - //incStat(ST_PHYS_FPS_20_SECONDS, time_diff); + LLStatViewer::SIM_PHYSICS_20_FPS_TIME.add(time_diff_seconds); } if (time_diff >= 0.5) { - LLStatViewer::FPS_2_TIME.add(time_diff); - //incStat(ST_FPS_2_SECONDS, time_diff); + LLStatViewer::FPS_2_TIME.add(time_diff_seconds); } if (time_diff >= 0.125) { - LLStatViewer::FPS_8_TIME.add(time_diff); - //incStat(ST_FPS_8_SECONDS, time_diff); + LLStatViewer::FPS_8_TIME.add(time_diff_seconds); } if (time_diff >= 0.1) { - LLStatViewer::FPS_10_TIME.add(time_diff); - //incStat(ST_FPS_10_SECONDS, time_diff); + LLStatViewer::FPS_10_TIME.add(time_diff_seconds); } if (gFrameCount && mLastTimeDiff > 0.0) { // new "stutter" meter LLStatViewer::FRAMETIME_DOUBLED.add(time_diff >= 2.0 * mLastTimeDiff ? 1 : 0); - //setStat(ST_FPS_DROP_50_RATIO, - // (getStat(ST_FPS_DROP_50_RATIO) * (F64)(gFrameCount - 1) + - // (time_diff >= 2.0 * mLastTimeDiff ? 1.0 : 0.0)) / gFrameCount); - // old stats that were never really used - LLStatViewer::FRAMETIME_JITTER.sample(mLastTimeDiff - time_diff); - //setStat(ST_FRAMETIME_JITTER, - // (getStat(ST_FRAMETIME_JITTER) * (gFrameCount - 1) + - // fabs(mLastTimeDiff - time_diff) / mLastTimeDiff) / gFrameCount); + LLStatViewer::FRAMETIME_JITTER.sample(mLastTimeDiff - time_diff); F32 average_frametime = gRenderStartTime.getElapsedTimeF32() / (F32)gFrameCount; - LLStatViewer::FRAMETIME_SLEW.sample(average_frametime - time_diff); - //setStat(ST_FRAMETIME_SLEW, - // (getStat(ST_FRAMETIME_SLEW) * (gFrameCount - 1) + - // fabs(average_frametime - time_diff) / average_frametime) / gFrameCount); + LLStatViewer::FRAMETIME_SLEW.sample(average_frametime - time_diff); F32 max_bandwidth = gViewerThrottle.getMaxBandwidth(); F32 delta_bandwidth = gViewerThrottle.getCurrentBandwidth() - max_bandwidth; LLStatViewer::DELTA_BANDWIDTH.sample(delta_bandwidth); - //setStat(ST_DELTA_BANDWIDTH, delta_bandwidth / 1024.f); - LLStatViewer::MAX_BANDWIDTH.sample(max_bandwidth); - //setStat(ST_MAX_BANDWIDTH, max_bandwidth / 1024.f); - } mLastTimeDiff = time_diff; @@ -299,10 +280,13 @@ F32 gAveLandCompression = 0.f, gAveWaterCompression = 0.f; F32 gBestLandCompression = 1.f, gBestWaterCompression = 1.f; F32 gWorstLandCompression = 0.f, gWorstWaterCompression = 0.f; -U32 gTotalWorldBytes = 0, gTotalObjectBytes = 0, gTotalTextureBytes = 0, gSimPingCount = 0; -U32 gObjectBits = 0; +LLUnit::Bytes gTotalWorldData = 0, + gTotalObjectData = 0, + gTotalTextureData = 0; +U32 gSimPingCount = 0; +LLUnit::Bits gObjectData = 0; F32 gAvgSimPing = 0.f; -U32 gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGORY] = {0}; +LLUnit::Bytes gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGORY] = {0}; extern U32 gVisCompared; extern U32 gVisTested; @@ -311,8 +295,8 @@ LLFrameTimer gTextureTimer; void update_statistics() { - gTotalWorldBytes += gVLManager.getTotalBytes(); - gTotalObjectBytes += gObjectBits / 8; + gTotalWorldData += gVLManager.getTotalBytes(); + gTotalObjectData += gObjectData; // make sure we have a valid time delta for this frame if (gFrameIntervalSeconds > 0.f) @@ -320,68 +304,48 @@ void update_statistics() if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK) { LLStatViewer::MOUSELOOK_TIME.add(gFrameIntervalSeconds); - //LLViewerStats::getInstance()->incStat(LLViewerStats::ST_MOUSELOOK_SECONDS, gFrameIntervalSeconds); } else if (gAgentCamera.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR) { LLStatViewer::AVATAR_EDIT_TIME.add(gFrameIntervalSeconds); - //LLViewerStats::getInstance()->incStat(LLViewerStats::ST_AVATAR_EDIT_SECONDS, gFrameIntervalSeconds); } else if (LLFloaterReg::instanceVisible("build")) { LLStatViewer::TOOLBOX_TIME.add(gFrameIntervalSeconds); - //LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TOOLBOX_SECONDS, gFrameIntervalSeconds); } } LLStatViewer::ENABLE_VBO.sample((F64)gSavedSettings.getBOOL("RenderVBOEnable")); - //stats.setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable")); LLStatViewer::LIGHTING_DETAIL.sample((F64)gPipeline.getLightingDetail()); - //stats.setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail()); LLStatViewer::DRAW_DISTANCE.sample((F64)gSavedSettings.getF32("RenderFarClip")); - //stats.setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip")); LLStatViewer::CHAT_BUBBLES.sample((F64)gSavedSettings.getBOOL("UseChatBubbles")); - //stats.setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles")); - LLStatViewer::FRAME_STACKTIME.sample(gDebugView->mFastTimerView->getTime("Frame")); - //stats.setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime("Frame")); + LLStatViewer::FRAME_STACKTIME.sample(gDebugView->mFastTimerView->getTime("Frame")); F64 idle_secs = gDebugView->mFastTimerView->getTime("Idle"); F64 network_secs = gDebugView->mFastTimerView->getTime("Network"); - LLStatViewer::UPDATE_STACKTIME.sample(idle_secs - network_secs); - //stats.setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs); - LLStatViewer::NETWORK_STACKTIME.sample(network_secs); - //stats.setStat(LLViewerStats::ST_NETWORK_SECS, network_secs); - LLStatViewer::IMAGE_STACKTIME.sample(gDebugView->mFastTimerView->getTime("Update Images")); - //stats.setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime("Update Images")); - LLStatViewer::REBUILD_STACKTIME.sample(gDebugView->mFastTimerView->getTime("Sort Draw State")); - //stats.setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime("Sort Draw State")); - LLStatViewer::RENDER_STACKTIME.sample(gDebugView->mFastTimerView->getTime("Geometry")); - //stats.setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime("Geometry")); + LLStatViewer::UPDATE_STACKTIME.sample(idle_secs - network_secs); + LLStatViewer::NETWORK_STACKTIME.sample(network_secs); + LLStatViewer::IMAGE_STACKTIME.sample(gDebugView->mFastTimerView->getTime("Update Images")); + LLStatViewer::REBUILD_STACKTIME.sample(gDebugView->mFastTimerView->getTime("Sort Draw State")); + LLStatViewer::RENDER_STACKTIME.sample(gDebugView->mFastTimerView->getTime("Geometry")); LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost()); if (cdp) { LLStatViewer::SIM_PING.sample(cdp->getPingDelay()); - //stats.mSimPingStat.addValue(cdp->getPingDelay()); gAvgSimPing = ((gAvgSimPing * (F32)gSimPingCount) + (F32)(cdp->getPingDelay())) / ((F32)gSimPingCount + 1); gSimPingCount++; } else { LLStatViewer::SIM_PING.sample(10000); - //stats.mSimPingStat.addValue(10000); } - //stats.mFPSStat.addValue(1); LLStatViewer::FPS.add(1); F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits()); LLStatViewer::LAYERS_KBIT.add(layer_bits); - //stats.mLayersKBitStat.addValue(layer_bits/1024.f); - LLStatViewer::OBJECT_KBIT.add(gObjectBits); - //stats.mObjectKBitStat.addValue(gObjectBits/1024.f); - //stats.mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending()); + LLStatViewer::OBJECT_KBIT.add(gObjectData); LLStatViewer::PENDING_VFS_OPERATIONS.sample(LLVFile::getVFSThread()->getPending()); LLStatViewer::ASSET_KBIT.add(gTransferManager.getTransferBitsIn(LLTCT_ASSET)); - //stats.mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f); gTransferManager.resetTransferBitsIn(LLTCT_ASSET); if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) @@ -403,14 +367,13 @@ void update_statistics() avg_visible_avatars = (avg_visible_avatars * (F32)(visible_avatar_frames - 1.f) + visible_avatars) / visible_avatar_frames; } LLStatViewer::VISIBLE_AVATARS.sample((F64)avg_visible_avatars); - //stats.setStat(LLViewerStats::ST_VISIBLE_AVATARS, (F64)avg_visible_avatars); } LLWorld::getInstance()->updateNetStats(); LLWorld::getInstance()->requestCacheMisses(); // Reset all of these values. gVLManager.resetBitCounts(); - gObjectBits = 0; + gObjectData = 0; // gDecodedBits = 0; // Only update texture stats periodically so that they are less noisy @@ -419,7 +382,7 @@ void update_statistics() static LLFrameTimer texture_stats_timer; if (texture_stats_timer.getElapsedTimeF32() >= texture_stats_freq) { - gTotalTextureBytes = LLTrace::Bytes(LLViewerStats::instance().getRecording().getSum(LLStatViewer::TEXTURE_KBIT)).value(); + gTotalTextureData = LLTrace::Bytes(LLViewerStats::instance().getRecording().getSum(LLStatViewer::TEXTURE_KBIT)).value(); texture_stats_timer.reset(); } } @@ -559,9 +522,9 @@ void send_stats() LLSD &download = body["downloads"]; - download["world_kbytes"] = gTotalWorldBytes / 1024.0; - download["object_kbytes"] = gTotalObjectBytes / 1024.0; - download["texture_kbytes"] = gTotalTextureBytes / 1024.0; + download["world_kbytes"] = LLTrace::Kilobytes(gTotalWorldData).value(); + download["object_kbytes"] = LLTrace::Kilobytes(gTotalObjectData).value(); + download["texture_kbytes"] = LLTrace::Kilobytes(gTotalTextureData).value(); download["mesh_kbytes"] = LLMeshRepository::sBytesReceived/1024.0; LLSD &in = body["stats"]["net"]["in"]; diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index b182a40403..06f65b2cdd 100755 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -57,7 +57,7 @@ struct SimMeasurement : public LLTrace::Measurement, public SimMeasurementSam /*virtual*/ void sample(F64 value) { - LLTrace::Measurement::sample(value); + LLTrace::Measurement::sample(T(value)); } }; @@ -318,7 +318,7 @@ void update_statistics(); void send_stats(); extern LLFrameTimer gTextureTimer; -extern U32 gTotalTextureBytes; -extern U32 gTotalObjectBytes; -extern U32 gTotalTextureBytesPerBoostLevel[] ; +extern LLUnit::Bytes gTotalTextureData; +extern LLUnit::Bytes gTotalObjectData; +extern LLUnit::Bytes gTotalTextureBytesPerBoostLevel[] ; #endif // LL_LLVIEWERSTATS_H diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index d355432e8a..b9d5751412 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -709,7 +709,7 @@ void LLViewerTextureList::updateImagesDecodePriorities() // Update the decode priority for N images each frame { static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities"); // default: 32 - const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds) + 1, MAX_PRIO_UPDATES); + const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds.value()) + 1, MAX_PRIO_UPDATES); S32 update_counter = llmin(max_update_count, mUUIDMap.size()); uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateUUID); while ((update_counter-- > 0) && !mUUIDMap.empty()) @@ -943,11 +943,11 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) static const F32 MIN_PRIORITY_THRESHOLD = gSavedSettings.getF32("TextureFetchUpdatePriorityThreshold"); // default: 0.0 static const bool SKIP_LOW_PRIO = gSavedSettings.getBOOL("TextureFetchUpdateSkipLowPriority"); // default: false - size_t max_priority_count = llmin((S32) (MAX_HIGH_PRIO_COUNT*MAX_HIGH_PRIO_COUNT*gFrameIntervalSeconds)+1, MAX_HIGH_PRIO_COUNT); + size_t max_priority_count = llmin((S32) (MAX_HIGH_PRIO_COUNT*MAX_HIGH_PRIO_COUNT*gFrameIntervalSeconds.value())+1, MAX_HIGH_PRIO_COUNT); max_priority_count = llmin(max_priority_count, mImageList.size()); size_t total_update_count = mUUIDMap.size(); - size_t max_update_count = llmin((S32) (MAX_UPDATE_COUNT*MAX_UPDATE_COUNT*gFrameIntervalSeconds)+1, MAX_UPDATE_COUNT); + size_t max_update_count = llmin((S32) (MAX_UPDATE_COUNT*MAX_UPDATE_COUNT*gFrameIntervalSeconds.value())+1, MAX_UPDATE_COUNT); max_update_count = llmin(max_update_count, total_update_count); // MAX_HIGH_PRIO_COUNT high priority entries diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 2062f07650..06daf15c08 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -731,7 +731,7 @@ public: { if(gTotalTextureBytesPerBoostLevel[i] > 0) { - addText(xpos, ypos, llformat("Boost_Level %d: %.3f MB", i, (F32)gTotalTextureBytesPerBoostLevel[i] / (1024 * 1024))); + addText(xpos, ypos, llformat("Boost_Level %d: %.3f MB", i, LLUnit::Megabytes(gTotalTextureBytesPerBoostLevel[i]).value())); ypos += y_inc; } } @@ -1405,8 +1405,8 @@ BOOL LLViewerWindow::handlePaint(LLWindow *window, S32 x, S32 y, S32 width, S LLTrace::Recording& recording = LLViewerStats::instance().getRecording(); temp_str = llformat( "FPS %3.1f Phy FPS %2.1f Time Dil %1.3f", /* Flawfinder: ignore */ recording.getPerSec(LLStatViewer::FPS), //mFPSStat.getMeanPerSec(), - recording.getMean(LLStatViewer::SIM_PHYSICS_FPS), //LLViewerStats::getInstance()->mSimPhysicsFPS.getPrev(0), - recording.getMean(LLStatViewer::SIM_TIME_DILATION)); //LLViewerStats::getInstance()->mSimTimeDilation.getPrev(0)); + recording.getLastValue(LLStatViewer::SIM_PHYSICS_FPS), + recording.getLastValue(LLStatViewer::SIM_TIME_DILATION)); S32 len = temp_str.length(); TextOutA(hdc, 0, 0, temp_str.c_str(), len); @@ -2185,9 +2185,7 @@ void LLViewerWindow::reshape(S32 width, S32 height) } LLStatViewer::WINDOW_WIDTH.sample((F64)width); - //LLViewerStats::getInstance()->setStat(LLViewerStats::ST_WINDOW_WIDTH, (F64)width); LLStatViewer::WINDOW_HEIGHT.sample((F64)height); - //LLViewerStats::getInstance()->setStat(LLViewerStats::ST_WINDOW_HEIGHT, (F64)height); LLLayoutStack::updateClass(); } @@ -3237,8 +3235,8 @@ void LLViewerWindow::updateMouseDelta() static F32 fdy = 0.f; F32 amount = 16.f; - fdx = fdx + ((F32) dx - fdx) * llmin(gFrameIntervalSeconds*amount,1.f); - fdy = fdy + ((F32) dy - fdy) * llmin(gFrameIntervalSeconds*amount,1.f); + fdx = fdx + ((F32) dx - fdx) * llmin(gFrameIntervalSeconds.value()*amount,1.f); + fdy = fdy + ((F32) dy - fdy) * llmin(gFrameIntervalSeconds.value()*amount,1.f); mCurrentMouseDelta.set(llround(fdx), llround(fdy)); mouse_vel.setVec(fdx,fdy); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index d366455a62..97c1b07ebc 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -7813,14 +7813,14 @@ void LLVOAvatar::cullAvatarsByPixelArea() if (gFrameTimeSeconds != sUnbakedUpdateTime) // only update once per frame { sUnbakedUpdateTime = gFrameTimeSeconds; - sUnbakedTime += gFrameIntervalSeconds; + sUnbakedTime += gFrameIntervalSeconds.value(); } if (grey_avatars > 0) { if (gFrameTimeSeconds != sGreyUpdateTime) // only update once per frame { sGreyUpdateTime = gFrameTimeSeconds; - sGreyTime += gFrameIntervalSeconds; + sGreyTime += gFrameIntervalSeconds.value(); } } } diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 9f0921ff59..7c20e8eae7 100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -910,18 +910,11 @@ void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp) if (mLastRegionHandle != 0) { ++mRegionCrossingCount; - F64 delta = (F64)mRegionCrossingTimer.getElapsedTimeF32(); - //F64 avg = (mRegionCrossingCount == 1) ? 0 : LLViewerStats::getInstance()->getStat(LLViewerStats::ST_CROSSING_AVG); - //F64 delta_avg = (delta + avg*(mRegionCrossingCount-1)) / mRegionCrossingCount; + LLTrace::Seconds delta = mRegionCrossingTimer.getElapsedTimeF32(); LLStatViewer::REGION_CROSSING_TIME.sample(delta); - //LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CROSSING_AVG, delta_avg); - // - //F64 max = (mRegionCrossingCount == 1) ? 0 : LLViewerStats::getInstance()->getStat(LLViewerStats::ST_CROSSING_MAX); - //max = llmax(delta, max); - //LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CROSSING_MAX, max); // Diagnostics - llinfos << "Region crossing took " << (F32)(delta * 1000.0) << " ms " << llendl; + llinfos << "Region crossing took " << (F32)(delta * 1000.0).value() << " ms " << llendl; } if (regionp) { @@ -2589,7 +2582,6 @@ void LLVOAvatarSelf::processRebakeAvatarTextures(LLMessageSystem* msg, void**) gAgentAvatarp->invalidateComposite(layer_set, TRUE); found = TRUE; LLStatViewer::TEX_REBAKES.add(1); - //LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES); } } } @@ -2635,7 +2627,6 @@ void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug) invalidateComposite(layer_set, TRUE); LLStatViewer::TEX_REBAKES.add(1); - //LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES); } else { diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp index 20033d6fe4..0eb00f7191 100644 --- a/indra/newview/llwearablelist.cpp +++ b/indra/newview/llwearablelist.cpp @@ -136,7 +136,6 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID { LLFile::remove(std::string(filename)); } - //LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); LL_WARNS("Wearable") << "Wearable download failed: " << LLAssetStorage::getErrorString( status ) << " " << uuid << LL_ENDL; switch( status ) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 4582de805f..75af605ad7 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -4892,7 +4892,7 @@ void LLPipeline::renderDebug() { DebugBlip& blip = *iter; - blip.mAge += gFrameIntervalSeconds; + blip.mAge += gFrameIntervalSeconds.value(); if (blip.mAge > 2.f) { mDebugBlips.erase(iter++); @@ -4902,7 +4902,7 @@ void LLPipeline::renderDebug() iter++; } - blip.mPosition.mV[2] += gFrameIntervalSeconds*2.f; + blip.mPosition.mV[2] += gFrameIntervalSeconds.value()*2.f; gGL.color4fv(blip.mColor.mV); gGL.vertex3fv(blip.mPosition.mV); @@ -5713,7 +5713,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) { if (farthest_light->fade >= 0.f) { - farthest_light->fade = -gFrameIntervalSeconds; + farthest_light->fade = -(gFrameIntervalSeconds.value()); } } else @@ -5809,12 +5809,12 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) if (fade >= 0.f) { fade = fade / LIGHT_FADE_TIME; - ((Light*) (&(*iter)))->fade += gFrameIntervalSeconds; + ((Light*) (&(*iter)))->fade += gFrameIntervalSeconds.value(); } else { fade = 1.f + fade / LIGHT_FADE_TIME; - ((Light*) (&(*iter)))->fade -= gFrameIntervalSeconds; + ((Light*) (&(*iter)))->fade -= gFrameIntervalSeconds.value(); } fade = llclamp(fade,0.f,1.f); light_color *= fade; @@ -7129,7 +7129,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) } else if (transition_time < 1.f) { //currently in a transition, continue interpolating - transition_time += 1.f/CameraFocusTransitionTime*gFrameIntervalSeconds; + transition_time += 1.f/CameraFocusTransitionTime*gFrameIntervalSeconds.value(); transition_time = llmin(transition_time, 1.f); F32 t = cosf(transition_time*F_PI+F_PI)*0.5f+0.5f; @@ -9121,7 +9121,7 @@ void LLPipeline::generateHighlight(LLCamera& camera) if (!mHighlightSet.empty()) { - F32 transition = gFrameIntervalSeconds/RenderHighlightFadeTime; + F32 transition = gFrameIntervalSeconds.value()/RenderHighlightFadeTime; LLGLDisable test(GL_ALPHA_TEST); LLGLDepthTest depth(GL_FALSE); @@ -9756,7 +9756,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) if (gen_shadow) { - F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f); + F32 fade_amt = gFrameIntervalSeconds.value() * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f); //update shadow targets for (U32 i = 0; i < 2; i++) diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp index f8923b9868..4a190fbe23 100755 --- a/indra/newview/tests/llviewerassetstats_test.cpp +++ b/indra/newview/tests/llviewerassetstats_test.cpp @@ -220,7 +220,18 @@ get_region(const LLSD & sd, U64 region_handle1) namespace tut { struct tst_viewerassetstats_index - {}; + { + tst_viewerassetstats_index() + { + LLTrace::init(); + } + + ~tst_viewerassetstats_index() + { + LLTrace::cleanup(); + } + + }; typedef test_group tst_viewerassetstats_index_t; typedef tst_viewerassetstats_index_t::object tst_viewerassetstats_index_object_t; tut::tst_viewerassetstats_index_t tut_tst_viewerassetstats_index("tst_viewerassetstats_test"); -- cgit v1.3 From 5ae116f89b8459963ccb6ae9125d94ffaa79025e Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Wed, 31 Oct 2012 17:05:53 -0600 Subject: for SH-3471: create a simplified version of octree for object cache entries. --- indra/newview/llspatialpartition.cpp | 108 ++++++---------------- indra/newview/llspatialpartition.h | 49 ++-------- indra/newview/llvieweroctree.cpp | 48 +++++++++- indra/newview/llvieweroctree.h | 39 +++++++- indra/newview/llviewerregion.cpp | 174 ++++++++++++++++++++++++----------- indra/newview/llviewerregion.h | 14 ++- indra/newview/llvocache.cpp | 77 ++++++++++++++++ indra/newview/llvocache.h | 13 +++ indra/newview/pipeline.cpp | 20 ++-- 9 files changed, 346 insertions(+), 196 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index debb790c58..e9ece331d1 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -264,11 +264,7 @@ LLSpatialGroup::~LLSpatialGroup() { llerrs << "Illegal deletion of LLSpatialGroup!" << llendl; }*/ - if(isVisible()) - { - mSpatialPartition->mRegionp->clearVisibleGroup(this); - } - + if (gDebugGL) { gPipeline.checkReferences(this); @@ -434,16 +430,6 @@ BOOL LLSpatialGroup::isRecentlyVisible() const return (LLDrawable::getCurrentFrame() - mVisible[LLViewerCamera::sCurCameraID]) < MIN_VIS_FRAME_RANGE ; } -BOOL LLSpatialGroup::isVisible() const -{ - return mVisible[LLViewerCamera::sCurCameraID] >= LLDrawable::getCurrentFrame() ? TRUE : FALSE; -} - -void LLSpatialGroup::setVisible() -{ - mVisible[LLViewerCamera::sCurCameraID] = LLDrawable::getCurrentFrame(); -} - void LLSpatialGroup::validate() { ll_assert_aligned(this,64); @@ -1165,12 +1151,6 @@ BOOL LLSpatialGroup::changeLOD() void LLSpatialGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry* entry) { - if(mSpatialPartition->isVOCachePartition()) - { - LLviewerOctreeGroup::handleInsertion(node, entry); - return; - } - addObject((LLDrawable*)entry->getDrawable()); unbound(); setState(OBJECT_DIRTY); @@ -1178,10 +1158,7 @@ void LLSpatialGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry* void LLSpatialGroup::handleRemoval(const TreeNode* node, LLViewerOctreeEntry* entry) { - if(!mSpatialPartition->isVOCachePartition()) - { - removeObject((LLDrawable*)entry->getDrawable(), TRUE); - } + removeObject((LLDrawable*)entry->getDrawable(), TRUE); LLviewerOctreeGroup::handleRemoval(node, entry); } @@ -1189,12 +1166,6 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node) { setState(DEAD); - if(mSpatialPartition->isVOCachePartition()) - { - LLviewerOctreeGroup::handleDestruction(node); - return; - } - for (element_iter i = getDataBegin(); i != getDataEnd(); ++i) { LLViewerOctreeEntry* entry = *i; @@ -1510,8 +1481,9 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) //============================================== LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage, LLViewerRegion* regionp) -: mRenderByGroup(render_by_group), mBridge(NULL), mRegionp(regionp) +: mRenderByGroup(render_by_group), mBridge(NULL) { + mRegionp = regionp; mOcclusionEnabled = TRUE; mDrawableType = 0; mPartitionType = LLViewerRegion::PARTITION_NONE; @@ -1521,27 +1493,14 @@ LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mBufferUsage = buffer_usage; mDepthMask = FALSE; mSlopRatio = 0.25f; - mInfiniteFarClip = FALSE; - mVisitedTime = 0; - - LLVector4a center, size; - center.splat(0.f); - size.splat(1.f); + mInfiniteFarClip = FALSE; - mOctree = new OctreeRoot(center,size, NULL); new LLSpatialGroup(mOctree, this); } LLSpatialPartition::~LLSpatialPartition() -{ - delete mOctree; - mOctree = NULL; -} - -BOOL LLSpatialPartition::isVOCachePartition() const -{ - return mPartitionType == LLViewerRegion::PARTITION_VO_CACHE; +{ } LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) @@ -2050,12 +2009,7 @@ BOOL LLSpatialPartition::visibleObjectsInFrustum(LLCamera& camera) S32 LLSpatialPartition::cull(LLCamera &camera, std::vector* results, BOOL for_select) { - bool is_vo_cache_part = (mPartitionType == LLViewerRegion::PARTITION_VO_CACHE); - - if(is_vo_cache_part && mVisitedTime == LLViewerOctreeEntryData::getCurrentFrame()) - { - return 0; //no need to visit more than once per frame - } + llassert(results != NULL && for_select); #if LL_OCTREE_PARANOIA_CHECK ((LLSpatialGroup*)mOctree->getListener(0))->checkStates(); @@ -2070,19 +2024,34 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector* result ((LLSpatialGroup*)mOctree->getListener(0))->validate(); #endif + LLOctreeSelect selecter(&camera, results); + selecter.traverse(mOctree); - if (for_select && !is_vo_cache_part) + return 0; +} + +S32 LLSpatialPartition::cull(LLCamera &camera) +{ +#if LL_OCTREE_PARANOIA_CHECK + ((LLSpatialGroup*)mOctree->getListener(0))->checkStates(); +#endif { - LLOctreeSelect selecter(&camera, results); - selecter.traverse(mOctree); + LLFastTimer ftm(FTM_CULL_REBOUND); + LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); + group->rebound(); } - else if (LLPipeline::sShadowRender && !is_vo_cache_part) + +#if LL_OCTREE_PARANOIA_CHECK + ((LLSpatialGroup*)mOctree->getListener(0))->validate(); +#endif + + if (LLPipeline::sShadowRender) { LLFastTimer ftm(FTM_FRUSTUM_CULL); LLOctreeCullShadow culler(&camera); culler.traverse(mOctree); } - else if ((mInfiniteFarClip || !LLPipeline::sUseFarClip) && !is_vo_cache_part) + else if (mInfiniteFarClip || !LLPipeline::sUseFarClip) { LLFastTimer ftm(FTM_FRUSTUM_CULL); LLOctreeCullNoFarClip culler(&camera); @@ -2090,11 +2059,6 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector* result } else { - if(is_vo_cache_part) - { - mVisitedTime = LLViewerOctreeEntryData::getCurrentFrame(); - } - LLFastTimer ftm(FTM_FRUSTUM_CULL); LLOctreeCull culler(&camera); culler.traverse(mOctree); @@ -4663,21 +4627,3 @@ void LLCullResult::assertDrawMapsEmpty() } } -LLVOCachePartition::LLVOCachePartition(LLViewerRegion* regionp) : LLSpatialPartition(0, FALSE, 0, regionp) -{ - mPartitionType = LLViewerRegion::PARTITION_VO_CACHE; -} - -void LLVOCachePartition::addEntry(LLViewerOctreeEntry* entry) -{ - llassert(entry->hasVOCacheEntry()); - - mOctree->insert(entry); -} - -void LLVOCachePartition::removeEntry(LLViewerOctreeEntry* entry) -{ - entry->getVOCacheEntry()->setGroup(NULL); - - llassert(!entry->getGroup()); -} diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index dd189d751d..079c0f58f0 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -45,6 +45,7 @@ #define SG_STATE_INHERIT_MASK (OCCLUDED) #define SG_INITIAL_STATE_MASK (DIRTY | GEOM_DIRTY) +class LLViewerOctreePartition; class LLSpatialPartition; class LLSpatialBridge; class LLSpatialGroup; @@ -225,10 +226,7 @@ public: typedef std::map draw_map_t; typedef std::vector > buffer_list_t; typedef std::map buffer_texture_map_t; - typedef std::map buffer_map_t; - - typedef LLOctreeNode::element_iter element_iter; - typedef LLOctreeNode::element_list element_list; + typedef std::map buffer_map_t; struct CompareDistanceGreater { @@ -308,9 +306,7 @@ public: BOOL addObject(LLDrawable *drawablep); BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE); BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group - BOOL isVisible() const; BOOL isRecentlyVisible() const; - void setVisible(); void shift(const LLVector4a &offset); void checkOcclusion(); //read back last occlusion query (if any) void doOcclusion(LLCamera* camera); //issue occlusion query @@ -325,14 +321,7 @@ public: void setState(U32 state) {mState |= state;} void dirtyGeom() { setState(GEOM_DIRTY); } - void dirtyMesh() { setState(MESH_DIRTY); } - - //octree wrappers to make code more readable - element_list& getData() { return mOctreeNode->getData(); } - element_iter getDataBegin() { return mOctreeNode->getDataBegin(); } - element_iter getDataEnd() { return mOctreeNode->getDataEnd(); } - U32 getElementCount() const { return mOctreeNode->getElementCount(); } - bool isEmpty() const { return mOctreeNode->isEmpty(); } + void dirtyMesh() { setState(MESH_DIRTY); } void drawObjectBox(LLColor4 col); @@ -404,8 +393,7 @@ public: U32 mBufferUsage; draw_map_t mDrawMap; - - S32 mVisible[LLViewerCamera::NUM_CAMERAS]; + F32 mDistance; F32 mDepth; F32 mLastUpdateDistance; @@ -428,7 +416,7 @@ public: virtual LLVertexBuffer* createVertexBuffer(U32 type_mask, U32 usage); }; -class LLSpatialPartition: public LLGeometryManager +class LLSpatialPartition: public LLViewerOctreePartition, public LLGeometryManager { public: LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mBufferUsage, LLViewerRegion* regionp); @@ -458,7 +446,8 @@ public: virtual void rebuildMesh(LLSpatialGroup* group); BOOL visibleObjectsInFrustum(LLCamera& camera); - S32 cull(LLCamera &camera, std::vector* results = NULL, BOOL for_select = FALSE); // Cull on arbitrary frustum + /*virtual*/ S32 cull(LLCamera &camera); // Cull on arbitrary frustum + S32 cull(LLCamera &camera, std::vector* results, BOOL for_select); // Cull on arbitrary frustum BOOL isVisible(const LLVector3& v); bool isHUDPartition() ; @@ -473,26 +462,21 @@ public: void resetVertexBuffers(); BOOL isOcclusionEnabled(); BOOL getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax); - BOOL isVOCachePartition() const; - + public: - 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; + U32 mDrawableType; const BOOL mRenderByGroup; U32 mLODSeed; U32 mLODPeriod; //number of frames between LOD updates for a given spatial group (staggered by mLODSeed) U32 mVertexDataMask; F32 mSlopRatio; //percentage distance must change before drawables receive LOD update (default is 0.25); - BOOL mDepthMask; //if TRUE, objects in this partition will be written to depth during alpha rendering - U32 mDrawableType; - U32 mPartitionType; - U32 mVisitedTime; - LLViewerRegion* mRegionp; // the region this partition belongs to. + BOOL mDepthMask; //if TRUE, objects in this partition will be written to depth during alpha rendering }; // class for creating bridges between spatial partitions @@ -638,19 +622,6 @@ public: LLVoidWaterPartition(LLViewerRegion* regionp); }; -//spatial partition for hole and edge water (implemented in LLVOWater.cpp) -class LLVOCachePartition : public LLSpatialPartition -{ -public: - LLVOCachePartition(LLViewerRegion* regionp); - - void addEntry(LLViewerOctreeEntry* entry); - void removeEntry(LLViewerOctreeEntry* entry); - - virtual void getGeometry(LLSpatialGroup* group) { } - virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { } -}; - //spatial partition for terrain (impelmented in LLVOSurfacePatch.cpp) class LLTerrainPartition : public LLSpatialPartition { diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp index 05f977036c..143f2a6819 100644 --- a/indra/newview/llvieweroctree.cpp +++ b/indra/newview/llvieweroctree.cpp @@ -26,6 +26,7 @@ #include "llviewerprecompiledheaders.h" #include "llvieweroctree.h" +#include "llviewerregion.h" //----------------------------------------------------------------------------------- //static variables definitions @@ -324,6 +325,10 @@ void LLViewerOctreeEntryData::setVisible() const LLviewerOctreeGroup::~LLviewerOctreeGroup() { + if(LLViewerRegion::sCurRegionp && isVisible()) + { + LLViewerRegion::sCurRegionp->clearVisibleGroup(this); + } } LLviewerOctreeGroup::LLviewerOctreeGroup(OctreeNode* node) : @@ -482,8 +487,10 @@ void LLviewerOctreeGroup::handleDestruction(const TreeNode* node) if (obj && obj->getGroup() == this) { obj->nullGroup(); + //obj->setGroup(NULL); } } + mOctreeNode = NULL; } //virtual @@ -500,8 +507,17 @@ void LLviewerOctreeGroup::handleStateChange(const TreeNode* node) //virtual void LLviewerOctreeGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child) { - llerrs << "can not access here. It is an abstract class." << llendl; + if (child->getListenerCount() == 0) + { + new LLviewerOctreeGroup(child); + } + else + { + OCT_ERRS << "LLSpatialGroup redundancy detected." << llendl; + } + unbound(); + //((LLviewerOctreeGroup*)child->getListener(0))->unbound(); } @@ -589,7 +605,35 @@ bool LLviewerOctreeGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4 //virtual BOOL LLviewerOctreeGroup::isVisible() const { - return TRUE; + return mVisible[LLViewerCamera::sCurCameraID] >= LLViewerOctreeEntryData::getCurrentFrame() ? TRUE : FALSE; +} + +//virtual +BOOL LLviewerOctreeGroup::isRecentlyVisible() const +{ + return FALSE; +} + +void LLviewerOctreeGroup::setVisible() +{ + mVisible[LLViewerCamera::sCurCameraID] = LLViewerOctreeEntryData::getCurrentFrame(); +} +//----------------------------------------------------------------------------------- +//class LLViewerOctreePartition definitions +//----------------------------------------------------------------------------------- +LLViewerOctreePartition::LLViewerOctreePartition() : mRegionp(NULL) +{ + LLVector4a center, size; + center.splat(0.f); + size.splat(1.f); + + mOctree = new OctreeRoot(center,size, NULL); +} + +LLViewerOctreePartition::~LLViewerOctreePartition() +{ + delete mOctree; + mOctree = NULL; } //----------------------------------------------------------------------------------- diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h index c063e96ea5..498ec3e75d 100644 --- a/indra/newview/llvieweroctree.h +++ b/indra/newview/llvieweroctree.h @@ -37,8 +37,9 @@ #include "llvector4a.h" #include "llquaternion.h" #include "lloctree.h" -#include "llcamera.h" +#include "llviewercamera.h" +class LLViewerRegion; class LLViewerOctreeEntryData; class LLviewerOctreeGroup; class LLViewerOctreeEntry; @@ -181,6 +182,9 @@ public: }; public: + typedef LLOctreeNode::element_iter element_iter; + typedef LLOctreeNode::element_list element_list; + LLviewerOctreeGroup(OctreeNode* node); LLviewerOctreeGroup(const LLviewerOctreeGroup& rhs) { @@ -203,8 +207,10 @@ public: virtual void unbound(); virtual void rebound(); - virtual BOOL isVisible() const; - virtual BOOL isRecentlyVisible() const = 0; + void setVisible(); + BOOL isVisible() const; + virtual BOOL isRecentlyVisible() const; + bool isEmpty() const { return mOctreeNode->isEmpty(); } U32 getState() {return mState; } bool isDirty() const {return mState & DIRTY;} @@ -228,20 +234,43 @@ public: const LLVector4a* getObjectBounds() const {return mObjectBounds;} const LLVector4a* getObjectExtents() const {return mObjectExtents;} + //octree wrappers to make code more readable + element_list& getData() { return mOctreeNode->getData(); } + element_iter getDataBegin() { return mOctreeNode->getDataBegin(); } + element_iter getDataEnd() { return mOctreeNode->getDataEnd(); } + U32 getElementCount() const { return mOctreeNode->getElementCount(); } + private: virtual bool boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut); protected: U32 mState; - OctreeNode* mOctreeNode; - + OctreeNode* mOctreeNode; + LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects) LL_ALIGN_16(LLVector4a mObjectBounds[2]); // bounding box (center, size) of objects in this node LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children LL_ALIGN_16(LLVector4a mObjectExtents[2]); // extents (min, max) of objects in this node +public: + S32 mVisible[LLViewerCamera::NUM_CAMERAS]; }LL_ALIGN_POSTFIX(16); +class LLViewerOctreePartition +{ +public: + LLViewerOctreePartition(); + virtual ~LLViewerOctreePartition(); + + // Cull on arbitrary frustum + virtual S32 cull(LLCamera &camera) = 0; + +public: + U32 mPartitionType; + OctreeNode* mOctree; + LLViewerRegion* mRegionp; // the region this partition belongs to. +}; + class LLViewerOctreeCull : public OctreeTraveler { public: diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 0c0522d32f..1adab15d70 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -86,6 +86,8 @@ const F32 CAP_REQUEST_TIMEOUT = 18; // Even though we gave up on login, keep trying for caps after we are logged in: const S32 MAX_CAP_REQUEST_ATTEMPTS = 30; +LLViewerRegion* LLViewerRegion::sCurRegionp = NULL; + typedef std::map CapabilityMap; class LLViewerRegionImpl { @@ -139,7 +141,7 @@ public: LLVOCacheEntry::vocache_entry_set_t mWaitingSet; //entries waiting for LLDrawable to be generated. LLVOCacheEntry::vocache_entry_set_t mVisibleEntries; //visible root entries of a linked set. std::set< LLPointer > mDummyEntries; //dummy vo cache entries, for LLSpatialBridge use. - std::set< LLSpatialGroup* > mVisibleGroups; //visible llspatialgroup + std::set< LLviewerOctreeGroup* > mVisibleGroups; //visible llspatialgroup LLVOCachePartition* mVOCachePartition; // time? @@ -165,7 +167,7 @@ public: LLCapabilityListener mCapabilityListener; //spatial partitions for objects in this region - std::vector mObjectPartition; + std::vector mObjectPartition; }; // support for secondlife:///app/region/{REGION} SLapps @@ -345,7 +347,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, mImpl->mObjectPartition.push_back(new LLVOCachePartition(this)); //PARTITION_VO_CACHE mImpl->mObjectPartition.push_back(NULL); //PARTITION_NONE - mImpl->mVOCachePartition = (LLVOCachePartition*)getSpatialPartition(PARTITION_VO_CACHE); + mImpl->mVOCachePartition = getVOCachePartition(); } @@ -384,12 +386,12 @@ LLViewerRegion::~LLViewerRegion() delete mParcelOverlay; delete mImpl->mLandp; delete mImpl->mEventPoll; - LLHTTPSender::clearSender(mImpl->mHost); - - saveObjectCache(); + LLHTTPSender::clearSender(mImpl->mHost); std::for_each(mImpl->mObjectPartition.begin(), mImpl->mObjectPartition.end(), DeletePointer()); + saveObjectCache(); + delete mImpl; mImpl = NULL; } @@ -865,13 +867,13 @@ void LLViewerRegion::removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* d entry->setState(LLVOCacheEntry::INACTIVE); } -void LLViewerRegion::addVisibleGroup(LLSpatialGroup* group) +void LLViewerRegion::addVisibleGroup(LLviewerOctreeGroup* group) { - if(mDead || group->isEmpty() || group->isDead()) + if(mDead || group->isEmpty()) { return; } - + group->setVisible(); mImpl->mVisibleGroups.insert(group); } @@ -909,7 +911,7 @@ void LLViewerRegion::addVisibleCacheEntry(LLVOCacheEntry* entry) mImpl->mVisibleEntries.insert(entry); } -void LLViewerRegion::clearVisibleGroup(LLSpatialGroup* group) +void LLViewerRegion::clearVisibleGroup(LLviewerOctreeGroup* group) { if(mDead) { @@ -920,44 +922,18 @@ void LLViewerRegion::clearVisibleGroup(LLSpatialGroup* group) mImpl->mVisibleGroups.erase(group); } - -BOOL LLViewerRegion::idleUpdate(F32 max_update_time) -{ - LLTimer update_timer; - - // did_update returns TRUE if we did at least one significant update - BOOL did_update = mImpl->mLandp->idleUpdate(max_update_time); - if (mParcelOverlay) - { - // Hopefully not a significant time sink... - mParcelOverlay->idleUpdate(); - } - - if(update_timer.getElapsedTimeF32() > max_update_time) - { - return did_update; - } - - //kill invisible objects - std::vector delete_list; - for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.begin(); - iter != mImpl->mActiveSet.end(); ++iter) - { - if(!(*iter)->isRecentlyVisible()) - { - killObject((*iter), delete_list); - } - } - for(S32 i = 0; i < delete_list.size(); i++) +//return time left +F32 LLViewerRegion::addLinkedSetChildren(F32 max_time, S32& max_num_objects) +{ + if(mImpl->mVisibleEntries.empty()) { - gObjectList.killObject(delete_list[i]->getVObj()); + return max_time; } - delete_list.clear(); + LLTimer update_timer; bool timeout = false; - S32 new_object_count = 64; //minimum number of new objects to be added - //add childrens of visible objects to the rendering pipeline + for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mVisibleEntries.begin(); iter != mImpl->mVisibleEntries.end();) { LLVOCacheEntry* entry = *iter; @@ -968,9 +944,9 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) { addNewObject(child); - if(new_object_count-- < 0 && update_timer.getElapsedTimeF32() > max_update_time) + if(max_num_objects-- < 0 && update_timer.getElapsedTimeF32() > max_time) { - timeout = true; + timeout = true; //timeout break; } } @@ -982,7 +958,10 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) { mImpl->mDummyEntries.erase(entry); } - + } + + if(!timeout) + { iter = mImpl->mVisibleEntries.erase(iter); } else @@ -990,17 +969,28 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) break; //timeout } } + if(timeout) { - mImpl->mVisibleGroups.clear(); - return did_update; + return -1.f; } + return max_time - update_timer.getElapsedTimeF32(); //time left +} - //add objects in the visible groups to the rendering pipeline - std::set< LLSpatialGroup* >::iterator group_iter = mImpl->mVisibleGroups.begin(); +F32 LLViewerRegion::addVisibleObjects(F32 max_time, S32& max_num_objects) +{ + if(mImpl->mVisibleGroups.empty()) + { + return max_time; + } + + LLTimer update_timer; + bool timeout = false; + + std::set< LLviewerOctreeGroup* >::iterator group_iter = mImpl->mVisibleGroups.begin(); while(group_iter != mImpl->mVisibleGroups.end()) { - LLSpatialGroup* group = *group_iter; + LLviewerOctreeGroup* group = *group_iter; if(!group->getOctreeNode() || group->isEmpty()) { mImpl->mVisibleGroups.erase(group_iter); @@ -1009,7 +999,7 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) } std::vector entry_list; - for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) + for (LLviewerOctreeGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { //group data contents could change during creating new objects, so copy all contents first. entry_list.push_back(*i); @@ -1028,7 +1018,7 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) else if(vo_entry->isState(LLVOCacheEntry::INACTIVE)) { addNewObject(vo_entry); - if(new_object_count-- < 0 && update_timer.getElapsedTimeF32() > max_update_time) + if(max_num_objects-- < 0 && update_timer.getElapsedTimeF32() > max_time) { timeout = true; break; @@ -1044,12 +1034,75 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) } mImpl->mVisibleGroups.erase(group); group_iter = mImpl->mVisibleGroups.begin(); + } + + if(timeout) + { + return -1.0f; } - mImpl->mVisibleGroups.clear(); + return max_time - update_timer.getElapsedTimeF32(); +} + +BOOL LLViewerRegion::idleUpdate(F32 max_update_time) +{ + LLTimer update_timer; + // did_update returns TRUE if we did at least one significant update + BOOL did_update = mImpl->mLandp->idleUpdate(max_update_time); + + if (mParcelOverlay) + { + // Hopefully not a significant time sink... + mParcelOverlay->idleUpdate(); + } + + max_update_time -= update_timer.getElapsedTimeF32(); + if(max_update_time < 0.f) + { + return did_update; + } + + sCurRegionp = this; + + //kill invisible objects + max_update_time = killInvisibleObjects(max_update_time); + + S32 new_object_count = 64; //minimum number of new objects to be added + + //add childrens of visible objects to the rendering pipeline + max_update_time = addLinkedSetChildren(max_update_time, new_object_count); + + //add objects in the visible groups to the rendering pipeline + if(max_update_time > 0.f) + { + addVisibleObjects(max_update_time, new_object_count); + } + + mImpl->mVisibleGroups.clear(); + sCurRegionp = NULL; return did_update; } +F32 LLViewerRegion::killInvisibleObjects(F32 max_time) +{ + std::vector delete_list; + for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.begin(); + iter != mImpl->mActiveSet.end(); ++iter) + { + if(!(*iter)->isRecentlyVisible()) + { + killObject((*iter), delete_list); + } + } + for(S32 i = 0; i < delete_list.size(); i++) + { + gObjectList.killObject(delete_list[i]->getVObj()); + } + delete_list.clear(); + + return max_time; +} + void LLViewerRegion::killObject(LLVOCacheEntry* entry, std::vector& delete_list) { //kill the object. @@ -2189,9 +2242,18 @@ void LLViewerRegion::logActiveCapabilities() const LLSpatialPartition* LLViewerRegion::getSpatialPartition(U32 type) { - if (type < mImpl->mObjectPartition.size()) + if (type < mImpl->mObjectPartition.size() && type < PARTITION_VO_CACHE) + { + return (LLSpatialPartition*)mImpl->mObjectPartition[type]; + } + return NULL; +} + +LLVOCachePartition* LLViewerRegion::getVOCachePartition() +{ + if(PARTITION_VO_CACHE < mImpl->mObjectPartition.size()) { - return mImpl->mObjectPartition[type]; + return (LLVOCachePartition*)mImpl->mObjectPartition[PARTITION_VO_CACHE]; } return NULL; } diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 17654a8bc7..86d3ee0d8c 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -69,6 +69,8 @@ class LLBBox; class LLSpatialGroup; class LLDrawable; class LLViewerRegionImpl; +class LLviewerOctreeGroup; +class LLVOCachePartition; class LLViewerRegion: public LLCapabilityProvider // implements this interface { @@ -85,7 +87,7 @@ public: PARTITION_GRASS, PARTITION_VOLUME, PARTITION_BRIDGE, - PARTITION_HUD_PARTICLE, + PARTITION_HUD_PARTICLE, PARTITION_VO_CACHE, PARTITION_NONE, NUM_PARTITIONS @@ -218,12 +220,12 @@ public: F32 getWidth() const { return mWidth; } BOOL idleUpdate(F32 max_update_time); - void addVisibleGroup(LLSpatialGroup* group); + void addVisibleGroup(LLviewerOctreeGroup* group); void addVisibleCacheEntry(LLVOCacheEntry* entry); void addActiveCacheEntry(LLVOCacheEntry* entry); void removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep); void killCacheEntry(U32 local_id); //physically delete the cache entry - void clearVisibleGroup(LLSpatialGroup* group); + void clearVisibleGroup(LLviewerOctreeGroup* group); // Like idleUpdate, but forces everything to complete regardless of // how long it takes. @@ -333,6 +335,7 @@ public: U32 getNumOfActiveCachedObjects() const; LLSpatialPartition* getSpatialPartition(U32 type); + LLVOCachePartition* getVOCachePartition(); bool objectIsReturnable(const LLVector3& pos, const std::vector& boxes) const; bool childrenObjectReturnable( const std::vector& boxes ) const; @@ -350,6 +353,10 @@ private: void replaceCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry); void killCacheEntry(LLVOCacheEntry* entry); //physically delete the cache entry + F32 killInvisibleObjects(F32 max_time); + F32 addLinkedSetChildren(F32 max_time, S32& max_num_objects); + F32 addVisibleObjects(F32 max_time, S32& max_num_objects); + public: struct CompareDistance { @@ -384,6 +391,7 @@ public: LLDynamicArray mMapAvatars; LLDynamicArray mMapAvatarIDs; + static LLViewerRegion* sCurRegionp; private: LLViewerRegionImpl * mImpl; diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index f389867484..d4938fd216 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -31,6 +31,7 @@ #include "llviewercontrol.h" #include "llviewerobjectlist.h" #include "lldrawable.h" +#include "llviewerregion.h" BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes) { @@ -355,6 +356,82 @@ BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const return success ; } +//------------------------------------------------------------------- +//LLVOCachePartition +//------------------------------------------------------------------- +LLVOCachePartition::LLVOCachePartition(LLViewerRegion* regionp) +{ + mRegionp = regionp; + mPartitionType = LLViewerRegion::PARTITION_VO_CACHE; + mVisitedTime = 0; + + new LLviewerOctreeGroup(mOctree); +} + +void LLVOCachePartition::addEntry(LLViewerOctreeEntry* entry) +{ + llassert(entry->hasVOCacheEntry()); + + mOctree->insert(entry); +} + +void LLVOCachePartition::removeEntry(LLViewerOctreeEntry* entry) +{ + entry->getVOCacheEntry()->setGroup(NULL); + + llassert(!entry->getGroup()); +} + +class LLVOCacheOctreeCull : public LLViewerOctreeCull +{ +public: + LLVOCacheOctreeCull(LLCamera* camera, LLViewerRegion* regionp) : LLViewerOctreeCull(camera), mRegionp(regionp) {} + + virtual S32 frustumCheck(const LLviewerOctreeGroup* group) + { + S32 res = AABBInFrustumNoFarClipGroupBounds(group); + if (res != 0) + { + res = llmin(res, AABBSphereIntersectGroupExtents(group)); + } + return res; + } + + virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group) + { + S32 res = AABBInFrustumNoFarClipObjectBounds(group); + if (res != 0) + { + res = llmin(res, AABBSphereIntersectObjectExtents(group)); + } + return res; + } + + virtual void processGroup(LLviewerOctreeGroup* base_group) + { + mRegionp->addVisibleGroup(base_group); + } + +private: + LLViewerRegion* mRegionp; +}; + +S32 LLVOCachePartition::cull(LLCamera &camera) +{ + if(mVisitedTime == LLViewerOctreeEntryData::getCurrentFrame()) + { + return 0; //already visited. + } + mVisitedTime = LLViewerOctreeEntryData::getCurrentFrame(); + + ((LLviewerOctreeGroup*)mOctree->getListener(0))->rebound(); + + LLVOCacheOctreeCull culler(&camera, mRegionp); + culler.traverse(mOctree); + + return 0; +} + //------------------------------------------------------------------- //LLVOCache //------------------------------------------------------------------- diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h index 2228e3e43b..675c12a3eb 100644 --- a/indra/newview/llvocache.h +++ b/indra/newview/llvocache.h @@ -98,6 +98,19 @@ protected: std::vector mChildrenList; //children entries in a linked set. }; +class LLVOCachePartition : public LLViewerOctreePartition +{ +public: + LLVOCachePartition(LLViewerRegion* regionp); + + void addEntry(LLViewerOctreeEntry* entry); + void removeEntry(LLViewerOctreeEntry* entry); + /*virtual*/ S32 cull(LLCamera &camera); + +private: + U32 mVisitedTime; +}; + // //Note: LLVOCache is not thread-safe // diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index e06577c512..850714f676 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -86,6 +86,7 @@ #include "llviewerregion.h" // for audio debugging. #include "llviewerwindow.h" // For getSpinAxis #include "llvoavatarself.h" +#include "llvocache.h" #include "llvoground.h" #include "llvosky.h" #include "llvotree.h" @@ -2352,12 +2353,15 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl { part->cull(camera); } - else if(part->mPartitionType == LLViewerRegion::PARTITION_VO_CACHE) - { - part->cull(camera); - } } } + + //scan the VO Cache tree + LLVOCachePartition* vo_part = region->getVOCachePartition(); + if(vo_part) + { + vo_part->cull(camera); + } } if (bound_shader) @@ -2433,12 +2437,8 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) } assertInitialized(); - - if(group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_VO_CACHE) - { - group->mSpatialPartition->mRegionp->addVisibleGroup(group); - } - else if (!group->mSpatialPartition->mRenderByGroup) + + if (!group->mSpatialPartition->mRenderByGroup) { //render by drawable sCull->pushDrawableGroup(group); } -- cgit v1.3 From 819adb5eb4d7f982121f3dbd82750e05d26864d9 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 1 Nov 2012 00:26:44 -0700 Subject: SH-3405 FIX convert existing stats to lltrace system final removal of remaining LLStat code --- indra/llcommon/CMakeLists.txt | 2 - indra/llcommon/llinstancetracker.h | 10 +- indra/llcommon/llmetricperformancetester.cpp | 1 - indra/llcommon/llpredicate.h | 4 + indra/llcommon/llstat.cpp | 352 ---------------------- indra/llcommon/llstat.h | 103 ------- indra/llcommon/lltrace.h | 90 ++++-- indra/llcommon/lltracerecording.cpp | 119 +++++++- indra/llcommon/lltracerecording.h | 216 +++++++------ indra/llcommon/lltracethreadrecorder.cpp | 4 + indra/llui/llstatbar.cpp | 138 ++++++--- indra/llui/llstatbar.h | 11 +- indra/llui/llstatgraph.cpp | 20 +- indra/llui/llstatgraph.h | 13 +- indra/llvfs/llvfile.cpp | 2 +- indra/lscript/lscript_execute/lscript_execute.cpp | 1 - indra/newview/llagentcamera.cpp | 4 +- indra/newview/llappviewer.cpp | 3 + indra/newview/llfasttimerview.cpp | 1 - indra/newview/llfloaterjoystick.cpp | 17 +- indra/newview/llfloaterjoystick.h | 1 - indra/newview/llhudnametag.cpp | 5 +- indra/newview/llstatusbar.cpp | 4 +- indra/newview/llsurface.h | 1 - indra/newview/lltexturefetch.cpp | 10 +- indra/newview/lltexturefetch.h | 7 +- indra/newview/llviewercamera.cpp | 13 +- indra/newview/llviewercamera.h | 28 +- indra/newview/llviewerdisplay.cpp | 6 +- indra/newview/llviewermessage.cpp | 22 -- indra/newview/llviewerobjectlist.cpp | 4 +- indra/newview/llviewerobjectlist.h | 4 +- indra/newview/llviewerregion.cpp | 9 +- indra/newview/llviewerregion.h | 6 +- indra/newview/llviewerstats.cpp | 33 +- indra/newview/llviewerstats.h | 1 - indra/newview/llviewertexturelist.h | 1 - indra/newview/llviewerwindow.cpp | 11 +- indra/newview/llviewerwindow.h | 7 +- indra/newview/llvoavatar.cpp | 6 - indra/newview/llworld.cpp | 17 +- indra/newview/pipeline.cpp | 6 +- 42 files changed, 543 insertions(+), 770 deletions(-) delete mode 100644 indra/llcommon/llstat.cpp delete mode 100644 indra/llcommon/llstat.h (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index d876842cf1..0f5ded86ed 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -91,7 +91,6 @@ set(llcommon_SOURCE_FILES llsdutil.cpp llsecondlifeurls.cpp llsingleton.cpp - llstat.cpp llstacktrace.cpp llstreamqueue.cpp llstreamtools.cpp @@ -234,7 +233,6 @@ set(llcommon_HEADER_FILES llsortedvector.h llstack.h llstacktrace.h - llstat.h llstatenums.h llstl.h llstreamqueue.h diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index 403df08990..3a1187a4c1 100644 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -77,8 +77,8 @@ protected: /// This mix-in class adds support for tracking all instances of the specified class parameter T /// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup /// If KEY is not provided, then instances are stored in a simple set -/// @NOTE: see explicit specialization below for default KEY==T* case -template +/// @NOTE: see explicit specialization below for default KEY==void case +template class LLInstanceTracker : public LLInstanceTrackerBase { typedef LLInstanceTracker MyT; @@ -224,12 +224,12 @@ private: KEY mInstanceKey; }; -/// explicit specialization for default case where KEY is T* +/// explicit specialization for default case where KEY is void /// use a simple std::set template -class LLInstanceTracker : public LLInstanceTrackerBase +class LLInstanceTracker : public LLInstanceTrackerBase { - typedef LLInstanceTracker MyT; + typedef LLInstanceTracker MyT; typedef typename std::set InstanceSet; struct StaticData: public StaticBase { diff --git a/indra/llcommon/llmetricperformancetester.cpp b/indra/llcommon/llmetricperformancetester.cpp index 41d3eb0bf3..a1b0a684c5 100644 --- a/indra/llcommon/llmetricperformancetester.cpp +++ b/indra/llcommon/llmetricperformancetester.cpp @@ -29,7 +29,6 @@ #include "indra_constants.h" #include "llerror.h" #include "llsdserialize.h" -#include "llstat.h" #include "lltreeiterators.h" #include "llmetricperformancetester.h" diff --git a/indra/llcommon/llpredicate.h b/indra/llcommon/llpredicate.h index 3f1bf1c8e6..75744667d9 100644 --- a/indra/llcommon/llpredicate.h +++ b/indra/llcommon/llpredicate.h @@ -165,6 +165,10 @@ namespace LLPredicate : Literal(e) {} + Value(const Literal other) + : Literal(other) + {} + Value() {} }; diff --git a/indra/llcommon/llstat.cpp b/indra/llcommon/llstat.cpp deleted file mode 100644 index b46d2e58b2..0000000000 --- a/indra/llcommon/llstat.cpp +++ /dev/null @@ -1,352 +0,0 @@ -/** - * @file llstat.cpp - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, 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 "linden_common.h" - -#include "llstat.h" -#include "lllivefile.h" -#include "llerrorcontrol.h" -#include "llframetimer.h" -#include "timing.h" -#include "llsd.h" -#include "llsdserialize.h" -#include "llstl.h" -#include "u64.h" - - -// statics -//------------------------------------------------------------------------ -LLTimer LLStat::sTimer; -LLFrameTimer LLStat::sFrameTimer; - -void LLStat::reset() -{ - mNumValues = 0; - mLastValue = 0.f; - delete[] mBins; - mBins = new ValueEntry[mNumBins]; - mCurBin = mNumBins-1; - mNextBin = 0; -} - -LLStat::LLStat(std::string name, BOOL use_frame_timer) -: LLInstanceTracker(name), - mUseFrameTimer(use_frame_timer), - mNumBins(50), - mName(name), - mBins(NULL) -{ - llassert(mNumBins > 0); - mLastTime = 0.f; - - reset(); -} - -LLStat::~LLStat() -{ - delete[] mBins; -} -// -//void LLStat::start() -//{ -// if (mUseFrameTimer) -// { -// mBins[mNextBin].mBeginTime = sFrameTimer.getElapsedSeconds(); -// } -// else -// { -// mBins[mNextBin].mBeginTime = sTimer.getElapsedTimeF64(); -// } -//} - -void LLStat::addValue(const F32 value) -{ - if (mNumValues < mNumBins) - { - mNumValues++; - } - - // Increment the bin counters. - mCurBin++; - if (mCurBin >= mNumBins) - { - mCurBin = 0; - } - mNextBin++; - if (mNextBin >= mNumBins) - { - mNextBin = 0; - } - - mBins[mCurBin].mValue = value; - if (mUseFrameTimer) - { - mBins[mCurBin].mTime = sFrameTimer.getElapsedSeconds(); - } - else - { - mBins[mCurBin].mTime = sTimer.getElapsedTimeF64(); - } - mBins[mCurBin].mDT = (F32)(mBins[mCurBin].mTime - mBins[mCurBin].mBeginTime); - - //this value is used to prime the min/max calls - mLastTime = mBins[mCurBin].mTime; - mLastValue = value; - - // Set the begin time for the next stat segment. - mBins[mNextBin].mBeginTime = mBins[mCurBin].mTime; - mBins[mNextBin].mTime = mBins[mCurBin].mTime; - mBins[mNextBin].mDT = 0.f; -} - - -F32 LLStat::getMax() const -{ - S32 i; - F32 current_max = mLastValue; - if (mNumBins == 0) - { - current_max = 0.f; - } - else - { - for (i = 0; (i < mNumBins) && (i < mNumValues); i++) - { - // Skip the bin we're currently filling. - if (i == mNextBin) - { - continue; - } - if (mBins[i].mValue > current_max) - { - current_max = mBins[i].mValue; - } - } - } - return current_max; -} - -F32 LLStat::getMean() const -{ - S32 i; - F32 current_mean = 0.f; - S32 samples = 0; - for (i = 0; (i < mNumBins) && (i < mNumValues); i++) - { - // Skip the bin we're currently filling. - if (i == mNextBin) - { - continue; - } - current_mean += mBins[i].mValue; - samples++; - } - - // There will be a wrap error at 2^32. :) - if (samples != 0) - { - current_mean /= samples; - } - else - { - current_mean = 0.f; - } - return current_mean; -} - -F32 LLStat::getMin() const -{ - S32 i; - F32 current_min = mLastValue; - - if (mNumBins == 0) - { - current_min = 0.f; - } - else - { - for (i = 0; (i < mNumBins) && (i < mNumValues); i++) - { - // Skip the bin we're currently filling. - if (i == mNextBin) - { - continue; - } - if (mBins[i].mValue < current_min) - { - current_min = mBins[i].mValue; - } - } - } - return current_min; -} - -F32 LLStat::getPrev(S32 age) const -{ - S32 bin; - bin = mCurBin - age; - - while (bin < 0) - { - bin += mNumBins; - } - - if (bin == mNextBin) - { - // Bogus for bin we're currently working on. - return 0.f; - } - return mBins[bin].mValue; -} - -F32 LLStat::getPrevPerSec(S32 age) const -{ - S32 bin; - bin = mCurBin - age; - - while (bin < 0) - { - bin += mNumBins; - } - - if (bin == mNextBin) - { - // Bogus for bin we're currently working on. - return 0.f; - } - return mBins[bin].mValue / mBins[bin].mDT; -} - -F32 LLStat::getCurrent() const -{ - return mBins[mCurBin].mValue; -} - -F32 LLStat::getCurrentPerSec() const -{ - return mBins[mCurBin].mValue / mBins[mCurBin].mDT; -} - -F32 LLStat::getMeanPerSec() const -{ - S32 i; - F32 value = 0.f; - F32 dt = 0.f; - - for (i = 0; (i < mNumBins) && (i < mNumValues); i++) - { - // Skip the bin we're currently filling. - if (i == mNextBin) - { - continue; - } - value += mBins[i].mValue; - dt += mBins[i].mDT; - } - - if (dt > 0.f) - { - return value/dt; - } - else - { - return 0.f; - } -} - -F32 LLStat::getMaxPerSec() const -{ - F32 value; - - if (mNextBin != 0) - { - value = mBins[0].mValue/mBins[0].mDT; - } - else if (mNumValues > 0) - { - value = mBins[1].mValue/mBins[1].mDT; - } - else - { - value = 0.f; - } - - for (S32 i = 0; (i < mNumBins) && (i < mNumValues); i++) - { - // Skip the bin we're currently filling. - if (i == mNextBin) - { - continue; - } - value = llmax(value, mBins[i].mValue/mBins[i].mDT); - } - return value; -} - -F32 LLStat::getMinPerSec() const -{ - S32 i; - F32 value; - - if (mNextBin != 0) - { - value = mBins[0].mValue/mBins[0].mDT; - } - else if (mNumValues > 0) - { - value = mBins[1].mValue/mBins[0].mDT; - } - else - { - value = 0.f; - } - - for (i = 0; (i < mNumBins) && (i < mNumValues); i++) - { - // Skip the bin we're currently filling. - if (i == mNextBin) - { - continue; - } - value = llmin(value, mBins[i].mValue/mBins[i].mDT); - } - return value; -} - -U32 LLStat::getNumValues() const -{ - return mNumValues; -} - -S32 LLStat::getNumBins() const -{ - return mNumBins; -} - -S32 LLStat::getNextBin() const -{ - return mNextBin; -} - diff --git a/indra/llcommon/llstat.h b/indra/llcommon/llstat.h deleted file mode 100644 index 82a246275d..0000000000 --- a/indra/llcommon/llstat.h +++ /dev/null @@ -1,103 +0,0 @@ -/** - * @file llstat.h - * @brief Runtime statistics accumulation. - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, 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$ - */ - -#ifndef LL_LLSTAT_H -#define LL_LLSTAT_H - -#include - -#include "lltimer.h" -#include "llframetimer.h" -#include "llinstancetracker.h" - -class LLSD; - -// ---------------------------------------------------------------------------- -class LL_COMMON_API LLStat : public LLInstanceTracker -{ -public: - LLStat(std::string name = std::string(), BOOL use_frame_timer = FALSE); - ~LLStat(); - - //void start(); // Start the timer for the current "frame", otherwise uses the time tracked from - // the last addValue - void reset(); - void addValue(const F32 value = 1.f); // Adds the current value being tracked, and tracks the DT. - void addValue(const S32 value) { addValue((F32)value); } - void addValue(const U32 value) { addValue((F32)value); } - - S32 getNextBin() const; - - F32 getPrev(S32 age) const; // Age is how many "addValues" previously - zero is current - F32 getPrevPerSec(S32 age) const; // Age is how many "addValues" previously - zero is current - - F32 getCurrent() const; - F32 getCurrentPerSec() const; - - F32 getMin() const; - F32 getMinPerSec() const; - - F32 getMean() const; - F32 getMeanPerSec() const; - - F32 getMax() const; - F32 getMaxPerSec() const; - - U32 getNumValues() const; - S32 getNumBins() const; - -private: - bool mUseFrameTimer; - U32 mNumValues; - U32 mNumBins; - F32 mLastValue; - F64 mLastTime; - - struct ValueEntry - { - ValueEntry() - : mValue(0.f), - mBeginTime(0.0), - mTime(0.0), - mDT(0.f) - {} - F32 mValue; - F64 mBeginTime; - F64 mTime; - F32 mDT; - }; - ValueEntry* mBins; - - S32 mCurBin; - S32 mNextBin; - - std::string mName; - - static LLTimer sTimer; - static LLFrameTimer sFrameTimer; -}; - -#endif // LL_STAT_ diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 2cdae4b0d2..2823db5cbb 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -227,10 +227,33 @@ namespace LLTrace }; + template + struct StorageType + { + typedef T type_t; + }; + + template + struct StorageType + { + typedef typename StorageType::type_t type_t; + }; + + template<> struct StorageType { typedef F64 type_t; }; + template<> struct StorageType { typedef S64 type_t; }; + template<> struct StorageType { typedef S64 type_t; }; + template<> struct StorageType { typedef S64 type_t; }; + template<> struct StorageType { typedef S64 type_t; }; + template<> struct StorageType { typedef S64 type_t; }; + template<> struct StorageType { typedef S64 type_t; }; + template class LL_COMMON_API MeasurementAccumulator { public: + typedef T value_t; + typedef MeasurementAccumulator self_t; + MeasurementAccumulator() : mSum(0), mMin(std::numeric_limits::max()), @@ -243,23 +266,24 @@ namespace LLTrace LL_FORCE_INLINE void sample(T value) { + T storage_value(value); mNumSamples++; - mSum += value; - if (value < mMin) + mSum += storage_value; + if (storage_value < mMin) { - mMin = value; + mMin = storage_value; } - else if (value > mMax) + if (storage_value > mMax) { - mMax = value; + mMax = storage_value; } F64 old_mean = mMean; - mMean += ((F64)value - old_mean) / (F64)mNumSamples; - mVarianceSum += ((F64)value - old_mean) * ((F64)value - mMean); - mLastValue = value; + mMean += ((F64)storage_value - old_mean) / (F64)mNumSamples; + mVarianceSum += ((F64)storage_value - old_mean) * ((F64)storage_value - mMean); + mLastValue = storage_value; } - void addSamples(const MeasurementAccumulator& other) + void addSamples(const self_t& other) { mSum += other.mSum; if (other.mMin < mMin) @@ -293,7 +317,7 @@ namespace LLTrace } else { - mVarianceSum = (F32)mNumSamples + mVarianceSum = (F64)mNumSamples * ((((n_1 - 1.f) * sd_1 * sd_1) + ((n_2 - 1.f) * sd_2 * sd_2) + (((n_1 * n_2) / (n_1 + n_2)) @@ -311,10 +335,10 @@ namespace LLTrace mMax = 0; } - T getSum() const { return mSum; } - T getMin() const { return mMin; } - T getMax() const { return mMax; } - T getLastValue() const { return mLastValue; } + T getSum() const { return (T)mSum; } + T getMin() const { return (T)mMin; } + T getMax() const { return (T)mMax; } + T getLastValue() const { return (T)mLastValue; } F64 getMean() const { return mMean; } F64 getStandardDeviation() const { return sqrtf(mVarianceSum / mNumSamples); } U32 getSampleCount() const { return mNumSamples; } @@ -325,7 +349,7 @@ namespace LLTrace mMax, mLastValue; - F64 mMean, + F64 mMean, mVarianceSum; U32 mNumSamples; @@ -335,6 +359,8 @@ namespace LLTrace class LL_COMMON_API CountAccumulator { public: + typedef T value_t; + CountAccumulator() : mSum(0), mNumSamples(0) @@ -358,7 +384,7 @@ namespace LLTrace mSum = 0; } - T getSum() const { return mSum; } + T getSum() const { return (T)mSum; } private: T mSum; @@ -366,14 +392,15 @@ namespace LLTrace U32 mNumSamples; }; - typedef TraceType > measurement_common_t; + typedef TraceType > measurement_common_float_t; + typedef TraceType > measurement_common_int_t; template class LL_COMMON_API Measurement - : public TraceType > + : public TraceType::type_t> > { public: - typedef T storage_t; + typedef typename StorageType::type_t storage_t; Measurement(const char* name, const char* description = NULL) : TraceType(name, description) @@ -381,17 +408,16 @@ namespace LLTrace void sample(T value) { - getPrimaryAccumulator().sample(value); + getPrimaryAccumulator().sample((storage_t)value); } }; template class LL_COMMON_API Measurement - : public TraceType > + : public TraceType::type_t> > { public: - typedef typename T::storage_t storage_t; - typedef Measurement base_measurement_t; + typedef typename StorageType::type_t storage_t; Measurement(const char* name, const char* description = NULL) : TraceType(name, description) @@ -402,18 +428,19 @@ namespace LLTrace { T converted_value; converted_value.assignFrom(value); - getPrimaryAccumulator().sample(converted_value.value()); + getPrimaryAccumulator().sample((storage_t)converted_value.value()); } }; - typedef TraceType > count_common_t; + typedef TraceType > count_common_float_t; + typedef TraceType > count_common_int_t; template class LL_COMMON_API Count - : public TraceType > + : public TraceType::type_t> > { public: - typedef T storage_t; + typedef typename StorageType::type_t storage_t; Count(const char* name, const char* description = NULL) : TraceType(name) @@ -421,17 +448,16 @@ namespace LLTrace void add(T value) { - getPrimaryAccumulator().add(value); + getPrimaryAccumulator().add((storage_t)value); } }; template class LL_COMMON_API Count - : public TraceType > + : public TraceType::type_t> > { public: - typedef typename T::storage_t storage_t; - typedef Count base_count_t; + typedef typename StorageType::type_t storage_t; Count(const char* name, const char* description = NULL) : TraceType(name) @@ -442,7 +468,7 @@ namespace LLTrace { T converted_value; converted_value.assignFrom(value); - getPrimaryAccumulator().add(converted_value.value()); + getPrimaryAccumulator().add((storage_t)converted_value.value()); } }; diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index 9a769ff344..f44a0a2764 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -39,8 +39,10 @@ namespace LLTrace Recording::Recording() : mElapsedSeconds(0), - mCounts(new AccumulatorBuffer >()), - mMeasurements(new AccumulatorBuffer >()), + mCountsFloat(new AccumulatorBuffer >()), + mMeasurementsFloat(new AccumulatorBuffer >()), + mCounts(new AccumulatorBuffer >()), + mMeasurements(new AccumulatorBuffer >()), mStackTimers(new AccumulatorBuffer()) {} @@ -59,6 +61,8 @@ void Recording::update() void Recording::handleReset() { + mCountsFloat.write()->reset(); + mMeasurementsFloat.write()->reset(); mCounts.write()->reset(); mMeasurements.write()->reset(); mStackTimers.write()->reset(); @@ -88,6 +92,8 @@ void Recording::handleSplitTo(Recording& other) void Recording::makePrimary() { + mCountsFloat.write()->makePrimary(); + mMeasurementsFloat.write()->makePrimary(); mCounts.write()->makePrimary(); mMeasurements.write()->makePrimary(); mStackTimers.write()->makePrimary(); @@ -100,14 +106,120 @@ bool Recording::isPrimary() const void Recording::mergeRecording( const Recording& other ) { + mCountsFloat.write()->addSamples(*other.mCountsFloat); + mMeasurementsFloat.write()->addSamples(*other.mMeasurementsFloat); mCounts.write()->addSamples(*other.mCounts); mMeasurements.write()->addSamples(*other.mMeasurements); mStackTimers.write()->addSamples(*other.mStackTimers); mElapsedSeconds += other.mElapsedSeconds; } +F64 Recording::getSum( const TraceType >& stat ) const +{ + return stat.getAccumulator(mCountsFloat).getSum(); +} + +S64 Recording::getSum( const TraceType >& stat ) const +{ + return stat.getAccumulator(mCounts).getSum(); +} + +F64 Recording::getSum( const TraceType >& stat ) const +{ + return (F64)stat.getAccumulator(mMeasurementsFloat).getSum(); +} + +S64 Recording::getSum( const TraceType >& stat ) const +{ + return (S64)stat.getAccumulator(mMeasurements).getSum(); +} + + + +F64 Recording::getPerSec( const TraceType >& stat ) const +{ + return stat.getAccumulator(mCountsFloat).getSum() / mElapsedSeconds; +} + +F64 Recording::getPerSec( const TraceType >& stat ) const +{ + return (F64)stat.getAccumulator(mCounts).getSum() / mElapsedSeconds; +} + +F64 Recording::getPerSec( const TraceType >& stat ) const +{ + return stat.getAccumulator(mMeasurementsFloat).getSum() / mElapsedSeconds; +} + +F64 Recording::getPerSec( const TraceType >& stat ) const +{ + return (F64)stat.getAccumulator(mMeasurements).getSum() / mElapsedSeconds; +} + +F64 Recording::getMin( const TraceType >& stat ) const +{ + return stat.getAccumulator(mMeasurementsFloat).getMin(); +} + +S64 Recording::getMin( const TraceType >& stat ) const +{ + return stat.getAccumulator(mMeasurements).getMin(); +} + +F64 Recording::getMax( const TraceType >& stat ) const +{ + return stat.getAccumulator(mMeasurementsFloat).getMax(); +} + +S64 Recording::getMax( const TraceType >& stat ) const +{ + return stat.getAccumulator(mMeasurements).getMax(); +} + +F64 Recording::getMean( const TraceType >& stat ) const +{ + return stat.getAccumulator(mMeasurementsFloat).getMean(); +} + +F64 Recording::getMean( const TraceType >& stat ) const +{ + return stat.getAccumulator(mMeasurements).getMean(); +} + +F64 Recording::getStandardDeviation( const TraceType >& stat ) const +{ + return stat.getAccumulator(mMeasurementsFloat).getStandardDeviation(); +} + +F64 Recording::getStandardDeviation( const TraceType >& stat ) const +{ + return stat.getAccumulator(mMeasurements).getStandardDeviation(); +} + +F64 Recording::getLastValue( const TraceType >& stat ) const +{ + return stat.getAccumulator(mMeasurementsFloat).getLastValue(); +} + +S64 Recording::getLastValue( const TraceType >& stat ) const +{ + return stat.getAccumulator(mMeasurements).getLastValue(); +} + +U32 Recording::getSampleCount( const TraceType >& stat ) const +{ + return stat.getAccumulator(mMeasurementsFloat).getSampleCount(); +} + +U32 Recording::getSampleCount( const TraceType >& stat ) const +{ + return stat.getAccumulator(mMeasurements).getSampleCount(); +} + + + /////////////////////////////////////////////////////////////////////// -// Recording +// PeriodicRecording /////////////////////////////////////////////////////////////////////// PeriodicRecording::PeriodicRecording( S32 num_periods ) @@ -179,6 +291,7 @@ void PeriodicRecording::handleSplitTo( PeriodicRecording& other ) getCurRecordingPeriod().handleSplitTo(other.getCurRecordingPeriod()); } + /////////////////////////////////////////////////////////////////////// // ExtendableRecording /////////////////////////////////////////////////////////////////////// diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index d3f001ab6a..4af973515d 100644 --- a/indra/llcommon/lltracerecording.h +++ b/indra/llcommon/lltracerecording.h @@ -112,124 +112,81 @@ namespace LLTrace void update(); // Count accessors + F64 getSum(const TraceType >& stat) const; + S64 getSum(const TraceType >& stat) const; template - T getSum(const TraceType >& stat) const + T getSum(const Count& stat) const { - return (T)stat.getAccumulator(mCounts).getSum(); - } - - template - T getSum(const Count& stat) const - { - return (T)stat.getAccumulator(mCounts).getSum(); + return (T)getSum(static_cast::type_t> >&> (stat)); } + F64 getPerSec(const TraceType >& stat) const; + F64 getPerSec(const TraceType >& stat) const; template - T getPerSec(const TraceType >& stat) const + T getPerSec(const Count& stat) const { - return (T)stat.getAccumulator(mCounts).getSum() / mElapsedSeconds; - } - - template - T getPerSec(const Count& stat) const - { - return (T)stat.getAccumulator(mCounts).getSum() / mElapsedSeconds; + return (T)getPerSec(static_cast::type_t> >&> (stat)); } // Measurement accessors + F64 getSum(const TraceType >& stat) const; + S64 getSum(const TraceType >& stat) const; template - T getSum(const TraceType >& stat) const + T getSum(const Measurement& stat) const { - return (T)stat.getAccumulator(mMeasurements).getSum(); - - } - - template - T getSum(const Measurement& stat) const - { - return (T)stat.getAccumulator(mMeasurements).getSum(); - + return (T)getSum(static_cast::type_t> >&> (stat)); } + F64 getPerSec(const TraceType >& stat) const; + F64 getPerSec(const TraceType >& stat) const; template - T getPerSec(const TraceType >& stat) const - { - return (T)stat.getAccumulator(mMeasurements).getSum() / mElapsedSeconds; - } - - template - T getPerSec(const Measurement& stat) const + T getPerSec(const Measurement& stat) const { - return (typename Count::base_unit_t)stat.getAccumulator(mMeasurements).getSum() / mElapsedSeconds; + return (T)getPerSec(static_cast::type_t> >&> (stat)); } + F64 getMin(const TraceType >& stat) const; + S64 getMin(const TraceType >& stat) const; template - T getMin(const TraceType >& stat) const - { - return (T)stat.getAccumulator(mMeasurements).getMin(); - } - - template - T getMin(const Measurement& stat) const + T getMin(const Measurement& stat) const { - return (T)stat.getAccumulator(mMeasurements).getMin(); + return (T)getMin(static_cast::type_t> >&> (stat)); } - + F64 getMax(const TraceType >& stat) const; + S64 getMax(const TraceType >& stat) const; template - T getMax(const TraceType >& stat) const - { - return (T)stat.getAccumulator(mMeasurements).getMax(); - } - - template - T getMax(const Measurement& stat) const + T getMax(const Measurement& stat) const { - return (T)stat.getAccumulator(mMeasurements).getMax(); + return (T)getMax(static_cast::type_t> >&> (stat)); } + F64 getMean(const TraceType >& stat) const; + F64 getMean(const TraceType >& stat) const; template - T getMean(const TraceType >& stat) const + T getMean(Measurement& stat) const { - return (T)stat.getAccumulator(mMeasurements).getMean(); - } - - template - T getMean(Measurement& stat) const - { - return (T)stat.getAccumulator(mMeasurements).getMean(); + return (T)getMean(static_cast::type_t> >&> (stat)); } + F64 getStandardDeviation(const TraceType >& stat) const; + F64 getStandardDeviation(const TraceType >& stat) const; template - T getStandardDeviation(const TraceType >& stat) const - { - return (T)stat.getAccumulator(mMeasurements).getStandardDeviation(); - } - - template - T getStandardDeviation(const Measurement& stat) const + T getStandardDeviation(const Measurement& stat) const { - return (T)stat.getAccumulator(mMeasurements).getStandardDeviation(); + return (T)getMean(static_cast::type_t> >&> (stat)); } + F64 getLastValue(const TraceType >& stat) const; + S64 getLastValue(const TraceType >& stat) const; template - T getLastValue(const TraceType >& stat) const - { - return (T)stat.getAccumulator(mMeasurements).getLastValue(); - } - - template - T getLastValue(const Measurement& stat) const + T getLastValue(const Measurement& stat) const { - return (T)stat.getAccumulator(mMeasurements).getLastValue(); + return (T)getLastValue(static_cast::type_t> >&> (stat)); } - - template - U32 getSampleCount(const TraceType >& stat) const - { - return stat.getAccumulator(mMeasurements).getSampleCount(); - } + U32 getSampleCount(const TraceType >& stat) const; + U32 getSampleCount(const TraceType >& stat) const; LLUnit::Seconds getDuration() const { return mElapsedSeconds; } @@ -244,8 +201,10 @@ namespace LLTrace // returns data for current thread class ThreadRecorder* getThreadRecorder(); - LLCopyOnWritePointer > > mCounts; - LLCopyOnWritePointer > > mMeasurements; + LLCopyOnWritePointer > > mCountsFloat; + LLCopyOnWritePointer > > mMeasurementsFloat; + LLCopyOnWritePointer > > mCounts; + LLCopyOnWritePointer > > mMeasurements; LLCopyOnWritePointer > mStackTimers; LLTimer mSamplingTimer; @@ -260,6 +219,7 @@ namespace LLTrace ~PeriodicRecording(); void nextPeriod(); + S32 getNumPeriods() { return mNumPeriods; } Recording& getLastRecordingPeriod() { @@ -268,7 +228,7 @@ namespace LLTrace const Recording& getLastRecordingPeriod() const { - return mRecordingPeriods[(mCurPeriod + mNumPeriods - 1) % mNumPeriods]; + return getPrevRecordingPeriod(1); } Recording& getCurRecordingPeriod() @@ -281,6 +241,16 @@ namespace LLTrace return mRecordingPeriods[mCurPeriod]; } + Recording& getPrevRecordingPeriod(S32 offset) + { + return mRecordingPeriods[(mCurPeriod + mNumPeriods - offset) % mNumPeriods]; + } + + const Recording& getPrevRecordingPeriod(S32 offset) const + { + return mRecordingPeriods[(mCurPeriod + mNumPeriods - offset) % mNumPeriods]; + } + Recording snapshotCurRecordingPeriod() const { Recording recording_copy(getCurRecordingPeriod()); @@ -290,6 +260,84 @@ namespace LLTrace Recording& getTotalRecording(); + template + typename T getPeriodMin(const TraceType >& stat) const + { + T min_val = std::numeric_limits::max(); + for (S32 i = 0; i < mNumPeriods; i++) + { + min_val = llmin(min_val, mRecordingPeriods[i].getSum(stat)); + } + return (T)min_val; + } + + template + F64 getPeriodMinPerSec(const TraceType >& stat) const + { + F64 min_val = std::numeric_limits::max(); + for (S32 i = 0; i < mNumPeriods; i++) + { + min_val = llmin(min_val, mRecordingPeriods[i].getPerSec(stat)); + } + return min_val; + } + + template + T getPeriodMax(const TraceType >& stat) const + { + T max_val = std::numeric_limits::min(); + for (S32 i = 0; i < mNumPeriods; i++) + { + max_val = llmax(max_val, mRecordingPeriods[i].getSum(stat)); + } + return max_val; + } + + template + F64 getPeriodMaxPerSec(const TraceType >& stat) const + { + F64 max_val = std::numeric_limits::min(); + for (S32 i = 0; i < mNumPeriods; i++) + { + max_val = llmax(max_val, mRecordingPeriods[i].getPerSec(stat)); + } + return max_val; + } + + template + F64 getPeriodMean(const TraceType >& stat) const + { + F64 mean = 0.0; + F64 count = 0; + for (S32 i = 0; i < mNumPeriods; i++) + { + if (mRecordingPeriods[i].getDuration() > 0.f) + { + count++; + mean += mRecordingPeriods[i].getSum(stat); + } + } + mean /= (F64)mNumPeriods; + return mean; + } + + template + F64 getPeriodMeanPerSec(const TraceType >& stat) const + { + F64 mean = 0.0; + F64 count = 0; + for (S32 i = 0; i < mNumPeriods; i++) + { + if (mRecordingPeriods[i].getDuration() > 0.f) + { + count++; + mean += mRecordingPeriods[i].getPerSec(stat); + } + } + mean /= count; + return mean; + } + private: // implementation for LLVCRControlsMixin diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index e81333f7f2..15056b80e4 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -113,9 +113,13 @@ ThreadRecorder::ActiveRecording::ActiveRecording( Recording* target ) void ThreadRecorder::ActiveRecording::moveBaselineToTarget() { + mTargetRecording->mMeasurementsFloat.write()->addSamples(*mBaseline.mMeasurementsFloat); + mTargetRecording->mCountsFloat.write()->addSamples(*mBaseline.mCountsFloat); mTargetRecording->mMeasurements.write()->addSamples(*mBaseline.mMeasurements); mTargetRecording->mCounts.write()->addSamples(*mBaseline.mCounts); mTargetRecording->mStackTimers.write()->addSamples(*mBaseline.mStackTimers); + mBaseline.mMeasurementsFloat.write()->reset(); + mBaseline.mCountsFloat.write()->reset(); mBaseline.mMeasurements.write()->reset(); mBaseline.mCounts.write()->reset(); mBaseline.mStackTimers.write()->reset(); diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp index 535c6f96e3..6b40f8d475 100644 --- a/indra/llui/llstatbar.cpp +++ b/indra/llui/llstatbar.cpp @@ -34,7 +34,6 @@ #include "llgl.h" #include "llfontgl.h" -#include "llstat.h" #include "lluictrlfactory.h" #include "lltracerecording.h" @@ -46,8 +45,10 @@ LLStatBar::LLStatBar(const Params& p) mUnitLabel(p.unit_label), mMinBar(p.bar_min), mMaxBar(p.bar_max), - mStatp(LLStat::getInstance(p.stat)), - mNewStatp(LLTrace::Count<>::getInstance(p.stat)), + mCountFloatp(LLTrace::Count<>::getInstance(p.stat)), + mCountIntp(LLTrace::Count::getInstance(p.stat)), + mMeasurementFloatp(LLTrace::Measurement<>::getInstance(p.stat)), + mMeasurementIntp(LLTrace::Measurement::getInstance(p.stat)), mTickSpacing(p.tick_spacing), mLabelSpacing(p.label_spacing), mPrecision(p.precision), @@ -90,46 +91,62 @@ void LLStatBar::draw() max = 0.f, mean = 0.f; - if (mStatp) + LLTrace::PeriodicRecording& frame_recording = LLTrace::get_frame_recording(); + + if (mCountFloatp) { - // Get the values. + LLTrace::Recording& last_frame_recording = frame_recording.getLastRecordingPeriod(); + if (mPerSec) { - current = mStatp->getCurrentPerSec(); - min = mStatp->getMinPerSec(); - max = mStatp->getMaxPerSec(); - mean = mStatp->getMeanPerSec(); + current = last_frame_recording.getPerSec(*mCountFloatp); + min = frame_recording.getPeriodMinPerSec(*mCountFloatp); + max = frame_recording.getPeriodMaxPerSec(*mCountFloatp); + mean = frame_recording.getPeriodMeanPerSec(*mCountFloatp); } else { - current = mStatp->getCurrent(); - min = mStatp->getMin(); - max = mStatp->getMax(); - mean = mStatp->getMean(); + current = last_frame_recording.getSum(*mCountFloatp); + min = frame_recording.getPeriodMin(*mCountFloatp); + max = frame_recording.getPeriodMax(*mCountFloatp); + mean = frame_recording.getPeriodMean(*mCountFloatp); } } - else if (mNewStatp) + else if (mCountIntp) { - LLTrace::PeriodicRecording& frame_recording = LLTrace::get_frame_recording(); LLTrace::Recording& last_frame_recording = frame_recording.getLastRecordingPeriod(); - LLTrace::Recording& windowed_frame_recording = frame_recording.getTotalRecording(); if (mPerSec) { - current = last_frame_recording.getPerSec(*mNewStatp); - //min = frame_window_recording.getMin(*mNewStatp) / frame_window_recording.getDuration(); - //max = frame_window_recording.getMax(*mNewStatp) / frame_window_recording.getDuration(); - mean = windowed_frame_recording.getPerSec(*mNewStatp);//frame_window_recording.getMean(*mNewStatp) / frame_window_recording.getDuration(); + current = last_frame_recording.getPerSec(*mCountIntp); + min = frame_recording.getPeriodMinPerSec(*mCountIntp); + max = frame_recording.getPeriodMaxPerSec(*mCountIntp); + mean = frame_recording.getPeriodMeanPerSec(*mCountIntp); } else { - current = last_frame_recording.getSum(*mNewStatp); - //min = last_frame_recording.getMin(*mNewStatp); - //max = last_frame_recording.getMax(*mNewStatp); - mean = windowed_frame_recording.getSum(*mNewStatp); + current = last_frame_recording.getSum(*mCountIntp); + min = frame_recording.getPeriodMin(*mCountIntp); + max = frame_recording.getPeriodMax(*mCountIntp); + mean = frame_recording.getPeriodMean(*mCountIntp); } } - + else if (mMeasurementFloatp) + { + LLTrace::Recording& recording = frame_recording.getTotalRecording(); + current = recording.getLastValue(*mMeasurementFloatp); + min = recording.getMin(*mMeasurementFloatp); + max = recording.getMax(*mMeasurementFloatp); + mean = recording.getMean(*mMeasurementFloatp); + } + else if (mMeasurementIntp) + { + LLTrace::Recording& recording = frame_recording.getTotalRecording(); + current = recording.getLastValue(*mMeasurementIntp); + min = recording.getMin(*mMeasurementIntp); + max = recording.getMax(*mMeasurementIntp); + mean = recording.getMean(*mMeasurementIntp); + } if ((mUpdatesPerSec == 0.f) || (mUpdateTimer.getElapsedTimeF32() > 1.f/mUpdatesPerSec) || (mValue == 0.f)) { @@ -176,7 +193,7 @@ void LLStatBar::draw() LLFontGL::RIGHT, LLFontGL::TOP); value_format = llformat( "%%.%df", mPrecision); - if (mDisplayBar && mStatp) + if (mDisplayBar && (mCountFloatp || mCountIntp || mMeasurementFloatp || mMeasurementIntp)) { std::string tick_label; @@ -219,7 +236,7 @@ void LLStatBar::draw() right = width; gl_rect_2d(left, top, right, bottom, LLColor4(0.f, 0.f, 0.f, 0.25f)); - if (mStatp->getNumValues() == 0) + if (frame_recording.getNumPeriods() == 0) { // No data, don't draw anything... return; @@ -236,26 +253,58 @@ void LLStatBar::draw() right = (S32) ((max - mMinBar) * value_scale); gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 0.f, 0.f, 0.25f)); - if (mDisplayHistory) + if (mDisplayHistory && (mCountFloatp || mCountIntp || mMeasurementFloatp || mMeasurementIntp)) { - S32 num_values = mStatp->getNumValues() - 1; + S32 num_values = frame_recording.getNumPeriods() - 1; S32 i; - for (i = 0; i < num_values; i++) + for (i = 1; i <= num_values; i++) { - if (i == mStatp->getNextBin()) - { - continue; - } if (mPerSec) { - left = (S32)((mStatp->getPrevPerSec(i) - mMinBar) * value_scale); - right = (S32)((mStatp->getPrevPerSec(i) - mMinBar) * value_scale) + 1; + if (mCountFloatp) + { + left = (S32)((frame_recording.getPrevRecordingPeriod(i).getPerSec(*mCountFloatp) - mMinBar) * value_scale); + right = (S32)((frame_recording.getPrevRecordingPeriod(i).getPerSec(*mCountFloatp) - mMinBar) * value_scale) + 1; + } + else if (mCountIntp) + { + left = (S32)((frame_recording.getPrevRecordingPeriod(i).getPerSec(*mCountIntp) - mMinBar) * value_scale); + right = (S32)((frame_recording.getPrevRecordingPeriod(i).getPerSec(*mCountIntp) - mMinBar) * value_scale) + 1; + } + else if (mMeasurementFloatp) + { + left = (S32)((frame_recording.getPrevRecordingPeriod(i).getPerSec(*mMeasurementFloatp) - mMinBar) * value_scale); + right = (S32)((frame_recording.getPrevRecordingPeriod(i).getPerSec(*mMeasurementFloatp) - mMinBar) * value_scale) + 1; + } + else if (mMeasurementIntp) + { + left = (S32)((frame_recording.getPrevRecordingPeriod(i).getPerSec(*mMeasurementIntp) - mMinBar) * value_scale); + right = (S32)((frame_recording.getPrevRecordingPeriod(i).getPerSec(*mMeasurementIntp) - mMinBar) * value_scale) + 1; + } gl_rect_2d(left, bottom+i+1, right, bottom+i, LLColor4(1.f, 0.f, 0.f, 1.f)); } else { - left = (S32)((mStatp->getPrev(i) - mMinBar) * value_scale); - right = (S32)((mStatp->getPrev(i) - mMinBar) * value_scale) + 1; + if (mCountFloatp) + { + left = (S32)((frame_recording.getPrevRecordingPeriod(i).getSum(*mCountFloatp) - mMinBar) * value_scale); + right = (S32)((frame_recording.getPrevRecordingPeriod(i).getSum(*mCountFloatp) - mMinBar) * value_scale) + 1; + } + else if (mCountIntp) + { + left = (S32)((frame_recording.getPrevRecordingPeriod(i).getSum(*mCountIntp) - mMinBar) * value_scale); + right = (S32)((frame_recording.getPrevRecordingPeriod(i).getSum(*mCountIntp) - mMinBar) * value_scale) + 1; + } + else if (mMeasurementFloatp) + { + left = (S32)((frame_recording.getPrevRecordingPeriod(i).getSum(*mMeasurementFloatp) - mMinBar) * value_scale); + right = (S32)((frame_recording.getPrevRecordingPeriod(i).getSum(*mMeasurementFloatp) - mMinBar) * value_scale) + 1; + } + else if (mMeasurementIntp) + { + left = (S32)((frame_recording.getPrevRecordingPeriod(i).getSum(*mMeasurementIntp) - mMinBar) * value_scale); + right = (S32)((frame_recording.getPrevRecordingPeriod(i).getSum(*mMeasurementIntp) - mMinBar) * value_scale) + 1; + } gl_rect_2d(left, bottom+i+1, right, bottom+i, LLColor4(1.f, 0.f, 0.f, 1.f)); } } @@ -279,6 +328,15 @@ void LLStatBar::draw() LLView::draw(); } +void LLStatBar::setStat(const std::string& stat_name) +{ + mCountFloatp = LLTrace::Count<>::getInstance(stat_name); + mCountIntp = LLTrace::Count::getInstance(stat_name); + mMeasurementFloatp = LLTrace::Measurement<>::getInstance(stat_name); + mMeasurementIntp = LLTrace::Measurement::getInstance(stat_name); +} + + void LLStatBar::setRange(F32 bar_min, F32 bar_max, F32 tick_spacing, F32 label_spacing) { mMinBar = bar_min; @@ -293,9 +351,9 @@ LLRect LLStatBar::getRequiredRect() if (mDisplayBar) { - if (mDisplayHistory && mStatp) + if (mDisplayHistory) { - rect.mTop = 35 + mStatp->getNumBins(); + rect.mTop = 35 + LLTrace::get_frame_recording().getNumPeriods(); } else { diff --git a/indra/llui/llstatbar.h b/indra/llui/llstatbar.h index d510f0e3fe..6aefb1e213 100644 --- a/indra/llui/llstatbar.h +++ b/indra/llui/llstatbar.h @@ -30,7 +30,6 @@ #include "llview.h" #include "llframetimer.h" #include "lltracerecording.h" -class LLStat; class LLStatBar : public LLView { @@ -79,7 +78,8 @@ public: virtual void draw(); virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); - void setStat(LLStat* stat) { mStatp = stat; } + void setStat(const std::string& stat_name); + void setRange(F32 bar_min, F32 bar_max, F32 tick_spacing, F32 label_spacing); void getRange(F32& bar_min, F32& bar_max) { bar_min = mMinBar; bar_max = mMaxBar; } @@ -96,10 +96,11 @@ private: BOOL mDisplayBar; // Display the bar graph. BOOL mDisplayHistory; BOOL mDisplayMean; // If true, display mean, if false, display current value - LLTrace::PeriodicRecording* mFrameRecording; - LLStat* mStatp; - LLTrace::count_common_t* mNewStatp; + LLTrace::count_common_float_t* mCountFloatp; + LLTrace::count_common_int_t* mCountIntp; + LLTrace::measurement_common_float_t* mMeasurementFloatp; + LLTrace::measurement_common_int_t* mMeasurementIntp; LLFrameTimer mUpdateTimer; LLUIString mLabel; diff --git a/indra/llui/llstatgraph.cpp b/indra/llui/llstatgraph.cpp index e961e7d3c0..22c276a018 100644 --- a/indra/llui/llstatgraph.cpp +++ b/indra/llui/llstatgraph.cpp @@ -32,7 +32,6 @@ #include "llmath.h" #include "llui.h" -#include "llstat.h" #include "llgl.h" #include "llglheaders.h" #include "lltracerecording.h" @@ -48,8 +47,8 @@ LLStatGraph::LLStatGraph(const Params& p) mPerSec(true), mPrecision(p.precision), mValue(p.value), - mStatp(p.stat.legacy_stat), - mNewStatp(p.stat.count_stat) + mNewStatFloatp(p.stat.count_stat_float), + mNewStatIntp(p.stat.count_stat_int) { setToolTip(p.name()); @@ -73,30 +72,31 @@ void LLStatGraph::draw() { F32 range, frac; range = mMax - mMin; - if (mStatp) + if (mNewStatFloatp) { + LLTrace::Recording& recording = LLTrace::get_frame_recording().getLastRecordingPeriod(); + if (mPerSec) { - mValue = mStatp->getMeanPerSec(); + mValue = recording.getPerSec(*mNewStatFloatp); } else { - mValue = mStatp->getMean(); + mValue = recording.getSum(*mNewStatFloatp); } } - else if (mNewStatp) + else if (mNewStatIntp) { LLTrace::Recording& recording = LLTrace::get_frame_recording().getLastRecordingPeriod(); if (mPerSec) { - mValue = recording.getPerSec(*mNewStatp); + mValue = recording.getPerSec(*mNewStatIntp); } else { - mValue = recording.getSum(*mNewStatp); + mValue = recording.getSum(*mNewStatIntp); } - } frac = (mValue - mMin) / range; diff --git a/indra/llui/llstatgraph.h b/indra/llui/llstatgraph.h index b20966d608..f33c784262 100644 --- a/indra/llui/llstatgraph.h +++ b/indra/llui/llstatgraph.h @@ -32,8 +32,6 @@ #include "v4color.h" #include "lltrace.h" -class LLStat; - class LLStatGraph : public LLView { public: @@ -59,9 +57,10 @@ public: struct StatParams : public LLInitParam::ChoiceBlock { - Alternative legacy_stat; - Alternative count_stat; - Alternative measurement_stat; + Alternative count_stat_float; + Alternative count_stat_int; + Alternative measurement_stat_float; + Alternative measurement_stat_int; }; struct Params : public LLInitParam::Block @@ -106,8 +105,8 @@ public: /*virtual*/ void setValue(const LLSD& value); private: - LLStat* mStatp; - LLTrace::count_common_t* mNewStatp; + LLTrace::count_common_float_t* mNewStatFloatp; + LLTrace::count_common_int_t* mNewStatIntp; BOOL mPerSec; diff --git a/indra/llvfs/llvfile.cpp b/indra/llvfs/llvfile.cpp index ca749c5eaf..7f631ef0bb 100644 --- a/indra/llvfs/llvfile.cpp +++ b/indra/llvfs/llvfile.cpp @@ -30,8 +30,8 @@ #include "llerror.h" #include "llthread.h" -#include "llstat.h" #include "llvfs.h" +#include "lltimer.h" const S32 LLVFile::READ = 0x00000001; const S32 LLVFile::WRITE = 0x00000002; diff --git a/indra/lscript/lscript_execute/lscript_execute.cpp b/indra/lscript/lscript_execute/lscript_execute.cpp index d79e9f8bde..23e1fe306e 100644 --- a/indra/lscript/lscript_execute/lscript_execute.cpp +++ b/indra/lscript/lscript_execute/lscript_execute.cpp @@ -35,7 +35,6 @@ #include "lscript_library.h" #include "lscript_heapruntime.h" #include "lscript_alloc.h" -#include "llstat.h" // Static diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 751b73e1eb..8d80e3aa0a 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -1081,8 +1081,8 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y) LLQuaternion av_inv_rot = ~gAgentAvatarp->mRoot.getWorldRotation(); LLVector3 root_at = LLVector3::x_axis * gAgentAvatarp->mRoot.getWorldRotation(); - if ((gViewerWindow->getMouseVelocityStat()->getCurrent() < 0.01f) && - (root_at * last_at_axis > 0.95f)) + if (LLTrace::get_frame_recording().getLastRecordingPeriod().getLastValue(*gViewerWindow->getMouseVelocityStat()) < 0.01f + && (root_at * last_at_axis > 0.95f)) { LLVector3 vel = gAgentAvatarp->getVelocity(); if (vel.magVecSquared() > 4.f) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 559f427de6..2d090f0f74 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4305,6 +4305,9 @@ void LLAppViewer::idle() update_statistics(); } + LLTrace::get_frame_recording().nextPeriod(); + + //////////////////////////////////////// // // Handle the regular UI idle callbacks as well as diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 4dfb93f1bc..065b20ba2b 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -46,7 +46,6 @@ #include "llviewertexturelist.h" #include "llui.h" #include "llviewercontrol.h" -#include "llstat.h" #include "llfasttimer.h" #include "lltreeiterators.h" diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp index f7b2670b8e..e2813a8272 100644 --- a/indra/newview/llfloaterjoystick.cpp +++ b/indra/newview/llfloaterjoystick.cpp @@ -33,7 +33,7 @@ #include "llerror.h" #include "llrect.h" #include "llstring.h" -#include "llstat.h" +#include "lltrace.h" // project includes #include "lluictrlfactory.h" @@ -42,6 +42,16 @@ #include "llviewerjoystick.h" #include "llcheckboxctrl.h" +static LLTrace::Measurement<> sJoystickAxes[6] = +{ + LLTrace::Measurement<>("Joystick axis 1"), + LLTrace::Measurement<>("Joystick axis 2"), + LLTrace::Measurement<>("Joystick axis 3"), + LLTrace::Measurement<>("Joystick axis 4"), + LLTrace::Measurement<>("Joystick axis 5"), + LLTrace::Measurement<>("Joystick axis 6") +}; + LLFloaterJoystick::LLFloaterJoystick(const LLSD& data) : LLFloater(data) { @@ -61,7 +71,7 @@ void LLFloaterJoystick::draw() for (U32 i = 0; i < 6; i++) { F32 value = joystick->getJoystickAxis(i); - mAxisStats[i]->addValue(value * gFrameIntervalSeconds.value()); + sJoystickAxes[i].sample(value * gFrameIntervalSeconds.value()); if (mAxisStatsBar[i]) { F32 minbar, maxbar; @@ -85,12 +95,11 @@ BOOL LLFloaterJoystick::postBuild() for (U32 i = 0; i < 6; i++) { std::string stat_name(llformat("Joystick axis %d", i)); - mAxisStats[i] = new LLStat(stat_name, 4); std::string axisname = llformat("axis%d", i); mAxisStatsBar[i] = getChild(axisname); if (mAxisStatsBar[i]) { - mAxisStatsBar[i]->setStat(mAxisStats[i]); + mAxisStatsBar[i]->setStat(stat_name); mAxisStatsBar[i]->setRange(-range, range, range * 0.25f, range * 0.5f); } } diff --git a/indra/newview/llfloaterjoystick.h b/indra/newview/llfloaterjoystick.h index dfdb108ff8..9c3752540d 100644 --- a/indra/newview/llfloaterjoystick.h +++ b/indra/newview/llfloaterjoystick.h @@ -84,7 +84,6 @@ private: LLCheckBoxCtrl *mCheckFlycamEnabled; // stats view - LLStat* mAxisStats[6]; LLStatBar* mAxisStatsBar[6]; }; diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index 482294c8a6..56fbdb429a 100644 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -30,6 +30,7 @@ #include "llhudnametag.h" #include "llrender.h" +#include "lltracerecording.h" #include "llagent.h" #include "llviewercontrol.h" @@ -899,8 +900,8 @@ void LLHUDNameTag::updateAll() // } } - LLStat* camera_vel_stat = LLViewerCamera::getInstance()->getVelocityStat(); - F32 camera_vel = camera_vel_stat->getCurrent(); + LLTrace::Count<>* camera_vel_stat = LLViewerCamera::getVelocityStat(); + F32 camera_vel = LLTrace::get_frame_recording().getLastRecordingPeriod().getPerSec(*camera_vel_stat); if (camera_vel > MAX_STABLE_CAMERA_VELOCITY) { return; diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 5720395d05..b945ec2318 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -198,7 +198,7 @@ BOOL LLStatusBar::postBuild() sgp.rect(r); sgp.follows.flags(FOLLOWS_BOTTOM | FOLLOWS_RIGHT); sgp.mouse_opaque(false); - sgp.stat.count_stat(&LLStatViewer::KBIT); + sgp.stat.count_stat_float(&LLStatViewer::KBIT); sgp.units("Kbps"); sgp.precision(0); mSGBandwidth = LLUICtrlFactory::create(sgp); @@ -212,7 +212,7 @@ BOOL LLStatusBar::postBuild() pgp.rect(r); pgp.follows.flags(FOLLOWS_BOTTOM | FOLLOWS_RIGHT); pgp.mouse_opaque(false); - pgp.stat.measurement_stat(&LLStatViewer::PACKETS_LOST_PERCENT); + pgp.stat.measurement_stat_float(&LLStatViewer::PACKETS_LOST_PERCENT); pgp.units("%"); pgp.min(0.f); pgp.max(5.f); diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h index 9d24bf8771..33a64ae7d5 100644 --- a/indra/newview/llsurface.h +++ b/indra/newview/llsurface.h @@ -45,7 +45,6 @@ class LLTimer; class LLUUID; class LLAgent; -class LLStat; static const U8 NO_EDGE = 0x00; static const U8 EAST_EDGE = 0x01; diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 2a72e77672..fa0e3acf5e 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -59,8 +59,8 @@ #include "llviewerstats.h" bool LLTextureFetchDebugger::sDebuggerEnabled = false ; -LLStat LLTextureFetch::sCacheHitRate("texture_cache_hits", 128); -LLStat LLTextureFetch::sCacheReadLatency("texture_cache_read_latency", 128); +LLTrace::Measurement<> LLTextureFetch::sCacheHitRate("texture_cache_hits"); +LLTrace::Measurement<> LLTextureFetch::sCacheReadLatency("texture_cache_read_latency"); ////////////////////////////////////////////////////////////////////////////// class LLTextureFetchWorker : public LLWorkerClass @@ -895,7 +895,7 @@ bool LLTextureFetchWorker::doWork(S32 param) LL_DEBUGS("Texture") << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize() << " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight()) << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL; - LLTextureFetch::sCacheHitRate.addValue(100.f); + LLTextureFetch::sCacheHitRate.sample(100.f); } else { @@ -912,7 +912,7 @@ bool LLTextureFetchWorker::doWork(S32 param) } // fall through - LLTextureFetch::sCacheHitRate.addValue(0.f); + LLTextureFetch::sCacheHitRate.sample(0.f); } } @@ -2039,7 +2039,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, F32 cache_read_time = worker->mCacheReadTime; if (cache_read_time != 0.f) { - sCacheReadLatency.addValue(cache_read_time * 1000.f); + sCacheReadLatency.sample(cache_read_time * 1000.f); } res = true; LL_DEBUGS("Texture") << id << ": Request Finished. State: " << worker->mState << " Discard: " << discard_level << LL_ENDL; diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 7ffa58660e..4ec67c8cdb 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -35,8 +35,7 @@ #include "lltextureinfo.h" #include "llapr.h" #include "llimageworker.h" -#include "llstat.h" -//#include "lltexturecache.h" +#include "lltrace.h" class LLViewerTexture; class LLTextureFetchWorker; @@ -166,8 +165,8 @@ private: LLMutex mQueueMutex; //to protect mRequestMap and mCommands only LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue. - static LLStat sCacheHitRate; - static LLStat sCacheReadLatency; + static LLTrace::Measurement<> sCacheHitRate; + static LLTrace::Measurement<> sCacheReadLatency; LLTextureCache* mTextureCache; LLImageDecodeThread* mImageDecodeThread; diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index a437a8b3b5..831304f428 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -49,10 +49,14 @@ #include "llglheaders.h" #include "llquaternion.h" #include "llwindow.h" // getPixelAspectRatio() +#include "lltracerecording.h" // System includes #include // for setprecision +LLTrace::Count<> LLViewerCamera::sVelocityStat("camera_velocity"); +LLTrace::Count<> LLViewerCamera::sAngularVelocityStat("camera_angular_velocity"); + U32 LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; //glu pick matrix implementation borrowed from Mesa3D @@ -163,11 +167,12 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 ¢er, F32 drot; rotation.getAngleAxis(&drot, &x, &y, &z); - mVelocityStat.addValue(dpos); - mAngularVelocityStat.addValue(drot); + sVelocityStat.add(dpos); + sAngularVelocityStat.add(drot); - mAverageSpeed = mVelocityStat.getMeanPerSec() ; - mAverageAngularSpeed = mAngularVelocityStat.getMeanPerSec() ; + LLTrace::Recording& recording = LLTrace::get_frame_recording().getTotalRecording(); + mAverageSpeed = LLTrace::get_frame_recording().getPeriodMeanPerSec(sVelocityStat); + mAverageAngularSpeed = LLTrace::get_frame_recording().getPeriodMeanPerSec(sAngularVelocityStat); mCosHalfCameraFOV = cosf(0.5f * getView() * llmax(1.0f, getAspect())); // update pixel meter ratio using default fov, not modified one diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h index b857c7fe89..399eed7695 100644 --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -29,10 +29,10 @@ #include "llcamera.h" #include "llsingleton.h" -#include "llstat.h" #include "lltimer.h" #include "m4math.h" #include "llcoord.h" +#include "lltrace.h" class LLViewerObject; @@ -100,12 +100,12 @@ public: BOOL projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoordGL &out_point, const BOOL clamp = TRUE) const; BOOL projectPosAgentToScreenEdge(const LLVector3 &pos_agent, LLCoordGL &out_point) const; - const LLVector3* getVelocityDir() const {return &mVelocityDir;} - LLStat *getVelocityStat() { return &mVelocityStat; } - LLStat *getAngularVelocityStat() { return &mAngularVelocityStat; } - F32 getCosHalfFov() {return mCosHalfCameraFOV;} - F32 getAverageSpeed() {return mAverageSpeed ;} - F32 getAverageAngularSpeed() {return mAverageAngularSpeed;} + const LLVector3* getVelocityDir() const {return &mVelocityDir;} + static LLTrace::Count<>* getVelocityStat() {return &sVelocityStat; } + static LLTrace::Count<>* getAngularVelocityStat() {return &sAngularVelocityStat; } + F32 getCosHalfFov() {return mCosHalfCameraFOV;} + F32 getAverageSpeed() {return mAverageSpeed ;} + F32 getAverageAngularSpeed() {return mAverageAngularSpeed;} void getPixelVectors(const LLVector3 &pos_agent, LLVector3 &up, LLVector3 &right); LLVector3 roundToPixel(const LLVector3 &pos_agent); @@ -117,9 +117,9 @@ public: F32 getDefaultFOV() { return mCameraFOVDefault; } BOOL cameraUnderWater() const; - - const LLVector3 &getPointOfInterest() { return mLastPointOfInterest; } BOOL areVertsVisible(LLViewerObject* volumep, BOOL all_verts); + + const LLVector3 &getPointOfInterest() { return mLastPointOfInterest; } F32 getPixelMeterRatio() const { return mPixelMeterRatio; } S32 getScreenPixelArea() const { return mScreenPixelArea; } @@ -130,12 +130,12 @@ public: protected: void calcProjection(const F32 far_distance) const; - LLStat mVelocityStat; - LLStat mAngularVelocityStat; - LLVector3 mVelocityDir ; - F32 mAverageSpeed ; - F32 mAverageAngularSpeed ; + static LLTrace::Count<> sVelocityStat; + static LLTrace::Count<> sAngularVelocityStat; + LLVector3 mVelocityDir ; + F32 mAverageSpeed ; + F32 mAverageAngularSpeed ; mutable LLMatrix4 mProjectionMatrix; // Cache of perspective matrix mutable LLMatrix4 mModelviewMatrix; F32 mCameraFOVDefault; diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 169b45c14e..41a08398bb 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -748,8 +748,10 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LLFastTimer t(FTM_IMAGE_UPDATE_CLASS); - LLViewerTexture::updateClass(LLViewerCamera::getInstance()->getVelocityStat()->getMean(), - LLViewerCamera::getInstance()->getAngularVelocityStat()->getMean()); + LLTrace::Count<>* velocity_stat = LLViewerCamera::getVelocityStat(); + LLTrace::Count<>* angular_velocity_stat = LLViewerCamera::getAngularVelocityStat(); + LLViewerTexture::updateClass(LLTrace::get_frame_recording().getPeriodMeanPerSec(*velocity_stat), + LLTrace::get_frame_recording().getPeriodMeanPerSec(*angular_velocity_stat)); } diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 82caa05983..acbe836c29 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -4765,28 +4765,6 @@ void process_sim_stats(LLMessageSystem *msg, void **user_data) } } - /* - msg->getF32Fast(_PREHASH_Statistics, _PREHASH_PhysicsTimeDilation, time_dilation); - LLViewerStats::getInstance()->mSimTDStat.addValue(time_dilation); - - // Process information - // { CpuUsage F32 } - // { SimMemTotal F32 } - // { SimMemRSS F32 } - // { ProcessUptime F32 } - F32 cpu_usage; - F32 sim_mem_total; - F32 sim_mem_rss; - F32 process_uptime; - msg->getF32Fast(_PREHASH_Statistics, _PREHASH_CpuUsage, cpu_usage); - msg->getF32Fast(_PREHASH_Statistics, _PREHASH_SimMemTotal, sim_mem_total); - msg->getF32Fast(_PREHASH_Statistics, _PREHASH_SimMemRSS, sim_mem_rss); - msg->getF32Fast(_PREHASH_Statistics, _PREHASH_ProcessUptime, process_uptime); - LLViewerStats::getInstance()->mSimCPUUsageStat.addValue(cpu_usage); - LLViewerStats::getInstance()->mSimMemTotalStat.addValue(sim_mem_total); - LLViewerStats::getInstance()->mSimMemRSSStat.addValue(sim_mem_rss); - */ - // // Various hacks that aren't statistics, but are being handled here. // diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 14a2ac3384..9c6045943f 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -93,7 +93,7 @@ extern LLPipeline gPipeline; U32 LLViewerObjectList::sSimulatorMachineIndex = 1; // Not zero deliberately, to speed up index check. std::map LLViewerObjectList::sIPAndPortToIndex; std::map LLViewerObjectList::sIndexAndLocalIDToUUID; -LLStat LLViewerObjectList::sCacheHitRate("object_cache_hits", 128); +LLTrace::Measurement<> LLViewerObjectList::sCacheHitRate("object_cache_hits"); LLViewerObjectList::LLViewerObjectList() { @@ -520,7 +520,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, } justCreated = TRUE; mNumNewObjects++; - sCacheHitRate.addValue(cached ? 100.f : 0.f); + sCacheHitRate.sample(cached ? 100.f : 0.f); } diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 9936432a71..ca4110230f 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -31,8 +31,8 @@ #include // common includes -#include "llstat.h" #include "llstring.h" +#include "lltrace.h" // project includes #include "llviewerobject.h" @@ -194,7 +194,7 @@ protected: std::vector mOrphanChildren; // UUID's of orphaned objects S32 mNumOrphans; - static LLStat sCacheHitRate; + static LLTrace::Measurement<> sCacheHitRate; typedef std::vector > vobj_list_t; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 31e3820a21..652e0ee70b 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -291,7 +291,9 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, mCacheLoaded(FALSE), mCacheDirty(FALSE), mReleaseNotesRequested(FALSE), - mCapabilitiesReceived(false) + mCapabilitiesReceived(false), + mBitsReceived(0.f), + mPacketsReceived(0.f) { mWidth = region_width_meters; mImpl->mOriginGlobal = from_region_handle(handle); @@ -909,9 +911,8 @@ void LLViewerRegion::updateNetStats() mPacketsLost = cdp->getPacketsLost(); mPingDelay = cdp->getPingDelay(); - mBitStat.addValue(mBitsIn - mLastBitsIn); - mPacketsStat.addValue(mPacketsIn - mLastPacketsIn); - mPacketsLostStat.addValue(mPacketsLost); + mBitsReceived += mBitsIn - mLastBitsIn; + mPacketsReceived += mPacketsIn - mLastPacketsIn; } diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index c9fffaf30e..756c0dc61f 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -34,7 +34,6 @@ #include "lldarray.h" #include "llwind.h" -#include "llstat.h" #include "v3dmath.h" #include "llstring.h" #include "llregionflags.h" @@ -351,9 +350,8 @@ public: LLWind mWind; LLViewerParcelOverlay *mParcelOverlay; - LLStat mBitStat; - LLStat mPacketsStat; - LLStat mPacketsLostStat; + F32 mBitsReceived; + F32 mPacketsReceived; LLMatrix4 mRenderMatrix; diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 04b0c30b40..a42368cec4 100755 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -94,8 +94,8 @@ LLTrace::Count KBIT("kbitstat"), OBJECT_KBIT("objectkbitstat"), ASSET_KBIT("assetkbitstat"), TEXTURE_KBIT("texturekbitstat"), - ACTUAL_IN_KBIT("actualinkbit"), - ACTUAL_OUT_KBIT("actualoutkbit"); + ACTUAL_IN_KBIT("actualinkbitstat"), + ACTUAL_OUT_KBIT("actualoutkbitstat"); LLTrace::Count AVATAR_EDIT_TIME("avataredittime", "Seconds in Edit Appearence"), TOOLBOX_TIME("toolboxtime", "Seconds using Toolbox"), @@ -276,20 +276,25 @@ void LLViewerStats::addToMessage(LLSD &body) const // *NOTE:Mani The following methods used to exist in viewer.cpp // Moving them here, but not merging them into LLViewerStats yet. -U32 gTotalLandIn = 0, gTotalLandOut = 0; -U32 gTotalWaterIn = 0, gTotalWaterOut = 0; - -F32 gAveLandCompression = 0.f, gAveWaterCompression = 0.f; -F32 gBestLandCompression = 1.f, gBestWaterCompression = 1.f; -F32 gWorstLandCompression = 0.f, gWorstWaterCompression = 0.f; +U32 gTotalLandIn = 0, + gTotalLandOut = 0, + gTotalWaterIn = 0, + gTotalWaterOut = 0; + +F32 gAveLandCompression = 0.f, + gAveWaterCompression = 0.f, + gBestLandCompression = 1.f, + gBestWaterCompression = 1.f, + gWorstLandCompression = 0.f, + gWorstWaterCompression = 0.f; LLUnit::Bytes gTotalWorldData = 0, gTotalObjectData = 0, gTotalTextureData = 0; -U32 gSimPingCount = 0; +U32 gSimPingCount = 0; LLUnit::Bits gObjectData = 0; -F32 gAvgSimPing = 0.f; -LLUnit::Bytes gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGORY] = {0}; +F32 gAvgSimPing = 0.f; +LLUnit::Bytes gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGORY] = {0}; extern U32 gVisCompared; extern U32 gVisTested; @@ -334,13 +339,13 @@ void update_statistics() LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost()); if (cdp) { - LLStatViewer::SIM_PING.sample(cdp->getPingDelay()); + LLStatViewer::SIM_PING.sample(cdp->getPingDelay()); gAvgSimPing = ((gAvgSimPing * (F32)gSimPingCount) + (F32)(cdp->getPingDelay())) / ((F32)gSimPingCount + 1); gSimPingCount++; } else { - LLStatViewer::SIM_PING.sample(10000); + LLStatViewer::SIM_PING.sample(10); } LLStatViewer::FPS.add(1); @@ -390,8 +395,6 @@ void update_statistics() texture_stats_timer.reset(); } } - - LLTrace::get_frame_recording().nextPeriod(); } class ViewerStatsResponder : public LLHTTPClient::Responder diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index 34731481f5..eda7b3329d 100755 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -27,7 +27,6 @@ #ifndef LL_LLVIEWERSTATS_H #define LL_LLVIEWERSTATS_H -#include "llstat.h" #include "llstatenums.h" #include "lltextureinfo.h" #include "lltracerecording.h" diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index a00f48b5a2..e3df71cca2 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -30,7 +30,6 @@ #include "lluuid.h" //#include "message.h" #include "llgl.h" -#include "llstat.h" #include "llviewertexture.h" #include "llui.h" #include diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 06daf15c08..b7415669bb 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -77,7 +77,6 @@ #include "llmediaentry.h" #include "llurldispatcher.h" #include "raytrace.h" -#include "llstat.h" // newview includes #include "llagent.h" @@ -249,6 +248,9 @@ std::string LLViewerWindow::sSnapshotDir; std::string LLViewerWindow::sMovieBaseName; +LLTrace::Measurement<> LLViewerWindow::sMouseVelocityStat("Mouse Velocity"); + + class RecordToChatConsole : public LLError::Recorder, public LLSingleton { public: @@ -1541,8 +1543,7 @@ LLViewerWindow::LLViewerWindow(const Params& p) mResDirty(false), mStatesDirty(false), mCurrResolutionIndex(0), - mProgressView(NULL), - mMouseVelocityStat(new LLStat("Mouse Velocity")) + mProgressView(NULL) { // gKeyboard is still NULL, so it doesn't do LLWindowListener any good to // pass its value right now. Instead, pass it a nullary function that @@ -2072,8 +2073,6 @@ LLViewerWindow::~LLViewerWindow() delete mDebugText; mDebugText = NULL; - - delete mMouseVelocityStat; } @@ -3247,7 +3246,7 @@ void LLViewerWindow::updateMouseDelta() mouse_vel.setVec((F32) dx, (F32) dy); } - mMouseVelocityStat->addValue(mouse_vel.magVec()); + sMouseVelocityStat.sample(mouse_vel.magVec()); } void LLViewerWindow::updateKeyboardFocus() diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 5f475fe145..be2d6d885e 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -44,12 +44,12 @@ #include "llmousehandler.h" #include "llhandle.h" #include "llinitparam.h" +#include "lltrace.h" #include #include #include -class LLStat; class LLView; class LLViewerObject; class LLUUID; @@ -250,7 +250,7 @@ public: S32 getCurrentMouseDX() const { return mCurrentMouseDelta.mX; } S32 getCurrentMouseDY() const { return mCurrentMouseDelta.mY; } LLCoordGL getCurrentMouseDelta() const { return mCurrentMouseDelta; } - LLStat* getMouseVelocityStat() { return mMouseVelocityStat; } + static LLTrace::Measurement<>* getMouseVelocityStat() { return &sMouseVelocityStat; } BOOL getLeftMouseDown() const { return mLeftMouseDown; } BOOL getMiddleMouseDown() const { return mMiddleMouseDown; } BOOL getRightMouseDown() const { return mRightMouseDown; } @@ -427,7 +427,6 @@ private: LLCoordGL mCurrentMousePoint; // last mouse position in GL coords LLCoordGL mLastMousePoint; // Mouse point at last frame. LLCoordGL mCurrentMouseDelta; //amount mouse moved this frame - LLStat* mMouseVelocityStat; BOOL mLeftMouseDown; BOOL mMiddleMouseDown; BOOL mRightMouseDown; @@ -482,6 +481,8 @@ private: // Object temporarily hovered over while dragging LLPointer mDragHoveredObject; + + static LLTrace::Measurement<> sMouseVelocityStat; }; // diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 97c1b07ebc..3c1f8ca6b0 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -4318,8 +4318,6 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) //-------------------------------------------------------------------- // render all geometry attached to the skeleton //-------------------------------------------------------------------- - static LLStat render_stat; - LLViewerJointMesh::sRenderPass = pass; if (pass == AVATAR_RENDER_PASS_SINGLE) @@ -4372,10 +4370,6 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) LLViewerJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE; - //llinfos << "Avatar render: " << render_timer.getElapsedTimeF32() << llendl; - - //render_stat.addValue(render_timer.getElapsedTimeF32()*1000.f); - return num_indices; } diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index dced5a847b..e140f3b23b 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -692,8 +692,10 @@ void LLWorld::updateNetStats() { LLViewerRegion* regionp = *iter; regionp->updateNetStats(); - bits += regionp->mBitStat.getCurrent(); - packets += llfloor( regionp->mPacketsStat.getCurrent() ); + bits += regionp->mBitsReceived; + packets += llfloor( regionp->mPacketsReceived ); + regionp->mBitsReceived = 0.f; + regionp->mPacketsReceived = 0.f; } S32 packets_in = gMessageSystem->mPacketsIn - mLastPacketsIn; @@ -705,26 +707,15 @@ void LLWorld::updateNetStats() LLStatViewer::ACTUAL_IN_KBIT.add(actual_in_bits); LLStatViewer::ACTUAL_OUT_KBIT.add(actual_out_bits); - //LLViewerStats::getInstance()->mActualInKBitStat.addValue(actual_in_bits/1024.f); - //LLViewerStats::getInstance()->mActualOutKBitStat.addValue(actual_out_bits/1024.f); LLStatViewer::KBIT.add(bits); - //LLViewerStats::getInstance()->mKBitStat.addValue(bits/1024.f); LLStatViewer::PACKETS_IN.add(packets_in); LLStatViewer::PACKETS_OUT.add(packets_out); LLStatViewer::PACKETS_LOST.add(packets_lost); LLStatViewer::PACKETS_LOST_PERCENT.sample(100.f*((F32)packets_lost/(F32)packets_in)); - //LLViewerStats::getInstance()->mPacketsInStat.addValue(packets_in); - //LLViewerStats::getInstance()->mPacketsOutStat.addValue(packets_out); - //LLViewerStats::getInstance()->mPacketsLostStat.addValue(gMessageSystem->mDroppedPackets); if (packets_in) { LLStatViewer::PACKETS_LOST_PERCENT.sample(100.f*((F32)packets_lost/(F32)packets_in)); - // LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(100.f*((F32)packets_lost/(F32)packets_in)); } - //else - //{ - // LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(0.f); - //} mLastPacketsIn = gMessageSystem->mPacketsIn; mLastPacketsOut = gMessageSystem->mPacketsOut; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 75af605ad7..1e050d2588 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -488,7 +488,6 @@ void LLPipeline::init() getPool(LLDrawPool::POOL_BUMP); getPool(LLDrawPool::POOL_GLOW); - //LLViewerStats::getInstance()->mTrianglesDrawnStat.reset(); resetFrameStats(); for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) @@ -1769,7 +1768,6 @@ void LLPipeline::resetFrameStats() assertInitialized(); LLStatViewer::TRIANGLES_DRAWN.add(mTrianglesDrawn); - //LLViewerStats::getInstance()->mTrianglesDrawnStat.addValue(mTrianglesDrawn/1000.f); if (mBatchCount > 0) { @@ -9756,7 +9754,9 @@ void LLPipeline::generateSunShadow(LLCamera& camera) if (gen_shadow) { - F32 fade_amt = gFrameIntervalSeconds.value() * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f); + LLTrace::Measurement<>* velocity_stat = LLViewerCamera::getVelocityStat(); + F32 fade_amt = gFrameIntervalSeconds.value() + * llmax(LLTrace::get_frame_recording().getLastRecordingPeriod().getLastValue(*velocity_stat), 1.0); //update shadow targets for (U32 i = 0; i < 2; i++) -- cgit v1.3 From 74fe126590fba03752d1d8d88dd3bb59c6900026 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 1 Nov 2012 17:52:11 -0700 Subject: SH-3405 FIX convert existing stats to lltrace system output of floater_stats is now identical to pre-lltrace system (with some tweaks) --- indra/llcommon/lltrace.h | 95 ++++++++++++---------- indra/llcommon/lltracerecording.cpp | 34 ++++++-- indra/llcommon/lltracerecording.h | 6 +- indra/llcommon/lltracethreadrecorder.cpp | 6 +- indra/llui/llstatbar.cpp | 6 ++ indra/llui/llstatbar.h | 5 +- indra/newview/llviewercamera.cpp | 1 - indra/newview/llworld.cpp | 1 - indra/newview/pipeline.cpp | 4 +- .../newview/skins/default/xui/en/floater_stats.xml | 16 +++- 10 files changed, 108 insertions(+), 66 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 2823db5cbb..735c45754c 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -138,11 +138,11 @@ namespace LLTrace } } - void reset() + void reset(const AccumulatorBuffer* other = NULL) { for (size_t i = 0; i < mNextStorageSlot; i++) { - mStorage[i].reset(); + mStorage[i].reset(other ? &other->mStorage[i] : NULL); } } @@ -285,54 +285,60 @@ namespace LLTrace void addSamples(const self_t& other) { - mSum += other.mSum; - if (other.mMin < mMin) - { - mMin = other.mMin; - } - if (other.mMax > mMax) - { - mMax = other.mMax; - } - mNumSamples += other.mNumSamples; - F64 weight = (F64)mNumSamples / (F64)(mNumSamples + other.mNumSamples); - mMean = mMean * weight + other.mMean * (1.f - weight); - - F64 n_1 = (F64)mNumSamples, - n_2 = (F64)other.mNumSamples; - F64 m_1 = mMean, - m_2 = other.mMean; - F64 sd_1 = getStandardDeviation(), - sd_2 = other.getStandardDeviation(); - // combine variance (and hence standard deviation) of 2 different sized sample groups using - // the following formula: http://www.mrc-bsu.cam.ac.uk/cochrane/handbook/chapter_7/7_7_3_8_combining_groups.htm - if (n_1 == 0) + if (other.mNumSamples) { - mVarianceSum = other.mVarianceSum; + mSum += other.mSum; + if (other.mMin < mMin) + { + mMin = other.mMin; + } + if (other.mMax > mMax) + { + mMax = other.mMax; + } + F64 weight = (F64)mNumSamples / (F64)(mNumSamples + other.mNumSamples); + mNumSamples += other.mNumSamples; + mMean = mMean * weight + other.mMean * (1.f - weight); + + F64 n_1 = (F64)mNumSamples, + n_2 = (F64)other.mNumSamples; + F64 m_1 = mMean, + m_2 = other.mMean; + F64 sd_1 = getStandardDeviation(), + sd_2 = other.getStandardDeviation(); + // combine variance (and hence standard deviation) of 2 different sized sample groups using + // the following formula: http://www.mrc-bsu.cam.ac.uk/cochrane/handbook/chapter_7/7_7_3_8_combining_groups.htm + if (n_1 == 0) + { + mVarianceSum = other.mVarianceSum; + } + else if (n_2 == 0) + { + // don't touch variance + // mVarianceSum = mVarianceSum; + } + else + { + mVarianceSum = (F64)mNumSamples + * ((((n_1 - 1.f) * sd_1 * sd_1) + + ((n_2 - 1.f) * sd_2 * sd_2) + + (((n_1 * n_2) / (n_1 + n_2)) + * ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2)))) + / (n_1 + n_2 - 1.f)); + } + mLastValue = other.mLastValue; } - else if (n_2 == 0) - { - // don't touch variance - // mVarianceSum = mVarianceSum; - } - else - { - mVarianceSum = (F64)mNumSamples - * ((((n_1 - 1.f) * sd_1 * sd_1) - + ((n_2 - 1.f) * sd_2 * sd_2) - + (((n_1 * n_2) / (n_1 + n_2)) - * ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2)))) - / (n_1 + n_2 - 1.f)); - } - mLastValue = other.mLastValue; } - void reset() + void reset(const self_t* other) { mNumSamples = 0; mSum = 0; mMin = 0; mMax = 0; + mMean = 0; + mVarianceSum = 0; + mLastValue = other ? other->mLastValue : 0; } T getSum() const { return (T)mSum; } @@ -359,6 +365,7 @@ namespace LLTrace class LL_COMMON_API CountAccumulator { public: + typedef CountAccumulator self_t; typedef T value_t; CountAccumulator() @@ -378,7 +385,7 @@ namespace LLTrace mNumSamples += other.mNumSamples; } - void reset() + void reset(const self_t* other) { mNumSamples = 0; mSum = 0; @@ -475,6 +482,8 @@ namespace LLTrace class LL_COMMON_API TimerAccumulator { public: + typedef TimerAccumulator self_t; + U32 mTotalTimeCounter, mChildTimeCounter, mCalls; @@ -493,7 +502,7 @@ namespace LLTrace mCalls += other.mCalls; } - void reset() + void reset(const self_t* other) { mTotalTimeCounter = 0; mChildTimeCounter = 0; diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index f44a0a2764..a2733fd0e7 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -87,6 +87,8 @@ void Recording::handleSplitTo(Recording& other) { stop(); other.restart(); + other.mMeasurementsFloat.write()->reset(mMeasurementsFloat); + other.mMeasurements.write()->reset(mMeasurements); } @@ -104,7 +106,7 @@ bool Recording::isPrimary() const return mCounts->isPrimary(); } -void Recording::mergeRecording( const Recording& other ) +void Recording::appendRecording( const Recording& other ) { mCountsFloat.write()->addSamples(*other.mCountsFloat); mMeasurementsFloat.write()->addSamples(*other.mMeasurementsFloat); @@ -138,22 +140,34 @@ S64 Recording::getSum( const TraceType >& stat ) con F64 Recording::getPerSec( const TraceType >& stat ) const { - return stat.getAccumulator(mCountsFloat).getSum() / mElapsedSeconds; + F64 sum = stat.getAccumulator(mCountsFloat).getSum(); + return (sum != 0.0) + ? (sum / mElapsedSeconds) + : 0.0; } F64 Recording::getPerSec( const TraceType >& stat ) const { - return (F64)stat.getAccumulator(mCounts).getSum() / mElapsedSeconds; + S64 sum = stat.getAccumulator(mCounts).getSum(); + return (sum != 0) + ? ((F64)sum / mElapsedSeconds) + : 0.0; } F64 Recording::getPerSec( const TraceType >& stat ) const { - return stat.getAccumulator(mMeasurementsFloat).getSum() / mElapsedSeconds; + F64 sum = stat.getAccumulator(mMeasurementsFloat).getSum(); + return (sum != 0.0) + ? (sum / mElapsedSeconds) + : 0.0; } F64 Recording::getPerSec( const TraceType >& stat ) const { - return (F64)stat.getAccumulator(mMeasurements).getSum() / mElapsedSeconds; + S64 sum = stat.getAccumulator(mMeasurements).getSum(); + return (sum != 0) + ? ((F64)sum / mElapsedSeconds) + : 0.0; } F64 Recording::getMin( const TraceType >& stat ) const @@ -240,17 +254,19 @@ PeriodicRecording::~PeriodicRecording() void PeriodicRecording::nextPeriod() { EPlayState play_state = getPlayState(); - getCurRecordingPeriod().stop(); + Recording& old_recording = getCurRecordingPeriod(); mCurPeriod = (mCurPeriod + 1) % mNumPeriods; + old_recording.splitTo(getCurRecordingPeriod()); + switch(play_state) { case STOPPED: + getCurRecordingPeriod().stop(); break; case PAUSED: getCurRecordingPeriod().pause(); break; case STARTED: - getCurRecordingPeriod().start(); break; } // new period, need to recalculate total @@ -264,7 +280,7 @@ Recording& PeriodicRecording::getTotalRecording() mTotalRecording.reset(); for (S32 i = mCurPeriod + 1; i < mCurPeriod + mNumPeriods; i++) { - mTotalRecording.mergeRecording(mRecordingPeriods[i % mNumPeriods]); + mTotalRecording.appendRecording(mRecordingPeriods[i % mNumPeriods]); } } mTotalValid = true; @@ -298,7 +314,7 @@ void PeriodicRecording::handleSplitTo( PeriodicRecording& other ) void ExtendableRecording::extend() { - mAcceptedRecording.mergeRecording(mPotentialRecording); + mAcceptedRecording.appendRecording(mPotentialRecording); mPotentialRecording.reset(); } diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index 4af973515d..a11f04b14b 100644 --- a/indra/llcommon/lltracerecording.h +++ b/indra/llcommon/lltracerecording.h @@ -81,12 +81,12 @@ class LLVCRControlsMixin public: void splitTo(DERIVED& other) { - onSplitTo(other); + handleSplitTo(other); } void splitFrom(DERIVED& other) { - other.onSplitTo(*this); + other.handleSplitTo(*this); } private: // atomically stop this object while starting the other @@ -107,7 +107,7 @@ namespace LLTrace void makePrimary(); bool isPrimary() const; - void mergeRecording(const Recording& other); + void appendRecording(const Recording& other); void update(); diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 15056b80e4..0feb3ab7af 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -73,7 +73,7 @@ std::list::iterator ThreadRecorder::update( Rec if (next_it != mActiveRecordings.end()) { // ...push our gathered data down to it - next_it->mBaseline.mergeRecording(it->mBaseline); + next_it->mBaseline.appendRecording(it->mBaseline); } // copy accumulated measurements into result buffer and clear accumulator (mBaseline) @@ -153,13 +153,13 @@ void SlaveThreadRecorder::pushToMaster() void SlaveThreadRecorder::SharedData::copyFrom( const Recording& source ) { LLMutexLock lock(&mRecordingMutex); - mRecording.mergeRecording(source); + mRecording.appendRecording(source); } void SlaveThreadRecorder::SharedData::copyTo( Recording& sink ) { LLMutexLock lock(&mRecordingMutex); - sink.mergeRecording(mRecording); + sink.appendRecording(mRecording); } /////////////////////////////////////////////////////////////////////// diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp index 6b40f8d475..1bc9a9fc67 100644 --- a/indra/llui/llstatbar.cpp +++ b/indra/llui/llstatbar.cpp @@ -53,6 +53,7 @@ LLStatBar::LLStatBar(const Params& p) mLabelSpacing(p.label_spacing), mPrecision(p.precision), mUpdatesPerSec(p.update_rate), + mUnitScale(p.unit_scale), mPerSec(p.show_per_sec), mDisplayBar(p.show_bar), mDisplayHistory(p.show_history), @@ -148,6 +149,11 @@ void LLStatBar::draw() mean = recording.getMean(*mMeasurementIntp); } + current *= mUnitScale; + min *= mUnitScale; + max *= mUnitScale; + mean *= mUnitScale; + if ((mUpdatesPerSec == 0.f) || (mUpdateTimer.getElapsedTimeF32() > 1.f/mUpdatesPerSec) || (mValue == 0.f)) { if (mDisplayMean) diff --git a/indra/llui/llstatbar.h b/indra/llui/llstatbar.h index 6aefb1e213..083da8444e 100644 --- a/indra/llui/llstatbar.h +++ b/indra/llui/llstatbar.h @@ -44,7 +44,8 @@ public: bar_max, tick_spacing, label_spacing, - update_rate; + update_rate, + unit_scale; Optional precision; @@ -64,6 +65,7 @@ public: label_spacing("label_spacing", 10.0f), precision("precision", 0), update_rate("update_rate", 5.0f), + unit_scale("unit_scale", 1.f), show_per_sec("show_per_sec", true), show_bar("show_bar", TRUE), show_history("show_history", false), @@ -92,6 +94,7 @@ private: F32 mLabelSpacing; U32 mPrecision; F32 mUpdatesPerSec; + F32 mUnitScale; BOOL mPerSec; // Use the per sec stats. BOOL mDisplayBar; // Display the bar graph. BOOL mDisplayHistory; diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index 831304f428..f74897daa7 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -170,7 +170,6 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 ¢er, sVelocityStat.add(dpos); sAngularVelocityStat.add(drot); - LLTrace::Recording& recording = LLTrace::get_frame_recording().getTotalRecording(); mAverageSpeed = LLTrace::get_frame_recording().getPeriodMeanPerSec(sVelocityStat); mAverageAngularSpeed = LLTrace::get_frame_recording().getPeriodMeanPerSec(sAngularVelocityStat); mCosHalfCameraFOV = cosf(0.5f * getView() * llmax(1.0f, getAspect())); diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index e140f3b23b..126dc59929 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -711,7 +711,6 @@ void LLWorld::updateNetStats() LLStatViewer::PACKETS_IN.add(packets_in); LLStatViewer::PACKETS_OUT.add(packets_out); LLStatViewer::PACKETS_LOST.add(packets_lost); - LLStatViewer::PACKETS_LOST_PERCENT.sample(100.f*((F32)packets_lost/(F32)packets_in)); if (packets_in) { LLStatViewer::PACKETS_LOST_PERCENT.sample(100.f*((F32)packets_lost/(F32)packets_in)); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 1e050d2588..bf353cd1e0 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -9754,9 +9754,9 @@ void LLPipeline::generateSunShadow(LLCamera& camera) if (gen_shadow) { - LLTrace::Measurement<>* velocity_stat = LLViewerCamera::getVelocityStat(); + LLTrace::Count<>* velocity_stat = LLViewerCamera::getVelocityStat(); F32 fade_amt = gFrameIntervalSeconds.value() - * llmax(LLTrace::get_frame_recording().getLastRecordingPeriod().getLastValue(*velocity_stat), 1.0); + * llmax(LLTrace::get_frame_recording().getLastRecordingPeriod().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecordingPeriod().getDuration().value(), 1.0); //update shadow targets for (U32 i = 0; i < 2; i++) diff --git a/indra/newview/skins/default/xui/en/floater_stats.xml b/indra/newview/skins/default/xui/en/floater_stats.xml index f9eb16d224..273954ee3e 100644 --- a/indra/newview/skins/default/xui/en/floater_stats.xml +++ b/indra/newview/skins/default/xui/en/floater_stats.xml @@ -104,6 +104,7 @@ label="KTris Drawn per Frame" unit_label="/fr" stat="trianglesdrawnstat" + unit_scale="0.001" bar_min="0" bar_max="10000" tick_spacing="1000" @@ -116,6 +117,7 @@ name="ktrissec" label="KTris Drawn per Sec" unit_label="/sec" + unit_scale="0.001" stat="trianglesdrawnstat" bar_min="0" bar_max="200000" @@ -222,6 +224,8 @@ name="gltexmemstat" label="GL Mem" stat="gltexmemstat" + unit_label="MB" + unit_scale="0.000001" bar_min="0.f" bar_max="400.f" tick_spacing="100.f" @@ -235,11 +239,13 @@ name="formattedmemstat" label="Formatted Mem" stat="formattedmemstat" + unit_label="MB" + unit_scale="0.000001" bar_min="0.f" bar_max="400.f" tick_spacing="100.f" label_spacing="200.f" - precision="1" + precision="3" show_per_sec="false" show_bar="false"> @@ -247,12 +253,14 @@ @@ -261,11 +269,13 @@ name="glboundmemstat" label="Bound Mem" stat="glboundmemstat" + unit_label="MB" + unit_scale="0.000001" bar_min="0.f" bar_max="400.f" tick_spacing="100.f" label_spacing="200.f" - precision="1" + precision="3" show_per_sec="false" show_bar="false"> -- cgit v1.3 From a3e3e8b4ccd96e98da73acf1c584bbfa5a8b2b56 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 12 Nov 2012 19:08:14 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system simplified llfasttimer code down to 2 classes llunit unit conversion now done in floating point or 64 bit integer precision, depending on source type --- indra/llcommon/llfasttimer.cpp | 270 ++++++++++++-------------------------- indra/llcommon/llfasttimer.h | 121 ++++++----------- indra/llcommon/llprocessor.cpp | 2 +- indra/llcommon/llprocessor.h | 4 +- indra/llcommon/lltrace.cpp | 1 + indra/llcommon/lltrace.h | 39 ++---- indra/llcommon/lltracerecording.h | 18 +-- indra/llcommon/llunit.h | 127 +++++++++++++----- indra/newview/llfasttimerview.cpp | 98 ++++++++------ indra/newview/llfasttimerview.h | 8 +- indra/newview/pipeline.cpp | 2 +- 11 files changed, 307 insertions(+), 383 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index 4f67004773..c4839fed77 100644 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -32,6 +32,7 @@ #include "llsingleton.h" #include "lltreeiterators.h" #include "llsdserialize.h" +#include "llunit.h" #include @@ -73,13 +74,13 @@ U64 LLFastTimer::sClockResolution = 1000000; // Microsecond resolution // FIXME: move these declarations to the relevant modules // helper functions -typedef LLTreeDFSPostIter timer_tree_bottom_up_iterator_t; +typedef LLTreeDFSPostIter timer_tree_bottom_up_iterator_t; -static timer_tree_bottom_up_iterator_t begin_timer_tree_bottom_up(LLFastTimer::NamedTimer& id) +static timer_tree_bottom_up_iterator_t begin_timer_tree_bottom_up(LLFastTimer::DeclareTimer& id) { return timer_tree_bottom_up_iterator_t(&id, - boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::beginChildren), _1), - boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::endChildren), _1)); + boost::bind(boost::mem_fn(&LLFastTimer::DeclareTimer::beginChildren), _1), + boost::bind(boost::mem_fn(&LLFastTimer::DeclareTimer::endChildren), _1)); } static timer_tree_bottom_up_iterator_t end_timer_tree_bottom_up() @@ -87,14 +88,14 @@ static timer_tree_bottom_up_iterator_t end_timer_tree_bottom_up() return timer_tree_bottom_up_iterator_t(); } -typedef LLTreeDFSIter timer_tree_dfs_iterator_t; +typedef LLTreeDFSIter timer_tree_dfs_iterator_t; -static timer_tree_dfs_iterator_t begin_timer_tree(LLFastTimer::NamedTimer& id) +static timer_tree_dfs_iterator_t begin_timer_tree(LLFastTimer::DeclareTimer& id) { return timer_tree_dfs_iterator_t(&id, - boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::beginChildren), _1), - boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::endChildren), _1)); + boost::bind(boost::mem_fn(&LLFastTimer::DeclareTimer::beginChildren), _1), + boost::bind(boost::mem_fn(&LLFastTimer::DeclareTimer::endChildren), _1)); } static timer_tree_dfs_iterator_t end_timer_tree() @@ -102,75 +103,12 @@ static timer_tree_dfs_iterator_t end_timer_tree() return timer_tree_dfs_iterator_t(); } -// factory class that creates NamedTimers via static DeclareTimer objects -class NamedTimerFactory : public LLSingleton +LLFastTimer::DeclareTimer& LLFastTimer::DeclareTimer::getRootTimer() { -public: - NamedTimerFactory() - : mTimerRoot(NULL) - {} - - /*virtual */ void initSingleton() - { - mTimerRoot = new LLFastTimer::NamedTimer("root"); - mRootFrameState.setNamedTimer(mTimerRoot); - mTimerRoot->setFrameState(&mRootFrameState); - mTimerRoot->mParent = mTimerRoot; - mTimerRoot->setCollapsed(false); - mRootFrameState.mParent = &mRootFrameState; - } - - ~NamedTimerFactory() - { - std::for_each(mTimers.begin(), mTimers.end(), DeletePairedPointer()); - - delete mTimerRoot; - } - - LLFastTimer::NamedTimer& createNamedTimer(const std::string& name, LLFastTimer::FrameState* state) - { - LLFastTimer::NamedTimer* timer = new LLFastTimer::NamedTimer(name); - timer->setFrameState(state); - timer->setParent(mTimerRoot); - mTimers.insert(std::make_pair(name, timer)); - - return *timer; - } - - LLFastTimer::NamedTimer* getTimerByName(const std::string& name) - { - timer_map_t::iterator found_it = mTimers.find(name); - if (found_it != mTimers.end()) - { - return found_it->second; - } - return NULL; - } - - LLFastTimer::NamedTimer* getRootTimer() { return mTimerRoot; } - - typedef std::multimap timer_map_t; - timer_map_t::iterator beginTimers() { return mTimers.begin(); } - timer_map_t::iterator endTimers() { return mTimers.end(); } - S32 timerCount() { return mTimers.size(); } - -private: - timer_map_t mTimers; - - LLFastTimer::NamedTimer* mTimerRoot; - LLFastTimer::FrameState mRootFrameState; -}; - -LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name, bool open ) -: mTimer(NamedTimerFactory::instance().createNamedTimer(name, &mFrameState)) -{ - mTimer.setCollapsed(!open); + static DeclareTimer root_timer("root", true, NULL); + return root_timer; } -LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name) -: mTimer(NamedTimerFactory::instance().createNamedTimer(name, &mFrameState)) -{ -} //static #if (LL_DARWIN || LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__)) @@ -183,7 +121,7 @@ U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer { #if LL_FASTTIMER_USE_RDTSC || !LL_WINDOWS //getCPUFrequency returns MHz and sCPUClockFrequency wants to be in Hz - static U64 sCPUClockFrequency = U64(LLProcessorInfo().getCPUFrequency()*1000000.0); + static LLUnit sCPUClockFrequency = LLProcessorInfo().getCPUFrequency(); // we drop the low-order byte in our timers, so report a lower frequency #else @@ -206,49 +144,44 @@ LLFastTimer::FrameState::FrameState() : mActiveCount(0), mCalls(0), mSelfTimeCounter(0), - mParent(NULL), mLastCaller(NULL), mMoveUpTree(false) {} -LLFastTimer::NamedTimer::NamedTimer(const std::string& name) +LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name, bool open, DeclareTimer* parent) : mName(name), mCollapsed(true), mParent(NULL), mTreeTimeCounter(0), mCountAverage(0), mCallAverage(0), - mNeedsSorting(false), - mFrameState(NULL) + mNeedsSorting(false) { + setCollapsed(!open); + + if (parent) + { + setParent(parent); + } + else + { + mParent = this; + } + mCountHistory = new U32[HISTORY_NUM]; memset(mCountHistory, 0, sizeof(U32) * HISTORY_NUM); mCallHistory = new U32[HISTORY_NUM]; memset(mCallHistory, 0, sizeof(U32) * HISTORY_NUM); } -LLFastTimer::NamedTimer::~NamedTimer() +LLFastTimer::DeclareTimer::~DeclareTimer() { delete[] mCountHistory; delete[] mCallHistory; } -std::string LLFastTimer::NamedTimer::getToolTip(S32 history_idx) -{ - F64 ms_multiplier = 1000.0 / (F64)LLFastTimer::countsPerSecond(); - if (history_idx < 0) - { - // by default, show average number of call - return llformat("%s (%d ms, %d calls)", getName().c_str(), (S32)(getCountAverage() * ms_multiplier), (S32)getCallAverage()); - } - else - { - return llformat("%s (%d ms, %d calls)", getName().c_str(), (S32)(getHistoricalCount(history_idx) * ms_multiplier), (S32)getHistoricalCalls(history_idx)); - } -} - -void LLFastTimer::NamedTimer::setParent(NamedTimer* parent) +void LLFastTimer::DeclareTimer::setParent(DeclareTimer* parent) { llassert_always(parent != this); llassert_always(parent != NULL); @@ -264,8 +197,8 @@ void LLFastTimer::NamedTimer::setParent(NamedTimer* parent) // subtract average timing from previous parent mParent->mCountAverage -= mCountAverage; - std::vector& children = mParent->getChildren(); - std::vector::iterator found_it = std::find(children.begin(), children.end(), this); + std::vector& children = mParent->getChildren(); + std::vector::iterator found_it = std::find(children.begin(), children.end(), this); if (found_it != children.end()) { children.erase(found_it); @@ -275,16 +208,15 @@ void LLFastTimer::NamedTimer::setParent(NamedTimer* parent) mParent = parent; if (parent) { - getFrameState().mParent = &parent->getFrameState(); parent->getChildren().push_back(this); parent->mNeedsSorting = true; } } -S32 LLFastTimer::NamedTimer::getDepth() +S32 LLFastTimer::DeclareTimer::getDepth() { S32 depth = 0; - NamedTimer* timerp = mParent; + DeclareTimer* timerp = mParent; while(timerp) { depth++; @@ -295,7 +227,7 @@ S32 LLFastTimer::NamedTimer::getDepth() } // static -void LLFastTimer::NamedTimer::processTimes() +void LLFastTimer::DeclareTimer::processTimes() { if (sCurFrameIndex < 0) return; @@ -306,14 +238,14 @@ void LLFastTimer::NamedTimer::processTimes() // sort child timers by name struct SortTimerByName { - bool operator()(const LLFastTimer::NamedTimer* i1, const LLFastTimer::NamedTimer* i2) + bool operator()(const LLFastTimer::DeclareTimer* i1, const LLFastTimer::DeclareTimer* i2) { return i1->getName() < i2->getName(); } }; //static -void LLFastTimer::NamedTimer::buildHierarchy() +void LLFastTimer::DeclareTimer::buildHierarchy() { if (sCurFrameIndex < 0 ) return; @@ -321,16 +253,16 @@ void LLFastTimer::NamedTimer::buildHierarchy() { for (instance_iter it = beginInstances(), end_it = endInstances(); it != end_it; ++it) { - NamedTimer& timer = *it; - if (&timer == NamedTimerFactory::instance().getRootTimer()) continue; + DeclareTimer& timer = *it; + if (&timer == &DeclareTimer::getRootTimer()) continue; // bootstrap tree construction by attaching to last timer to be on stack // when this timer was called - if (timer.getFrameState().mLastCaller && timer.mParent == NamedTimerFactory::instance().getRootTimer()) + if (timer.mLastCaller && timer.mParent == &DeclareTimer::getRootTimer()) { - timer.setParent(timer.getFrameState().mLastCaller->mTimer); + timer.setParent(timer.mLastCaller); // no need to push up tree on first use, flag can be set spuriously - timer.getFrameState().mMoveUpTree = false; + timer.mMoveUpTree = false; } } } @@ -338,22 +270,22 @@ void LLFastTimer::NamedTimer::buildHierarchy() // bump timers up tree if they've been flagged as being in the wrong place // do this in a bottom up order to promote descendants first before promoting ancestors // this preserves partial order derived from current frame's observations - for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(*NamedTimerFactory::instance().getRootTimer()); + for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(DeclareTimer::getRootTimer()); it != end_timer_tree_bottom_up(); ++it) { - NamedTimer* timerp = *it; + DeclareTimer* timerp = *it; // skip root timer - if (timerp == NamedTimerFactory::instance().getRootTimer()) continue; + if (timerp == &DeclareTimer::getRootTimer()) continue; - if (timerp->getFrameState().mMoveUpTree) + if (timerp->mMoveUpTree) { // since ancestors have already been visited, reparenting won't affect tree traversal //step up tree, bringing our descendants with us LL_DEBUGS("FastTimers") << "Moving " << timerp->getName() << " from child of " << timerp->getParent()->getName() << " to child of " << timerp->getParent()->getParent()->getName() << LL_ENDL; timerp->setParent(timerp->getParent()->getParent()); - timerp->getFrameState().mMoveUpTree = false; + timerp->mMoveUpTree = false; // don't bubble up any ancestors until descendants are done bubbling up it.skipAncestors(); @@ -361,11 +293,11 @@ void LLFastTimer::NamedTimer::buildHierarchy() } // sort timers by time last called, so call graph makes sense - for(timer_tree_dfs_iterator_t it = begin_timer_tree(*NamedTimerFactory::instance().getRootTimer()); + for(timer_tree_dfs_iterator_t it = begin_timer_tree(DeclareTimer::getRootTimer()); it != end_timer_tree(); ++it) { - NamedTimer* timerp = (*it); + DeclareTimer* timerp = (*it); if (timerp->mNeedsSorting) { std::sort(timerp->getChildren().begin(), timerp->getChildren().end(), SortTimerByName()); @@ -375,7 +307,7 @@ void LLFastTimer::NamedTimer::buildHierarchy() } //static -void LLFastTimer::NamedTimer::accumulateTimings() +void LLFastTimer::DeclareTimer::accumulateTimings() { U32 cur_time = getCPUClockCount32(); @@ -388,8 +320,8 @@ void LLFastTimer::NamedTimer::accumulateTimings() U32 cumulative_time_delta = cur_time - cur_timer->mStartTime; U32 self_time_delta = cumulative_time_delta - cur_data->mChildTime; cur_data->mChildTime = 0; - cur_data->mFrameState->mSelfTimeCounter += self_time_delta; - cur_data->mFrameState->mTotalTimeCounter += cumulative_time_delta; + cur_data->mTimerData->mSelfTimeCounter += self_time_delta; + cur_data->mTimerData->mTotalTimeCounter += cumulative_time_delta; cur_timer->mStartTime = cur_time; @@ -400,12 +332,12 @@ void LLFastTimer::NamedTimer::accumulateTimings() } // traverse tree in DFS post order, or bottom up - for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(*NamedTimerFactory::instance().getRootTimer()); + for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(DeclareTimer::getRootTimer()); it != end_timer_tree_bottom_up(); ++it) { - NamedTimer* timerp = (*it); - timerp->mTreeTimeCounter = timerp->getFrameState().mSelfTimeCounter; + DeclareTimer* timerp = (*it); + timerp->mTreeTimeCounter = timerp->mSelfTimeCounter; for (child_const_iter child_it = timerp->beginChildren(); child_it != timerp->endChildren(); ++child_it) { timerp->mTreeTimeCounter += (*child_it)->mTreeTimeCounter; @@ -418,15 +350,15 @@ void LLFastTimer::NamedTimer::accumulateTimings() int hidx = cur_frame % HISTORY_NUM; timerp->mCountHistory[hidx] = timerp->mTreeTimeCounter; - timerp->mCountAverage = ((U64)timerp->mCountAverage * cur_frame + timerp->mTreeTimeCounter) / (cur_frame+1); - timerp->mCallHistory[hidx] = timerp->getFrameState().mCalls; - timerp->mCallAverage = ((U64)timerp->mCallAverage * cur_frame + timerp->getFrameState().mCalls) / (cur_frame+1); + timerp->mCountAverage = ((U64)timerp->mCountAverage * cur_frame + timerp->mTreeTimeCounter) / (cur_frame+1); + timerp->mCallHistory[hidx] = timerp->mCalls; + timerp->mCallAverage = ((U64)timerp->mCallAverage * cur_frame + timerp->mCalls) / (cur_frame+1); } } } // static -void LLFastTimer::NamedTimer::resetFrame() +void LLFastTimer::DeclareTimer::resetFrame() { if (sLog) { //output current frame counts to performance log @@ -435,11 +367,11 @@ void LLFastTimer::NamedTimer::resetFrame() if (call_count % 100 == 0) { LL_DEBUGS("FastTimers") << "countsPerSecond (32 bit): " << countsPerSecond() << LL_ENDL; - LL_DEBUGS("FastTimers") << "get_clock_count (64 bit): " << get_clock_count() << llendl; + LL_DEBUGS("FastTimers") << "get_clock_count (64 bit): " << get_clock_count() << LL_ENDL; LL_DEBUGS("FastTimers") << "LLProcessorInfo().getCPUFrequency() " << LLProcessorInfo().getCPUFrequency() << LL_ENDL; LL_DEBUGS("FastTimers") << "getCPUClockCount32() " << getCPUClockCount32() << LL_ENDL; LL_DEBUGS("FastTimers") << "getCPUClockCount64() " << getCPUClockCount64() << LL_ENDL; - LL_DEBUGS("FastTimers") << "elapsed sec " << ((F64)getCPUClockCount64())/((F64)LLProcessorInfo().getCPUFrequency()*1000000.0) << LL_ENDL; + LL_DEBUGS("FastTimers") << "elapsed sec " << ((F64)getCPUClockCount64()) / (LLUnit(LLProcessorInfo().getCPUFrequency())) << LL_ENDL; } call_count++; @@ -451,14 +383,13 @@ void LLFastTimer::NamedTimer::resetFrame() { for (instance_iter it = beginInstances(), end_it = endInstances(); it != end_it; ++it) { - NamedTimer& timer = *it; - FrameState& info = timer.getFrameState(); - sd[timer.getName()]["Time"] = (LLSD::Real) (info.mSelfTimeCounter*iclock_freq); - sd[timer.getName()]["Calls"] = (LLSD::Integer) info.mCalls; + DeclareTimer& timer = *it; + sd[timer.getName()]["Time"] = (LLSD::Real) (timer.mSelfTimeCounter*iclock_freq); + sd[timer.getName()]["Calls"] = (LLSD::Integer) timer.mCalls; // computing total time here because getting the root timer's getCountHistory // doesn't work correctly on the first frame - total_time = total_time + info.mSelfTimeCounter * iclock_freq; + total_time = total_time + timer.mSelfTimeCounter * iclock_freq; } } @@ -474,23 +405,16 @@ void LLFastTimer::NamedTimer::resetFrame() // reset for next frame for (instance_iter it = beginInstances(), end_it = endInstances(); it != end_it; ++it) { - NamedTimer& timer = *it; - - FrameState& info = timer.getFrameState(); - info.mSelfTimeCounter = 0; - info.mCalls = 0; - info.mLastCaller = NULL; - info.mMoveUpTree = false; - // update parent pointer in timer state struct - if (timer.mParent) - { - info.mParent = &timer.mParent->getFrameState(); - } + DeclareTimer& timer = *it; + timer.mSelfTimeCounter = 0; + timer.mCalls = 0; + timer.mLastCaller = NULL; + timer.mMoveUpTree = false; } } //static -void LLFastTimer::NamedTimer::reset() +void LLFastTimer::DeclareTimer::reset() { resetFrame(); // reset frame data @@ -514,10 +438,10 @@ void LLFastTimer::NamedTimer::reset() { for (instance_iter it = beginInstances(), end_it = endInstances(); it != end_it; ++it) { - NamedTimer& timer = *it; - if (&timer != NamedTimerFactory::instance().getRootTimer()) + DeclareTimer& timer = *it; + if (&timer != &DeclareTimer::getRootTimer()) { - timer.setParent(NamedTimerFactory::instance().getRootTimer()); + timer.setParent(&DeclareTimer::getRootTimer()); } timer.mCountAverage = 0; @@ -531,34 +455,29 @@ void LLFastTimer::NamedTimer::reset() sCurFrameIndex = 0; } -U32 LLFastTimer::NamedTimer::getHistoricalCount(S32 history_index) const +U32 LLFastTimer::DeclareTimer::getHistoricalCount(S32 history_index) const { - S32 history_idx = (getLastFrameIndex() + history_index) % LLFastTimer::NamedTimer::HISTORY_NUM; + S32 history_idx = (getLastFrameIndex() + history_index) % LLFastTimer::DeclareTimer::HISTORY_NUM; return mCountHistory[history_idx]; } -U32 LLFastTimer::NamedTimer::getHistoricalCalls(S32 history_index ) const +U32 LLFastTimer::DeclareTimer::getHistoricalCalls(S32 history_index ) const { - S32 history_idx = (getLastFrameIndex() + history_index) % LLFastTimer::NamedTimer::HISTORY_NUM; + S32 history_idx = (getLastFrameIndex() + history_index) % LLFastTimer::DeclareTimer::HISTORY_NUM; return mCallHistory[history_idx]; } -LLFastTimer::FrameState& LLFastTimer::NamedTimer::getFrameState() const -{ - return *mFrameState; -} - -std::vector::const_iterator LLFastTimer::NamedTimer::beginChildren() +std::vector::const_iterator LLFastTimer::DeclareTimer::beginChildren() { return mChildren.begin(); } -std::vector::const_iterator LLFastTimer::NamedTimer::endChildren() +std::vector::const_iterator LLFastTimer::DeclareTimer::endChildren() { return mChildren.end(); } -std::vector& LLFastTimer::NamedTimer::getChildren() +std::vector& LLFastTimer::DeclareTimer::getChildren() { return mChildren; } @@ -575,12 +494,12 @@ void LLFastTimer::nextFrame() if (!sPauseHistory) { - NamedTimer::processTimes(); + DeclareTimer::processTimes(); sLastFrameIndex = sCurFrameIndex++; } // get ready for next frame - NamedTimer::resetFrame(); + DeclareTimer::resetFrame(); sLastFrameTime = frame_time; } @@ -588,17 +507,17 @@ void LLFastTimer::nextFrame() void LLFastTimer::dumpCurTimes() { // accumulate timings, etc. - NamedTimer::processTimes(); + DeclareTimer::processTimes(); F64 clock_freq = (F64)countsPerSecond(); F64 iclock_freq = 1000.0 / clock_freq; // clock_ticks -> milliseconds // walk over timers in depth order and output timings - for(timer_tree_dfs_iterator_t it = begin_timer_tree(*NamedTimerFactory::instance().getRootTimer()); + for(timer_tree_dfs_iterator_t it = begin_timer_tree(DeclareTimer::getRootTimer()); it != end_timer_tree(); ++it) { - NamedTimer* timerp = (*it); + DeclareTimer* timerp = (*it); F64 total_time_ms = ((F64)timerp->getHistoricalCount(0) * iclock_freq); // Don't bother with really brief times, keep output concise if (total_time_ms < 0.1) continue; @@ -621,7 +540,7 @@ void LLFastTimer::dumpCurTimes() //static void LLFastTimer::reset() { - NamedTimer::reset(); + DeclareTimer::reset(); } @@ -637,22 +556,3 @@ void LLFastTimer::writeLog(std::ostream& os) } } -//static -const LLFastTimer::NamedTimer* LLFastTimer::getTimerByName(const std::string& name) -{ - return NamedTimerFactory::instance().getTimerByName(name); -} - -//LLFastTimer::LLFastTimer(LLFastTimer::FrameState* state) -//: mFrameState(state) -//{ -// U32 start_time = getCPUClockCount32(); -// mStartTime = start_time; -// mFrameState->mActiveCount++; -// LLFastTimer::sCurTimerData.mCurTimer = this; -// LLFastTimer::sCurTimerData.mFrameState = mFrameState; -// LLFastTimer::sCurTimerData.mChildTime = 0; -// mLastTimerData = LLFastTimer::sCurTimerData; -//} - - diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index 4660fad5e3..31872e4e65 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -30,7 +30,6 @@ #include "llinstancetracker.h" #define FAST_TIMER_ON 1 -#define DEBUG_FAST_TIMER_THREADS 1 class LLMutex; @@ -45,64 +44,53 @@ LL_COMMON_API void assert_main_thread(); class LL_COMMON_API LLFastTimer { public: - class NamedTimer; - + class DeclareTimer; struct LL_COMMON_API FrameState { FrameState(); - void setNamedTimer(class NamedTimer* timerp) { mTimer = timerp; } U32 mSelfTimeCounter; U32 mTotalTimeCounter; U32 mCalls; - FrameState* mParent; // info for caller timer - FrameState* mLastCaller; // used to bootstrap tree construction - class NamedTimer* mTimer; + DeclareTimer* mLastCaller; // used to bootstrap tree construction U16 mActiveCount; // number of timers with this ID active on stack bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame }; // stores a "named" timer instance to be reused via multiple LLFastTimer stack instances - class LL_COMMON_API NamedTimer - : public LLInstanceTracker + class LL_COMMON_API DeclareTimer + : public LLInstanceTracker { - friend class DeclareTimer; public: - ~NamedTimer(); + DeclareTimer(const std::string& name, bool open = false, DeclareTimer* parent = &getRootTimer()); + ~DeclareTimer(); enum { HISTORY_NUM = 300 }; const std::string& getName() const { return mName; } - NamedTimer* getParent() const { return mParent; } - void setParent(NamedTimer* parent); + DeclareTimer* getParent() const { return mParent; } + void setParent(DeclareTimer* parent); S32 getDepth(); - std::string getToolTip(S32 history_index = -1); - typedef std::vector::const_iterator child_const_iter; + typedef std::vector::const_iterator child_const_iter; child_const_iter beginChildren(); child_const_iter endChildren(); - std::vector& getChildren(); + std::vector& getChildren(); - void setCollapsed(bool collapsed) { mCollapsed = collapsed; } - bool getCollapsed() const { return mCollapsed; } + void setCollapsed(bool collapsed) { mCollapsed = collapsed; } + bool getCollapsed() const { return mCollapsed; } U32 getCountAverage() const { return mCountAverage; } - U32 getCallAverage() const { return mCallAverage; } + U32 getCallAverage() const { return mCallAverage; } U32 getHistoricalCount(S32 history_index = 0) const; U32 getHistoricalCalls(S32 history_index = 0) const; - void setFrameState(FrameState* state) { mFrameState = state; state->setNamedTimer(this); } - FrameState& getFrameState() const; + static DeclareTimer& getRootTimer(); private: friend class LLFastTimer; - friend class NamedTimerFactory; - // - // methods - // - NamedTimer(const std::string& name); // recursive call to gather total time from children static void accumulateTimings(); @@ -117,82 +105,62 @@ public: // // members // - FrameState* mFrameState; + U32 mSelfTimeCounter; + U32 mTotalTimeCounter; + U32 mCalls; + DeclareTimer* mLastCaller; // used to bootstrap tree construction + U16 mActiveCount; // number of timers with this ID active on stack + bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame - std::string mName; + std::string mName; - // sum of recorded self time and tree time of all children timers (might not match actual recorded time of children if topology is incomplete - U32 mTreeTimeCounter; + // sum of recored self time and tree time of all children timers (might not match actual recorded time of children if topology is incomplete + U32 mTreeTimeCounter; - U32 mCountAverage; - U32 mCallAverage; + U32 mCountAverage; + U32 mCallAverage; - U32* mCountHistory; - U32* mCallHistory; + U32* mCountHistory; + U32* mCallHistory; // tree structure - NamedTimer* mParent; // NamedTimer of caller(parent) - std::vector mChildren; + DeclareTimer* mParent; // DeclareTimer of caller(parent) + std::vector mChildren; bool mCollapsed; // don't show children bool mNeedsSorting; // sort children whenever child added }; - // used to statically declare a new named timer - class LL_COMMON_API DeclareTimer - : public LLInstanceTracker - { - friend class LLFastTimer; - public: - DeclareTimer(const std::string& name, bool open); - DeclareTimer(const std::string& name); - - NamedTimer& getNamedTimer() { return mTimer; } - - private: - FrameState mFrameState; - NamedTimer& mTimer; - }; - public: - //LLFastTimer(LLFastTimer::FrameState* state); - LL_FORCE_INLINE LLFastTimer(LLFastTimer::DeclareTimer& timer) { #if FAST_TIMER_ON - LLFastTimer::FrameState* frame_state = &timer.mFrameState; mStartTime = getCPUClockCount32(); - frame_state->mActiveCount++; - frame_state->mCalls++; + timer.mActiveCount++; + timer.mCalls++; // keep current parent as long as it is active when we are - frame_state->mMoveUpTree |= (frame_state->mParent->mActiveCount == 0); + timer.mMoveUpTree |= (timer.mParent->mActiveCount == 0); LLFastTimer::CurTimerData* cur_timer_data = &LLFastTimer::sCurTimerData; mLastTimerData = *cur_timer_data; cur_timer_data->mCurTimer = this; - cur_timer_data->mFrameState = frame_state; + cur_timer_data->mTimerData = &timer; cur_timer_data->mChildTime = 0; -#endif -#if DEBUG_FAST_TIMER_THREADS -#if !LL_RELEASE - assert_main_thread(); -#endif #endif } LL_FORCE_INLINE ~LLFastTimer() { #if FAST_TIMER_ON - LLFastTimer::FrameState* frame_state = LLFastTimer::sCurTimerData.mFrameState; U32 total_time = getCPUClockCount32() - mStartTime; - - frame_state->mSelfTimeCounter += total_time - LLFastTimer::sCurTimerData.mChildTime; - frame_state->mTotalTimeCounter += total_time; - frame_state->mActiveCount--; + DeclareTimer* timer_data = LLFastTimer::sCurTimerData.mTimerData; + timer_data->mSelfTimeCounter += total_time - LLFastTimer::sCurTimerData.mChildTime; + timer_data->mTotalTimeCounter += total_time; + timer_data->mActiveCount--; // store last caller to bootstrap tree creation // do this in the destructor in case of recursion to get topmost caller - frame_state->mLastCaller = mLastTimerData.mFrameState; + timer_data->mLastCaller = mLastTimerData.mTimerData; // we are only tracking self time, so subtract our total time delta from parents mLastTimerData.mChildTime += total_time; @@ -225,12 +193,11 @@ public: static S32 getCurFrameIndex() { return sCurFrameIndex; } static void writeLog(std::ostream& os); - static const NamedTimer* getTimerByName(const std::string& name); struct CurTimerData { LLFastTimer* mCurTimer; - FrameState* mFrameState; + DeclareTimer* mTimerData; U32 mChildTime; }; static CurTimerData sCurTimerData; @@ -374,15 +341,13 @@ private: #endif - static U64 sClockResolution; - - static S32 sCurFrameIndex; - static S32 sLastFrameIndex; - static U64 sLastFrameTime; + static U64 sClockResolution; + static S32 sCurFrameIndex; + static S32 sLastFrameIndex; + static U64 sLastFrameTime; U32 mStartTime; LLFastTimer::CurTimerData mLastTimerData; - }; typedef class LLFastTimer LLFastTimer; diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index fd8f603d21..87a5930c14 100644 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -877,7 +877,7 @@ LLProcessorInfo::LLProcessorInfo() : mImpl(NULL) LLProcessorInfo::~LLProcessorInfo() {} -F64 LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); } +LLUnit LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); } bool LLProcessorInfo::hasSSE() const { return mImpl->hasSSE(); } bool LLProcessorInfo::hasSSE2() const { return mImpl->hasSSE2(); } bool LLProcessorInfo::hasAltivec() const { return mImpl->hasAltivec(); } diff --git a/indra/llcommon/llprocessor.h b/indra/llcommon/llprocessor.h index 6364d3c8bb..2a21a5c115 100644 --- a/indra/llcommon/llprocessor.h +++ b/indra/llcommon/llprocessor.h @@ -27,6 +27,8 @@ #ifndef LLPROCESSOR_H #define LLPROCESSOR_H +#include "llunit.h" + class LLProcessorInfoImpl; class LL_COMMON_API LLProcessorInfo @@ -35,7 +37,7 @@ public: LLProcessorInfo(); ~LLProcessorInfo(); - F64 getCPUFrequency() const; + LLUnit getCPUFrequency() const; bool hasSSE() const; bool hasSSE2() const; bool hasAltivec() const; diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp index d5911ece25..3f605f2c74 100644 --- a/indra/llcommon/lltrace.cpp +++ b/indra/llcommon/lltrace.cpp @@ -42,6 +42,7 @@ void init() void cleanup() { delete gMasterThreadRecorder; + LLUnitStrict seconds; gMasterThreadRecorder = NULL; } diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index d289ea9a88..549e407822 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -57,8 +57,6 @@ namespace LLTrace typedef LLUnit Milliseconds; typedef LLUnit Minutes; typedef LLUnit Hours; - typedef LLUnit Days; - typedef LLUnit Weeks; typedef LLUnit Milliseconds; typedef LLUnit Microseconds; typedef LLUnit Nanoseconds; @@ -226,27 +224,6 @@ namespace LLTrace size_t mAccumulatorIndex; }; - - template - struct StorageType - { - typedef T type_t; - }; - - template - struct StorageType - { - typedef typename StorageType::type_t type_t; - }; - - template<> struct StorageType { typedef F64 type_t; }; - template<> struct StorageType { typedef S64 type_t; }; - template<> struct StorageType { typedef S64 type_t; }; - template<> struct StorageType { typedef S64 type_t; }; - template<> struct StorageType { typedef S64 type_t; }; - template<> struct StorageType { typedef S64 type_t; }; - template<> struct StorageType { typedef S64 type_t; }; - template class LL_COMMON_API MeasurementAccumulator { @@ -406,10 +383,10 @@ namespace LLTrace template class LL_COMMON_API Measurement - : public TraceType::type_t> > + : public TraceType::type_t> > { public: - typedef typename StorageType::type_t storage_t; + typedef typename LLUnits::HighestPrecisionType::type_t storage_t; Measurement(const char* name, const char* description = NULL) : TraceType(name, description) @@ -423,10 +400,10 @@ namespace LLTrace template class LL_COMMON_API Measurement - : public TraceType::type_t> > + : public TraceType::type_t> > { public: - typedef typename StorageType::type_t storage_t; + typedef typename LLUnits::HighestPrecisionType::type_t storage_t; Measurement(const char* name, const char* description = NULL) : TraceType(name, description) @@ -446,10 +423,10 @@ namespace LLTrace template class LL_COMMON_API Count - : public TraceType::type_t> > + : public TraceType::type_t> > { public: - typedef typename StorageType::type_t storage_t; + typedef typename LLUnits::HighestPrecisionType::type_t storage_t; Count(const char* name, const char* description = NULL) : TraceType(name) @@ -463,10 +440,10 @@ namespace LLTrace template class LL_COMMON_API Count - : public TraceType::type_t> > + : public TraceType::type_t> > { public: - typedef typename StorageType::type_t storage_t; + typedef typename LLUnits::HighestPrecisionType::type_t storage_t; Count(const char* name, const char* description = NULL) : TraceType(name) diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index ca9950b78d..16b80fd1d8 100644 --- a/indra/llcommon/lltracerecording.h +++ b/indra/llcommon/lltracerecording.h @@ -122,7 +122,7 @@ namespace LLTrace template T getSum(const Count& stat) const { - return (T)getSum(static_cast::type_t> >&> (stat)); + return (T)getSum(static_cast::type_t> >&> (stat)); } F64 getPerSec(const TraceType >& stat) const; @@ -130,7 +130,7 @@ namespace LLTrace template T getPerSec(const Count& stat) const { - return (T)getPerSec(static_cast::type_t> >&> (stat)); + return (T)getPerSec(static_cast::type_t> >&> (stat)); } U32 getSampleCount(const TraceType >& stat) const; @@ -143,7 +143,7 @@ namespace LLTrace template T getSum(const Measurement& stat) const { - return (T)getSum(static_cast::type_t> >&> (stat)); + return (T)getSum(static_cast::type_t> >&> (stat)); } F64 getPerSec(const TraceType >& stat) const; @@ -151,7 +151,7 @@ namespace LLTrace template T getPerSec(const Measurement& stat) const { - return (T)getPerSec(static_cast::type_t> >&> (stat)); + return (T)getPerSec(static_cast::type_t> >&> (stat)); } F64 getMin(const TraceType >& stat) const; @@ -159,7 +159,7 @@ namespace LLTrace template T getMin(const Measurement& stat) const { - return (T)getMin(static_cast::type_t> >&> (stat)); + return (T)getMin(static_cast::type_t> >&> (stat)); } F64 getMax(const TraceType >& stat) const; @@ -167,7 +167,7 @@ namespace LLTrace template T getMax(const Measurement& stat) const { - return (T)getMax(static_cast::type_t> >&> (stat)); + return (T)getMax(static_cast::type_t> >&> (stat)); } F64 getMean(const TraceType >& stat) const; @@ -175,7 +175,7 @@ namespace LLTrace template T getMean(Measurement& stat) const { - return (T)getMean(static_cast::type_t> >&> (stat)); + return (T)getMean(static_cast::type_t> >&> (stat)); } F64 getStandardDeviation(const TraceType >& stat) const; @@ -183,7 +183,7 @@ namespace LLTrace template T getStandardDeviation(const Measurement& stat) const { - return (T)getMean(static_cast::type_t> >&> (stat)); + return (T)getMean(static_cast::type_t> >&> (stat)); } F64 getLastValue(const TraceType >& stat) const; @@ -191,7 +191,7 @@ namespace LLTrace template T getLastValue(const Measurement& stat) const { - return (T)getLastValue(static_cast::type_t> >&> (stat)); + return (T)getLastValue(static_cast::type_t> >&> (stat)); } U32 getSampleCount(const TraceType >& stat) const; diff --git a/indra/llcommon/llunit.h b/indra/llcommon/llunit.h index 0dcafbe26e..54ba1d67db 100644 --- a/indra/llcommon/llunit.h +++ b/indra/llcommon/llunit.h @@ -32,19 +32,44 @@ namespace LLUnits { -template + +template +struct HighestPrecisionType +{ + typedef T type_t; +}; + +template +struct HighestPrecisionType +{ + typedef typename HighestPrecisionType::type_t type_t; +}; + +template<> struct HighestPrecisionType { typedef F64 type_t; }; +template<> struct HighestPrecisionType { typedef S64 type_t; }; +template<> struct HighestPrecisionType { typedef S64 type_t; }; +template<> struct HighestPrecisionType { typedef S64 type_t; }; +template<> struct HighestPrecisionType { typedef S64 type_t; }; +template<> struct HighestPrecisionType { typedef S64 type_t; }; +template<> struct HighestPrecisionType { typedef S64 type_t; }; + +template struct ConversionFactor { - static F64 get() + static typename HighestPrecisionType::type_t get() { + // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template llstatic_assert(sizeof(DERIVED_UNITS_TAG) == 0, "Cannot convert between types."); } }; -template -struct ConversionFactor +template +struct ConversionFactor { - static F64 get() { return 1.0; } + static typename HighestPrecisionType::type_t get() + { + return 1; + } }; } @@ -91,6 +116,11 @@ struct LLUnit return mValue; } + template LLUnit as() + { + return LLUnit(*this); + } + void operator += (storage_t value) { mValue += value; @@ -121,7 +151,8 @@ struct LLUnit template void operator *= (LLUnit multiplicand) { - llstatic_assert(sizeof(OTHER_UNIT) == false, "Multiplication of unit types not supported."); + // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template + llstatic_assert(sizeof(OTHER_UNIT) == 0, "Multiplication of unit types not supported."); } void operator /= (storage_t divisor) @@ -132,15 +163,16 @@ struct LLUnit template void operator /= (LLUnit divisor) { - llstatic_assert(sizeof(OTHER_UNIT) == false, "Division of unit types not supported."); + // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template + llstatic_assert(sizeof(OTHER_UNIT) == 0, "Division of unit types not supported."); } - template - static storage_t convert(LLUnit v) + template + static storage_t convert(LLUnit v) { return (storage_t)(v.value() - * LLUnits::ConversionFactor::get() - * LLUnits::ConversionFactor::get()); + * LLUnits::ConversionFactor::get() + * LLUnits::ConversionFactor::get()); } protected: @@ -148,6 +180,32 @@ protected: storage_t mValue; }; +template +struct LLUnitStrict : public LLUnit +{ + typedef LLUnitStrict self_t; + + explicit LLUnitStrict(storage_t value = storage_t()) + : LLUnit(value) + {} + + template + LLUnitStrict(LLUnit other) + : LLUnit(convert(other)) + {} + + LLUnitStrict(self_t& other) + : LLUnit(other) + {} + + +private: + operator storage_t() const + { + return value(); + } +}; + // // operator + // @@ -221,7 +279,8 @@ LLUnit operator * (LLUnit firs template void operator * (LLUnit, LLUnit) { - llstatic_assert(sizeof(STORAGE_TYPE1) == false, "Multiplication of unit types results in new unit type - not supported."); + // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template + llstatic_assert(sizeof(STORAGE_TYPE1) == 0, "Multiplication of unit types results in new unit type - not supported."); } // @@ -242,7 +301,8 @@ LLUnit operator / (LLUnit firs template void operator / (LLUnit, LLUnit) { - llstatic_assert(sizeof(STORAGE_TYPE1) == false, "Multiplication of unit types results in new unit type - not supported."); + // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template + llstatic_assert(sizeof(STORAGE_TYPE1) == 0, "Multiplication of unit types results in new unit type - not supported."); } #define COMPARISON_OPERATORS(op) \ @@ -273,21 +333,21 @@ COMPARISON_OPERATORS(!=) namespace LLUnits { -#define LL_DECLARE_DERIVED_UNIT(base_unit_name, unit_name, conversion_factor)\ -struct unit_name \ -{ \ - typedef base_unit_name base_unit_t; \ -}; \ -template<> \ -struct ConversionFactor \ -{ \ - static F64 get() { return (conversion_factor); } \ -}; \ - \ -template<> \ -struct ConversionFactor \ -{ \ - static F64 get() { return 1.0 / (conversion_factor); } \ +#define LL_DECLARE_DERIVED_UNIT(base_unit_name, unit_name, conversion_factor) \ +struct unit_name \ +{ \ + typedef base_unit_name base_unit_t; \ +}; \ +template \ +struct ConversionFactor \ +{ \ + static typename HighestPrecisionType::type_t get() { return typename HighestPrecisionType::type_t(conversion_factor); } \ +}; \ + \ +template \ +struct ConversionFactor \ +{ \ + static typename HighestPrecisionType::type_t get() { return typename HighestPrecisionType::type_t(1.0 / (conversion_factor)); } \ } struct Bytes { typedef Bytes base_unit_t; }; @@ -302,16 +362,19 @@ LL_DECLARE_DERIVED_UNIT(Bytes, Gigabits, (1024 * 1024 * 1024 / 8)); struct Seconds { typedef Seconds base_unit_t; }; LL_DECLARE_DERIVED_UNIT(Seconds, Minutes, 60); LL_DECLARE_DERIVED_UNIT(Seconds, Hours, 60 * 60); -LL_DECLARE_DERIVED_UNIT(Seconds, Days, 60 * 60 * 24); -LL_DECLARE_DERIVED_UNIT(Seconds, Weeks, 60 * 60 * 24 * 7); LL_DECLARE_DERIVED_UNIT(Seconds, Milliseconds, (1.0 / 1000.0)); LL_DECLARE_DERIVED_UNIT(Seconds, Microseconds, (1.0 / (1000000.0))); LL_DECLARE_DERIVED_UNIT(Seconds, Nanoseconds, (1.0 / (1000000000.0))); struct Meters { typedef Meters base_unit_t; }; LL_DECLARE_DERIVED_UNIT(Meters, Kilometers, 1000); -LL_DECLARE_DERIVED_UNIT(Meters, Centimeters, (1.0 / 100)); -LL_DECLARE_DERIVED_UNIT(Meters, Millimeters, (1.0 / 1000)); +LL_DECLARE_DERIVED_UNIT(Meters, Centimeters, (1.0 / 100.0)); +LL_DECLARE_DERIVED_UNIT(Meters, Millimeters, (1.0 / 1000.0)); + +struct Hertz { typedef Hertz base_unit_t; }; +LL_DECLARE_DERIVED_UNIT(Hertz, Kilohertz, 1000); +LL_DECLARE_DERIVED_UNIT(Hertz, Megahertz, 1000 * 1000); +LL_DECLARE_DERIVED_UNIT(Hertz, Gigahertz, 1000 * 1000 * 1000); } #endif // LL_LLUNIT_H diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 065b20ba2b..0934028a8c 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -61,17 +61,17 @@ static const S32 LINE_GRAPH_HEIGHT = 240; static S32 FTV_NUM_TIMERS; const S32 FTV_MAX_DEPTH = 8; -std::vector ft_display_idx; // line of table entry for display purposes (for collapse) +std::vector ft_display_idx; // line of table entry for display purposes (for collapse) -typedef LLTreeDFSIter timer_tree_iterator_t; +typedef LLTreeDFSIter timer_tree_iterator_t; BOOL LLFastTimerView::sAnalyzePerformance = FALSE; -static timer_tree_iterator_t begin_timer_tree(LLFastTimer::NamedTimer& id) +static timer_tree_iterator_t begin_timer_tree(LLFastTimer::DeclareTimer& id) { return timer_tree_iterator_t(&id, - boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::beginChildren), _1), - boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::endChildren), _1)); + boost::bind(boost::mem_fn(&LLFastTimer::DeclareTimer::beginChildren), _1), + boost::bind(boost::mem_fn(&LLFastTimer::DeclareTimer::endChildren), _1)); } static timer_tree_iterator_t end_timer_tree() @@ -92,7 +92,7 @@ LLFastTimerView::LLFastTimerView(const LLSD& key) mScrollIndex = 0; mHoverID = NULL; mHoverBarIndex = -1; - FTV_NUM_TIMERS = LLFastTimer::NamedTimer::instanceCount(); + FTV_NUM_TIMERS = LLFastTimer::DeclareTimer::instanceCount(); mPrintStats = -1; } @@ -139,13 +139,13 @@ BOOL LLFastTimerView::handleRightMouseDown(S32 x, S32 y, MASK mask) { S32 bar_idx = MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight()); bar_idx = llclamp(bar_idx, 0, MAX_VISIBLE_HISTORY); - mPrintStats = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - bar_idx; + mPrintStats = LLFastTimer::DeclareTimer::HISTORY_NUM - mScrollIndex - bar_idx; return TRUE; } return LLFloater::handleRightMouseDown(x, y, mask); } -LLFastTimer::NamedTimer* LLFastTimerView::getLegendID(S32 y) +LLFastTimer::DeclareTimer* LLFastTimerView::getLegendID(S32 y) { S32 idx = (getRect().getHeight() - y) / (LLFontGL::getFontMonospace()->getLineHeight()+2) - 5; @@ -172,7 +172,7 @@ BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask) { if (x < mBarRect.mLeft) { - LLFastTimer::NamedTimer* idp = getLegendID(y); + LLFastTimer::DeclareTimer* idp = getLegendID(y); if (idp) { idp->setCollapsed(!idp->getCollapsed()); @@ -235,7 +235,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) if (hasMouseCapture()) { F32 lerp = llclamp(1.f - (F32) (x - mGraphRect.mLeft) / (F32) mGraphRect.getWidth(), 0.f, 1.f); - mScrollIndex = llround( lerp * (F32)(LLFastTimer::NamedTimer::HISTORY_NUM - MAX_VISIBLE_HISTORY)); + mScrollIndex = llround( lerp * (F32)(LLFastTimer::DeclareTimer::HISTORY_NUM - MAX_VISIBLE_HISTORY)); mScrollIndex = llclamp( mScrollIndex, 0, LLFastTimer::getLastFrameIndex()); return TRUE; } @@ -288,7 +288,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) } else if (x < mBarRect.mLeft) { - LLFastTimer::NamedTimer* timer_id = getLegendID(y); + LLFastTimer::DeclareTimer* timer_id = getLegendID(y); if (timer_id) { mHoverID = timer_id; @@ -299,6 +299,23 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) } +static std::string get_tooltip(LLFastTimer::DeclareTimer& timer, S32 history_index = -1) +{ + F64 ms_multiplier = 1000.0 / (F64)LLFastTimer::countsPerSecond(); + + std::string tooltip; + if (history_index < 0) + { + // by default, show average number of call + tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)(timer.getCountAverage() * ms_multiplier), (S32)timer.getCallAverage()); + } + else + { + tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)(timer.getHistoricalCount(history_index) * ms_multiplier), (S32)timer.getHistoricalCalls(history_index)); + } + return tooltip; +} + BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask) { if(LLFastTimer::sPauseHistory && mBarRect.pointInRect(x, y)) @@ -309,8 +326,10 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask) LLRect screen_rect; localRectToScreen(mToolTipRect, &screen_rect); + std::string tooltip = get_tooltip(*mHoverTimer, LLFastTimer::DeclareTimer::HISTORY_NUM - mScrollIndex - mHoverBarIndex); + LLToolTipMgr::instance().show(LLToolTip::Params() - .message(mHoverTimer->getToolTip(LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - mHoverBarIndex)) + .message(tooltip) .sticky_rect(screen_rect) .delay_time(0.f)); @@ -322,10 +341,10 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask) // tooltips for timer legend if (x < mBarRect.mLeft) { - LLFastTimer::NamedTimer* idp = getLegendID(y); + LLFastTimer::DeclareTimer* idp = getLegendID(y); if (idp) { - LLToolTipMgr::instance().show(idp->getToolTip()); + LLToolTipMgr::instance().show(get_tooltip(*idp)); return TRUE; } @@ -340,13 +359,13 @@ BOOL LLFastTimerView::handleScrollWheel(S32 x, S32 y, S32 clicks) LLFastTimer::sPauseHistory = TRUE; mScrollIndex = llclamp( mScrollIndex + clicks, 0, - llmin(LLFastTimer::getLastFrameIndex(), (S32)LLFastTimer::NamedTimer::HISTORY_NUM - MAX_VISIBLE_HISTORY)); + llmin(LLFastTimer::getLastFrameIndex(), (S32)LLFastTimer::DeclareTimer::HISTORY_NUM - MAX_VISIBLE_HISTORY)); return TRUE; } static LLFastTimer::DeclareTimer FTM_RENDER_TIMER("Timers", true); -static std::map sTimerColors; +static std::map sTimerColors; void LLFastTimerView::draw() { @@ -426,7 +445,7 @@ void LLFastTimerView::draw() it != timer_tree_iterator_t(); ++it) { - LLFastTimer::NamedTimer* idp = (*it); + LLFastTimer::DeclareTimer* idp = (*it); const F32 HUE_INCREMENT = 0.23f; hue = fmodf(hue + HUE_INCREMENT, 1.f); @@ -446,12 +465,12 @@ void LLFastTimerView::draw() LLLocalClipRect clip(LLRect(margin, y, LEGEND_WIDTH, margin)); S32 cur_line = 0; ft_display_idx.clear(); - std::map display_line; + std::map display_line; for (timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); it != timer_tree_iterator_t(); ++it) { - LLFastTimer::NamedTimer* idp = (*it); + LLFastTimer::DeclareTimer* idp = (*it); display_line[idp] = cur_line; ft_display_idx.push_back(idp); cur_line++; @@ -471,7 +490,7 @@ void LLFastTimerView::draw() S32 calls = 0; if (mHoverBarIndex > 0 && mHoverID) { - S32 hidx = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - mHoverBarIndex; + S32 hidx = LLFastTimer::DeclareTimer::HISTORY_NUM - mScrollIndex - mHoverBarIndex; U64 ticks = idp->getHistoricalCount(hidx); ms = (F32)((F64)ticks * iclock_freq); calls = (S32)idp->getHistoricalCalls(hidx); @@ -509,7 +528,7 @@ void LLFastTimerView::draw() x += dx; BOOL is_child_of_hover_item = (idp == mHoverID); - LLFastTimer::NamedTimer* next_parent = idp->getParent(); + LLFastTimer::DeclareTimer* next_parent = idp->getParent(); while(!is_child_of_hover_item && next_parent) { is_child_of_hover_item = (mHoverID == next_parent); @@ -687,7 +706,7 @@ void LLFastTimerView::draw() S32 tidx; if (j >= 0) { - tidx = LLFastTimer::NamedTimer::HISTORY_NUM - j - 1 - mScrollIndex; + tidx = LLFastTimer::DeclareTimer::HISTORY_NUM - j - 1 - mScrollIndex; } else { @@ -701,14 +720,14 @@ void LLFastTimerView::draw() std::vector deltax; xpos.push_back(xleft); - LLFastTimer::NamedTimer* prev_id = NULL; + LLFastTimer::DeclareTimer* prev_id = NULL; S32 i = 0; for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); it != end_timer_tree(); ++it, ++i) { - LLFastTimer::NamedTimer* idp = (*it); + LLFastTimer::DeclareTimer* idp = (*it); F32 frac = tidx == -1 ? (F32)idp->getCountAverage() / (F32)totalticks : (F32)idp->getHistoricalCount(tidx) / (F32)totalticks; @@ -735,7 +754,7 @@ void LLFastTimerView::draw() { U64 sublevelticks = 0; - for (LLFastTimer::NamedTimer::child_const_iter it = prev_id->beginChildren(); + for (LLFastTimer::DeclareTimer::child_const_iter it = prev_id->beginChildren(); it != prev_id->endChildren(); ++it) { @@ -777,7 +796,7 @@ void LLFastTimerView::draw() S32 scale_offset = 0; BOOL is_child_of_hover_item = (idp == mHoverID); - LLFastTimer::NamedTimer* next_parent = idp->getParent(); + LLFastTimer::DeclareTimer* next_parent = idp->getParent(); while(!is_child_of_hover_item && next_parent) { is_child_of_hover_item = (mHoverID == next_parent); @@ -842,10 +861,10 @@ void LLFastTimerView::draw() //highlight visible range { - S32 first_frame = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex; + S32 first_frame = LLFastTimer::DeclareTimer::HISTORY_NUM - mScrollIndex; S32 last_frame = first_frame - MAX_VISIBLE_HISTORY; - F32 frame_delta = ((F32) (mGraphRect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1); + F32 frame_delta = ((F32) (mGraphRect.getWidth()))/(LLFastTimer::DeclareTimer::HISTORY_NUM-1); F32 right = (F32) mGraphRect.mLeft + frame_delta*first_frame; F32 left = (F32) mGraphRect.mLeft + frame_delta*last_frame; @@ -872,7 +891,7 @@ void LLFastTimerView::draw() it != end_timer_tree(); ++it) { - LLFastTimer::NamedTimer* idp = (*it); + LLFastTimer::DeclareTimer* idp = (*it); //fatten highlighted timer if (mHoverID == idp) @@ -896,8 +915,8 @@ void LLFastTimerView::draw() gGL.color4f(col[0], col[1], col[2], alpha); gGL.begin(LLRender::TRIANGLE_STRIP); - for (U32 j = llmax(0, LLFastTimer::NamedTimer::HISTORY_NUM - LLFastTimer::getLastFrameIndex()); - j < LLFastTimer::NamedTimer::HISTORY_NUM; + for (U32 j = llmax(0, LLFastTimer::DeclareTimer::HISTORY_NUM - LLFastTimer::getLastFrameIndex()); + j < LLFastTimer::DeclareTimer::HISTORY_NUM; j++) { U64 ticks = idp->getHistoricalCount(j); @@ -918,7 +937,7 @@ void LLFastTimerView::draw() //normalize to highlighted timer cur_max = llmax(cur_max, ticks); } - F32 x = mGraphRect.mLeft + ((F32) (mGraphRect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1)*j; + F32 x = mGraphRect.mLeft + ((F32) (mGraphRect.getWidth()))/(LLFastTimer::DeclareTimer::HISTORY_NUM-1)*j; F32 y = mGraphRect.mBottom + (F32) mGraphRect.getHeight()/max_ticks*ticks; gGL.vertex2f(x,y); gGL.vertex2f(x,mGraphRect.mBottom); @@ -973,7 +992,7 @@ void LLFastTimerView::draw() it != end_timer_tree(); ++it) { - LLFastTimer::NamedTimer* idp = (*it); + LLFastTimer::DeclareTimer* idp = (*it); if (!first) { @@ -995,7 +1014,7 @@ void LLFastTimerView::draw() it != end_timer_tree(); ++it) { - LLFastTimer::NamedTimer* idp = (*it); + LLFastTimer::DeclareTimer* idp = (*it); if (!first) { @@ -1033,11 +1052,8 @@ void LLFastTimerView::draw() F64 LLFastTimerView::getTime(const std::string& name) { - const LLFastTimer::NamedTimer* timerp = LLFastTimer::getTimerByName(name); - if (timerp) - { - return (F64)timerp->getCountAverage() / (F64)LLFastTimer::countsPerSecond(); - } + //TODO: replace calls to this with use of timer object directly + //llstatic_assert(false, "TODO: implement"); return 0.0; } @@ -1552,9 +1568,9 @@ void LLFastTimerView::onClickCloseBtn() setVisible(false); } -LLFastTimer::NamedTimer& LLFastTimerView::getFrameTimer() +LLFastTimer::DeclareTimer& LLFastTimerView::getFrameTimer() { - return FTM_FRAME.getNamedTimer(); + return FTM_FRAME; } diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h index 5766cfa0b0..01a3501e4b 100644 --- a/indra/newview/llfasttimerview.h +++ b/indra/newview/llfasttimerview.h @@ -46,7 +46,7 @@ private: static LLSD analyzePerformanceLogDefault(std::istream& is) ; static void exportCharts(const std::string& base, const std::string& target); void onPause(); - LLFastTimer::NamedTimer& getFrameTimer(); + LLFastTimer::DeclareTimer& getFrameTimer(); public: @@ -59,7 +59,7 @@ public: virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); virtual void draw(); - LLFastTimer::NamedTimer* getLegendID(S32 y); + LLFastTimer::DeclareTimer* getLegendID(S32 y); F64 getTime(const std::string& name); protected: @@ -85,8 +85,8 @@ private: U64 mMaxCountTotal; LLRect mBarRect; S32 mScrollIndex; - LLFastTimer::NamedTimer* mHoverID; - LLFastTimer::NamedTimer* mHoverTimer; + LLFastTimer::DeclareTimer* mHoverID; + LLFastTimer::DeclareTimer* mHoverTimer; LLRect mToolTipRect; S32 mHoverBarIndex; LLFrameTimer mHighlightTimer; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index bf353cd1e0..5ac5ae892a 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2715,7 +2715,7 @@ void LLPipeline::updateGeom(F32 max_dtime) S32 count = 0; - max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, max_dtime); + max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, LLUnit(max_dtime)); LLSpatialGroup* last_group = NULL; LLSpatialBridge* last_bridge = NULL; -- cgit v1.3 From 6db6cb39f41e921e75970d1570a74cf35d353a35 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 16 Nov 2012 23:02:53 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system got new fast timer code to compile and run --- indra/llcommon/llfasttimer.cpp | 13 +++++++++++- indra/llcommon/lltrace.cpp | 12 ++++++++--- indra/llcommon/lltrace.h | 6 ++++++ indra/llcommon/lltracethreadrecorder.cpp | 4 ++++ indra/llmessage/llurlrequest.cpp | 4 ++-- indra/newview/llagentcamera.cpp | 5 +++-- indra/newview/llappviewer.cpp | 8 ++++---- indra/newview/llinventorypanel.cpp | 3 ++- indra/newview/llstartup.cpp | 2 +- indra/newview/llviewerobjectlist.cpp | 6 +++--- indra/newview/llviewerwindow.cpp | 3 ++- indra/newview/pipeline.cpp | 35 ++++---------------------------- 12 files changed, 52 insertions(+), 49 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index 4ecca12832..e1549b4bff 100644 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -336,7 +336,10 @@ void BlockTimer::accumulateTimings() cur_data = &cur_timer->mLastTimerData; cur_data->mChildTime += cumulative_time_delta; - accumulator = cur_data->mTimerData->getPrimaryAccumulator(); + if (cur_data->mTimerData) + { + accumulator = cur_data->mTimerData->getPrimaryAccumulator(); + } cur_timer = cur_timer->mLastTimerData.mCurTimer; } @@ -572,6 +575,14 @@ void Time::writeLog(std::ostream& os) } +LLTrace::TimerAccumulator::TimerAccumulator() : mSelfTimeCounter(0), + mTotalTimeCounter(0), + mCalls(0), + mLastCaller(NULL), + mActiveCount(0), + mMoveUpTree(false) +{} + void LLTrace::TimerAccumulator::addSamples( const LLTrace::TimerAccumulator& other ) { mSelfTimeCounter += other.mSelfTimeCounter; diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp index 9bf9ae6c8e..e11e39a1a2 100644 --- a/indra/llcommon/lltrace.cpp +++ b/indra/llcommon/lltrace.cpp @@ -30,6 +30,8 @@ #include "lltracethreadrecorder.h" #include "llfasttimer.h" +static bool sInitialized; + namespace LLTrace { @@ -38,15 +40,18 @@ static MasterThreadRecorder* gMasterThreadRecorder = NULL; void init() { gMasterThreadRecorder = new MasterThreadRecorder(); - BlockTimer::sCurTimerData = new CurTimerData(); + sInitialized = true; +} + +bool isInitialized() +{ + return sInitialized; } void cleanup() { delete gMasterThreadRecorder; gMasterThreadRecorder = NULL; - delete BlockTimer::sCurTimerData.get(); - BlockTimer::sCurTimerData = NULL; } MasterThreadRecorder& getMasterThreadRecorder() @@ -62,3 +67,4 @@ LLThreadLocalPointer& get_thread_recorder() } } + diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 61fed6e7b8..61d14569cd 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -67,6 +67,7 @@ namespace LLTrace void init(); void cleanup(); + bool isInitialized(); LLThreadLocalPointer& get_thread_recorder(); @@ -162,6 +163,10 @@ namespace LLTrace // NOTE: this is not thread-safe. We assume that slots are reserved in the main thread before any child threads are spawned size_t reserveSlot() { + if (LLTrace::isInitialized()) + { + llerrs << "Attempting to declare trace object after program initialization. Trace objects should be statically initialized." << llendl; + } size_t next_slot = mNextStorageSlot++; if (next_slot >= mStorageSize) { @@ -383,6 +388,7 @@ namespace LLTrace class TimerAccumulator { public: + TimerAccumulator(); void addSamples(const TimerAccumulator& other); void reset(const TimerAccumulator* other); diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 0f111aab59..c2fefe2957 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -40,6 +40,8 @@ ThreadRecorder::ThreadRecorder() { get_thread_recorder() = this; mFullRecording.start(); + + BlockTimer::sCurTimerData = new CurTimerData(); } ThreadRecorder::ThreadRecorder( const ThreadRecorder& other ) @@ -52,6 +54,8 @@ ThreadRecorder::ThreadRecorder( const ThreadRecorder& other ) ThreadRecorder::~ThreadRecorder() { get_thread_recorder() = NULL; + delete BlockTimer::sCurTimerData.get(); + BlockTimer::sCurTimerData = NULL; } void ThreadRecorder::activate( Recording* recording ) diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index 982f4804f0..0e5fe1de08 100644 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -281,6 +281,8 @@ LLIOPipe::EStatus LLURLRequest::handleError( static LLFastTimer::DeclareTimer FTM_PROCESS_URL_REQUEST("URL Request"); static LLFastTimer::DeclareTimer FTM_PROCESS_URL_REQUEST_GET_RESULT("Get Result"); static LLFastTimer::DeclareTimer FTM_URL_PERFORM("Perform"); +static LLFastTimer::DeclareTimer FTM_PROCESS_URL_PUMP_RESPOND("Pump Respond"); +static LLFastTimer::DeclareTimer FTM_URL_ADJUST_TIMEOUT("Adjust Timeout"); // virtual LLIOPipe::EStatus LLURLRequest::process_impl( @@ -300,7 +302,6 @@ LLIOPipe::EStatus LLURLRequest::process_impl( const S32 MIN_ACCUMULATION = 100000; if(pump && (mDetail->mByteAccumulator > MIN_ACCUMULATION)) { - static LLFastTimer::DeclareTimer FTM_URL_ADJUST_TIMEOUT("Adjust Timeout"); LLFastTimer t(FTM_URL_ADJUST_TIMEOUT); // This is a pretty sloppy calculation, but this // tries to make the gross assumption that if data @@ -398,7 +399,6 @@ LLIOPipe::EStatus LLURLRequest::process_impl( link.mChannels = LLBufferArray::makeChannelConsumer( channels); chain.push_back(link); - static LLFastTimer::DeclareTimer FTM_PROCESS_URL_PUMP_RESPOND("Pump Respond"); { LLFastTimer t(FTM_PROCESS_URL_PUMP_RESPOND); pump->respond(chain, buffer, context); diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 8d80e3aa0a..4e6079e3f2 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -1137,13 +1137,14 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y) } } +static LLFastTimer::DeclareTimer FTM_UPDATE_CAMERA("Camera"); + //----------------------------------------------------------------------------- // updateCamera() //----------------------------------------------------------------------------- void LLAgentCamera::updateCamera() { - static LLFastTimer::DeclareTimer ftm("Camera"); - LLFastTimer t(ftm); + LLFastTimer t(FTM_UPDATE_CAMERA); // - changed camera_skyward to the new global "mCameraUpVector" mCameraUpVector = LLVector3::z_axis; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 9d4ed833b8..547eb2fefe 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4126,6 +4126,8 @@ static LLFastTimer::DeclareTimer FTM_WORLD_UPDATE("Update World"); static LLFastTimer::DeclareTimer FTM_NETWORK("Network"); static LLFastTimer::DeclareTimer FTM_AGENT_NETWORK("Agent Network"); static LLFastTimer::DeclareTimer FTM_VLMANAGER("VL Manager"); +static LLFastTimer::DeclareTimer FTM_AGENT_POSITION("Agent Position"); +static LLFastTimer::DeclareTimer FTM_HUD_EFFECTS("HUD Effects"); /////////////////////////////////////////////////////// // idle() @@ -4362,8 +4364,7 @@ void LLAppViewer::idle() { // Handle pending gesture processing - static LLFastTimer::DeclareTimer ftm("Agent Position"); - LLFastTimer t(ftm); + LLFastTimer t(FTM_AGENT_POSITION); LLGestureMgr::instance().update(); gAgent.updateAgentPosition(gFrameDTClamped, yaw, current_mouse.mX, current_mouse.mY); @@ -4410,8 +4411,7 @@ void LLAppViewer::idle() // { - static LLFastTimer::DeclareTimer ftm("HUD Effects"); - LLFastTimer t(ftm); + LLFastTimer t(FTM_HUD_EFFECTS); LLSelectMgr::getInstance()->updateEffects(); LLHUDManager::getInstance()->cleanupEffects(); LLHUDManager::getInstance()->sendEffects(); diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index f7567baa2b..4c10717ce8 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -396,9 +396,10 @@ LLInventoryFilter::EFolderShow LLInventoryPanel::getShowFolderState() return getFilter()->getShowFolderState(); } +static LLFastTimer::DeclareTimer FTM_REFRESH("Inventory Refresh"); + void LLInventoryPanel::modelChanged(U32 mask) { - static LLFastTimer::DeclareTimer FTM_REFRESH("Inventory Refresh"); LLFastTimer t2(FTM_REFRESH); bool handled = false; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index bf47bd44c3..5f6772bf0b 100755 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -2184,7 +2184,7 @@ bool idle_startup() LLAppViewer::instance()->handleLoginComplete(); // reset timers now that we are running "logged in" logic - LLFastTimer::reset(); + LLTrace::BlockTimer::reset(); LLAgentPicksInfo::getInstance()->requestNumberOfPicks(); diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 9c6045943f..1bd028688a 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -850,6 +850,8 @@ private: LLSD mObjectIDs; }; +static LLFastTimer::DeclareTimer FTM_IDLE_COPY("Idle Copy"); + void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) { // Update globals @@ -900,10 +902,8 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) U32 idle_count = 0; - static LLFastTimer::DeclareTimer idle_copy("Idle Copy"); - { - LLFastTimer t(idle_copy); + LLFastTimer t(FTM_IDLE_COPY); for (std::vector >::iterator active_iter = mActiveObjects.begin(); active_iter != mActiveObjects.end(); active_iter++) diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 8e72ca1d74..dea55fd0b0 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2760,11 +2760,12 @@ void append_xui_tooltip(LLView* viewp, LLToolTip::Params& params) } } +static LLFastTimer::DeclareTimer ftm("Update UI"); + // Update UI based on stored mouse position from mouse-move // event processing. void LLViewerWindow::updateUI() { - static LLFastTimer::DeclareTimer ftm("Update UI"); LLFastTimer t(ftm); static std::string last_handle_msg; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 5ac5ae892a..acf3a4e74c 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1886,6 +1886,8 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list) static LLFastTimer::DeclareTimer FTM_OCTREE_BALANCE("Balance Octree"); static LLFastTimer::DeclareTimer FTM_UPDATE_MOVE("Update Move"); +static LLFastTimer::DeclareTimer FTM_RETEXTURE("Retexture"); +static LLFastTimer::DeclareTimer FTM_MOVED_LIST("Moved List"); void LLPipeline::updateMove() { @@ -1899,8 +1901,7 @@ void LLPipeline::updateMove() assertInitialized(); { - static LLFastTimer::DeclareTimer ftm("Retexture"); - LLFastTimer t(ftm); + LLFastTimer t(FTM_RETEXTURE); for (LLDrawable::drawable_set_t::iterator iter = mRetexturedList.begin(); iter != mRetexturedList.end(); ++iter) @@ -1915,8 +1916,7 @@ void LLPipeline::updateMove() } { - static LLFastTimer::DeclareTimer ftm("Moved List"); - LLFastTimer t(ftm); + LLFastTimer t(FTM_MOVED_LIST); updateMovedList(mMovedList); } @@ -3688,33 +3688,6 @@ void LLPipeline::postSort(LLCamera& camera) } } - /*static LLFastTimer::DeclareTimer FTM_TRANSFORM_WAIT("Transform Fence"); - static LLFastTimer::DeclareTimer FTM_TRANSFORM_DO_WORK("Transform Work"); - if (use_transform_feedback) - { //using transform feedback, wait for transform feedback to complete - LLFastTimer t(FTM_TRANSFORM_WAIT); - - S32 done = 0; - //glGetQueryivARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_CURRENT_QUERY, &count); - - glGetQueryObjectivARB(mMeshDirtyQueryObject, GL_QUERY_RESULT_AVAILABLE, &done); - - while (!done) - { - { - LLFastTimer t(FTM_TRANSFORM_DO_WORK); - F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f); - //do some useful work while we wait - LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread - LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread - LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread - } - glGetQueryObjectivARB(mMeshDirtyQueryObject, GL_QUERY_RESULT_AVAILABLE, &done); - } - - mTransformFeedbackPrimitives = 0; - }*/ - //LLSpatialGroup::sNoDelete = FALSE; llpushcallstacks ; } -- cgit v1.3 From 21409a3aaaef71102195d65fc35cebdb5d941a26 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Fri, 30 Nov 2012 22:50:06 -0700 Subject: for SH-3350 and SH-3353: Report frame-to-frame visual deltas as an LLStat --- .../class1/interface/onetexturefilterF.glsl | 49 ++++++ .../class1/interface/onetexturefilterV.glsl | 38 +++++ .../class1/interface/twotexturecompareF.glsl | 16 +- indra/newview/llscenemonitor.cpp | 188 ++++++++++++++------- indra/newview/llscenemonitor.h | 17 +- indra/newview/llspatialpartition.cpp | 22 ++- indra/newview/llspatialpartition.h | 2 + indra/newview/llviewershadermgr.cpp | 17 ++ indra/newview/llviewershadermgr.h | 4 +- indra/newview/pipeline.cpp | 5 +- 10 files changed, 271 insertions(+), 87 deletions(-) create mode 100644 indra/newview/app_settings/shaders/class1/interface/onetexturefilterF.glsl create mode 100644 indra/newview/app_settings/shaders/class1/interface/onetexturefilterV.glsl (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/app_settings/shaders/class1/interface/onetexturefilterF.glsl b/indra/newview/app_settings/shaders/class1/interface/onetexturefilterF.glsl new file mode 100644 index 0000000000..f1400c9b44 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/onetexturefilterF.glsl @@ -0,0 +1,49 @@ +/** + * @file onetexturefilterF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, 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$ + */ + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +uniform sampler2D tex0; +uniform float tolerance; + +VARYING vec2 vary_texcoord0; + +void main() +{ + frag_color = texture2D(tex0, vary_texcoord0.xy); + + if(frag_color[0] + frag_color[1] + frag_color[2] < tolerance) + { + discard; + } + else + { + frag_color[3] = 0.95f; + } +} diff --git a/indra/newview/app_settings/shaders/class1/interface/onetexturefilterV.glsl b/indra/newview/app_settings/shaders/class1/interface/onetexturefilterV.glsl new file mode 100644 index 0000000000..a33ef7e92c --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/onetexturefilterV.glsl @@ -0,0 +1,38 @@ +/** + * @file onetexturefilterV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2007, 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$ + */ + +uniform mat4 modelview_projection_matrix; + +ATTRIBUTE vec3 position; +ATTRIBUTE vec2 texcoord0; + +VARYING vec2 vary_texcoord0; + +void main() +{ + gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); + vary_texcoord0 = texcoord0; +} + diff --git a/indra/newview/app_settings/shaders/class1/interface/twotexturecompareF.glsl b/indra/newview/app_settings/shaders/class1/interface/twotexturecompareF.glsl index 336ca21b96..050114b37e 100644 --- a/indra/newview/app_settings/shaders/class1/interface/twotexturecompareF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/twotexturecompareF.glsl @@ -37,19 +37,5 @@ VARYING vec2 vary_texcoord1; void main() { - frag_color = texture2D(tex0, vary_texcoord0.xy) - texture2D(tex1, vary_texcoord0.xy); - - if(frag_color[0] < 0.f) - { - frag_color[0] = -frag_color[0]; - } - if(frag_color[1] < 0.f) - { - frag_color[1] = -frag_color[1]; - } - if(frag_color[2] < 0.f) - { - frag_color[2] = -frag_color[2]; - } - frag_color[3] = 0.95f; + frag_color = abs(texture2D(tex0, vary_texcoord0.xy) - texture2D(tex1, vary_texcoord0.xy)); } diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp index 0730281d85..adeada04ca 100644 --- a/indra/newview/llscenemonitor.cpp +++ b/indra/newview/llscenemonitor.cpp @@ -36,18 +36,24 @@ #include "llappviewer.h" #include "llwindow.h" #include "llpointer.h" +#include "llspatialpartition.h" LLSceneMonitorView* gSceneMonitorView = NULL; LLSceneMonitor::LLSceneMonitor() : mEnabled(FALSE), - mDiff(NULL), + mDiff(NULL), + mDiffResult(0.f), + mDiffTolerance(0.1f), mCurTarget(NULL), - mNeedsUpdateDiff(FALSE), - mDebugViewerVisible(FALSE) + mNeedsUpdateDiff(FALSE), + mHasNewDiff(FALSE), + mHasNewQueryResult(FALSE), + mDebugViewerVisible(FALSE), + mQueryObject(0) { mFrames[0] = NULL; - mFrames[1] = NULL; + mFrames[1] = NULL; } LLSceneMonitor::~LLSceneMonitor() @@ -69,6 +75,15 @@ void LLSceneMonitor::reset() mFrames[0] = NULL; mFrames[1] = NULL; mDiff = NULL; + mCurTarget = NULL; + + unfreezeScene(); + + if(mQueryObject > 0) + { + release_occlusion_query_object_name(mQueryObject); + mQueryObject = 0; + } } void LLSceneMonitor::setDebugViewerVisible(BOOL visible) @@ -108,28 +123,6 @@ bool LLSceneMonitor::preCapture() return false; } - if (LLStartUp::getStartupState() < STATE_STARTED) - { - return false; - } - - if(LLAppViewer::instance()->logoutRequestSent()) - { - return false; - } - - if(gWindowResized || gHeadlessClient || gTeleportDisplay || gRestoreGL || gDisconnected) - { - return false; - } - - if ( !gViewerWindow->getActive() - || !gViewerWindow->getWindow()->getVisible() - || gViewerWindow->getWindow()->getMinimized() ) - { - return false; - } - if(timer.getElapsedTimeF32() < 1.0f) { return false; @@ -174,12 +167,6 @@ bool LLSceneMonitor::preCapture() return true; } -void LLSceneMonitor::postCapture() -{ - mCurTarget = NULL; - mNeedsUpdateDiff = TRUE; -} - void LLSceneMonitor::freezeAvatar(LLCharacter* avatarp) { mAvatarPauseHandles.push_back(avatarp->requestPause()); @@ -207,19 +194,14 @@ void LLSceneMonitor::unfreezeScene() gSavedSettings.setBOOL("FreezeTime", FALSE); } -LLRenderTarget* LLSceneMonitor::getDiffTarget() const -{ - return mDiff; -} - void LLSceneMonitor::capture() { - static U32 count = 0; - if(count == gFrameCount) + static U32 last_capture_time = 0; + if(last_capture_time == gFrameCount) { return; } - count = gFrameCount; + last_capture_time = gFrameCount; preCapture(); @@ -239,7 +221,8 @@ void LLSceneMonitor::capture() glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, old_FBO); - postCapture(); + mCurTarget = NULL; + mNeedsUpdateDiff = TRUE; } void LLSceneMonitor::compare() @@ -248,6 +231,7 @@ void LLSceneMonitor::compare() { return; } + mNeedsUpdateDiff = FALSE; if(!mFrames[0] || !mFrames[1]) { @@ -258,11 +242,6 @@ void LLSceneMonitor::compare() return; //size does not match } - if (!LLGLSLShader::sNoFixedFunction) - { - return; - } - S32 width = gViewerWindow->getWindowWidthRaw(); S32 height = gViewerWindow->getWindowHeightRaw(); if(!mDiff) @@ -274,9 +253,10 @@ void LLSceneMonitor::compare() { mDiff->resize(width, height, GL_RGBA); } + mDiff->bindTarget(); mDiff->clear(); - + gTwoTextureCompareProgram.bind(); gGL.getTexUnit(0)->activate(); @@ -288,21 +268,108 @@ void LLSceneMonitor::compare() gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(1)->bind(mFrames[1]); gGL.getTexUnit(1)->activate(); - + gl_rect_2d_simple_tex(width, height); - mDiff->flush(); + mDiff->flush(); gTwoTextureCompareProgram.unbind(); - + gGL.getTexUnit(0)->disable(); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(1)->disable(); gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE); - mNeedsUpdateDiff = FALSE; + mHasNewDiff = TRUE; + + //send out the query request. + queryDiff(); +} + +void LLSceneMonitor::queryDiff() +{ + if(mDebugViewerVisible) + { + return; + } + + calcDiffAggregate(); +} + +//calculate Diff aggregate information in GPU, and enable gl occlusion query to capture it. +void LLSceneMonitor::calcDiffAggregate() +{ + if(!mHasNewDiff && !mDebugViewerVisible) + { + return; + } + + if(!mQueryObject) + { + mQueryObject = get_new_occlusion_query_object_name(); + } + + LLGLDepthTest depth(true, false, GL_ALWAYS); + if(!mDebugViewerVisible) + { + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + } + + LLGLSLShader* cur_shader = NULL; + + cur_shader = LLGLSLShader::sCurBoundShaderPtr; + gOneTextureFilterProgram.bind(); + gOneTextureFilterProgram.uniform1f("tolerance", mDiffTolerance); + + if(mHasNewDiff) + { + glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mQueryObject); + } + + gl_draw_scaled_target(0, 0, mDiff->getWidth() * 0.5f, mDiff->getHeight() * 0.5f, mDiff); + + if(mHasNewDiff) + { + glEndQueryARB(GL_SAMPLES_PASSED_ARB); + mHasNewDiff = FALSE; + mHasNewQueryResult = TRUE; + } + + gOneTextureFilterProgram.unbind(); + + if(cur_shader != NULL) + { + cur_shader->bind(); + } + + if(!mDebugViewerVisible) + { + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + } } +void LLSceneMonitor::fetchQueryResult() +{ + if(!mHasNewQueryResult) + { + return; + } + mHasNewQueryResult = FALSE; + + GLuint available = 0; + glGetQueryObjectuivARB(mQueryObject, GL_QUERY_RESULT_AVAILABLE_ARB, &available); + if(!available) + { + return; + } + + GLuint count = 0; + glGetQueryObjectuivARB(mQueryObject, GL_QUERY_RESULT_ARB, &count); + + mDiffResult = count * 0.5f / (mDiff->getWidth() * mDiff->getHeight() * 0.25f); + + //llinfos << count << " : " << mDiffResult << llendl; +} //------------------------------------------------------------------------------------------------------------- //definition of class LLSceneMonitorView //------------------------------------------------------------------------------------------------------------- @@ -330,27 +397,26 @@ void LLSceneMonitorView::setVisible(BOOL visible) void LLSceneMonitorView::draw() { - if (!LLGLSLShader::sNoFixedFunction) - { - return; - } - LLRenderTarget* target = LLSceneMonitor::getInstance()->getDiffTarget(); + const LLRenderTarget* target = LLSceneMonitor::getInstance()->getDiffTarget(); if(!target) { return; } - S32 height = (S32) (gViewerWindow->getWindowRectScaled().getHeight()*0.5f); - S32 width = (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.5f); + S32 height = target->getHeight() * 0.5f; + S32 width = target->getWidth() * 0.5f; + //S32 height = (S32) (gViewerWindow->getWindowRectScaled().getHeight()*0.5f); + //S32 width = (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.5f); LLRect new_rect; new_rect.setLeftTopAndSize(getRect().mLeft, getRect().mTop, width, height); setRect(new_rect); - //gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - //gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f)); + //draw background + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f)); - gl_draw_scaled_target(0, 0, getRect().getWidth(), getRect().getHeight(), target); + LLSceneMonitor::getInstance()->calcDiffAggregate(); LLView::draw(); } diff --git a/indra/newview/llscenemonitor.h b/indra/newview/llscenemonitor.h index 648429f97b..db5ac3eeef 100644 --- a/indra/newview/llscenemonitor.h +++ b/indra/newview/llscenemonitor.h @@ -48,8 +48,14 @@ public: void capture(); //capture the main frame buffer void compare(); //compare the stored two buffers. + void queryDiff(); + void fetchQueryResult(); + void calcDiffAggregate(); + void setDiffTolerance(F32 tol) {mDiffTolerance = tol;} - LLRenderTarget* getDiffTarget() const; + const LLRenderTarget* getDiffTarget() const {return mDiff;} + F32 getDiffTolerance() const {return mDiffTolerance;} + F32 getDiffResult() const { return mDiffResult;} bool isEnabled()const {return mEnabled;} private: @@ -57,17 +63,22 @@ private: void unfreezeScene(); void reset(); bool preCapture(); - void postCapture(); - + private: BOOL mEnabled; BOOL mNeedsUpdateDiff; + BOOL mHasNewDiff; + BOOL mHasNewQueryResult; BOOL mDebugViewerVisible; LLRenderTarget* mFrames[2]; LLRenderTarget* mDiff; LLRenderTarget* mCurTarget; + GLuint mQueryObject; //used for glQuery + F32 mDiffResult; //aggregate results of mDiff. + F32 mDiffTolerance; //pixels are filtered out when R+G+B < mDiffTolerance + std::vector mAvatarPauseHandles; }; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index e9ece331d1..b7694074a5 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -126,6 +126,16 @@ protected: static LLOcclusionQueryPool sQueryPool; +GLuint get_new_occlusion_query_object_name() +{ + return sQueryPool.allocate(); +} + +void release_occlusion_query_object_name(GLuint name) +{ + sQueryPool.release(name); +} + //static counter for frame to switch LOD on void sg_assert(BOOL expr) @@ -283,7 +293,7 @@ LLSpatialGroup::~LLSpatialGroup() { if (mOcclusionQuery[i]) { - sQueryPool.release(mOcclusionQuery[i]); + release_occlusion_query_object_name(mOcclusionQuery[i]); } } } @@ -879,7 +889,7 @@ void LLSpatialGroup::setOcclusionState(U32 state, S32 mode) if ((state & DISCARD_QUERY) && mOcclusionQuery[i]) { - sQueryPool.release(mOcclusionQuery[i]); + release_occlusion_query_object_name(mOcclusionQuery[i]); mOcclusionQuery[i] = 0; } } @@ -890,7 +900,7 @@ void LLSpatialGroup::setOcclusionState(U32 state, S32 mode) mOcclusionState[LLViewerCamera::sCurCameraID] |= state; if ((state & DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) { - sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]); + release_occlusion_query_object_name(mOcclusionQuery[LLViewerCamera::sCurCameraID]); mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; } } @@ -1237,7 +1247,7 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion) { if (mOcclusionQuery[i]) { - sQueryPool.release(mOcclusionQuery[i]); + release_occlusion_query_object_name(mOcclusionQuery[i]); mOcclusionQuery[i] = 0; } } @@ -1318,7 +1328,7 @@ void LLSpatialGroup::checkOcclusion() } else if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) { //delete the query to avoid holding onto hundreds of pending queries - sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]); + release_occlusion_query_object_name(mOcclusionQuery[LLViewerCamera::sCurCameraID]); mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; } @@ -1390,7 +1400,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) if (!mOcclusionQuery[LLViewerCamera::sCurCameraID]) { LLFastTimer t(FTM_OCCLUSION_ALLOCATE); - mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate(); + mOcclusionQuery[LLViewerCamera::sCurCameraID] = get_new_occlusion_query_object_name(); } // Depth clamp all water to avoid it being culled as a result of being diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 079c0f58f0..57e986fb80 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -58,6 +58,8 @@ void pushVerts(LLFace* face, U32 mask); // get index buffer for binary encoded axis vertex buffer given a box at center being viewed by given camera U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center); U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center); +GLuint get_new_occlusion_query_object_name(); +void release_occlusion_query_object_name(GLuint name); class LLDrawInfo : public LLRefCount { diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 5295573709..1aa36eafee 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -79,6 +79,7 @@ LLGLSLShader gSplatTextureRectProgram; LLGLSLShader gGlowCombineFXAAProgram; LLGLSLShader gTwoTextureAddProgram; LLGLSLShader gTwoTextureCompareProgram; +LLGLSLShader gOneTextureFilterProgram; LLGLSLShader gOneTextureNoColorProgram; LLGLSLShader gDebugProgram; LLGLSLShader gClipProgram; @@ -674,6 +675,7 @@ void LLViewerShaderMgr::unloadShaders() gGlowCombineFXAAProgram.unload(); gTwoTextureAddProgram.unload(); gTwoTextureCompareProgram.unload(); + gOneTextureFilterProgram.unload(); gOneTextureNoColorProgram.unload(); gSolidColorProgram.unload(); @@ -2724,6 +2726,21 @@ BOOL LLViewerShaderMgr::loadShadersInterface() } } + if (success) + { + gOneTextureFilterProgram.mName = "One Texture Filter Shader"; + gOneTextureFilterProgram.mShaderFiles.clear(); + gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterV.glsl", GL_VERTEX_SHADER_ARB)); + gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gOneTextureFilterProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; + success = gOneTextureFilterProgram.createShader(NULL, NULL); + if (success) + { + gOneTextureFilterProgram.bind(); + gOneTextureFilterProgram.uniform1i("tex0", 0); + } + } + if (success) { gOneTextureNoColorProgram.mName = "One Texture No Color Shader"; diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 8a706daa8f..3e7c615f23 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -235,7 +235,9 @@ extern LLGLSLShader gAlphaMaskProgram; extern LLGLSLShader gTwoTextureAddProgram; //output tex0[tc0] - tex1[tc1] extern LLGLSLShader gTwoTextureCompareProgram; - +//discard some fragments based on user-set color tolerance +extern LLGLSLShader gOneTextureFilterProgram; + extern LLGLSLShader gOneTextureNoColorProgram; //object shaders diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 850714f676..d8af7a5cfb 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -112,6 +112,7 @@ #include "llfloaterpathfindingconsole.h" #include "llfloaterpathfindingcharacters.h" #include "llpathfindingpathtool.h" +#include "llscenemonitor.h" #ifdef _DEBUG // Debug indices is disabled for now for debug performance - djs 4/24/02 @@ -3161,7 +3162,9 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } } - postSort(camera); + postSort(camera); + + LLSceneMonitor::getInstance()->fetchQueryResult(); } void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) -- cgit v1.3 From c99886d94389babc78e92bbfa5084fdd785915af Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 7 Dec 2012 15:20:12 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system improved unit tests for LLUnit renamed LLUnit to LLUnitImplicit with LLUnit being reserved for explicit units --- indra/llcommon/CMakeLists.txt | 2 +- indra/llcommon/llfasttimer.cpp | 6 +- indra/llcommon/llleap.cpp | 2 +- indra/llcommon/llprocessor.cpp | 2 +- indra/llcommon/llprocessor.h | 2 +- indra/llcommon/lltimer.cpp | 14 +-- indra/llcommon/lltimer.h | 16 +-- indra/llcommon/lltrace.h | 7 +- indra/llcommon/lltracerecording.h | 2 +- indra/llcommon/llunit.h | 193 ++++++++++++++++++++++--------- indra/llcommon/tests/llunit_test.cpp | 156 ------------------------- indra/llcommon/tests/llunits_test.cpp | 208 ++++++++++++++++++++++++++++++++++ indra/newview/llfasttimerview.cpp | 30 ++--- indra/newview/pipeline.cpp | 2 +- 14 files changed, 392 insertions(+), 250 deletions(-) delete mode 100644 indra/llcommon/tests/llunit_test.cpp create mode 100644 indra/llcommon/tests/llunits_test.cpp (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index e1f2eb44fd..5b76703af7 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -342,7 +342,7 @@ if (LL_TESTS) LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}") LL_ADD_INTEGRATION_TEST(lltreeiterators "" "${test_libs}") LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}") - LL_ADD_INTEGRATION_TEST(llunit "" "${test_libs}") + LL_ADD_INTEGRATION_TEST(llunits "" "${test_libs}") LL_ADD_INTEGRATION_TEST(reflection "" "${test_libs}") LL_ADD_INTEGRATION_TEST(stringize "" "${test_libs}") LL_ADD_INTEGRATION_TEST(lleventdispatcher "" "${test_libs}") diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index cf7655acf7..37e0fbac0a 100644 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -166,7 +166,7 @@ U64 TimeBlock::countsPerSecond() // counts per second for the *64-bit* timer firstcall = false; } #endif - return sCPUClockFrequency; + return sCPUClockFrequency.value(); } #endif @@ -408,7 +408,7 @@ void TimeBlock::nextFrame() } call_count++; - LLUnit total_time = 0; + LLUnit total_time(0); LLSD sd; { @@ -479,7 +479,7 @@ void TimeBlock::dumpCurTimes() } out_str << timerp->getName() << " " - << std::setprecision(3) << total_time_ms.as() << " ms, " + << std::setprecision(3) << total_time_ms.as().value() << " ms, " << num_calls << " calls"; llinfos << out_str.str() << llendl; diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp index 0a57ef1c48..84d2a12f65 100644 --- a/indra/llcommon/llleap.cpp +++ b/indra/llcommon/llleap.cpp @@ -394,7 +394,7 @@ public: LLProcess::WritePipe& childin(mChild->getWritePipe(LLProcess::STDIN)); LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop")); LLSD nop; - F64 until(LLTimer::getElapsedSeconds() + 2); + F64 until = (LLTimer::getElapsedSeconds() + 2).value(); while (childin.size() && LLTimer::getElapsedSeconds() < until) { mainloop.post(nop); diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index 6fe53396ca..5ddfa6fcef 100644 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -875,7 +875,7 @@ LLProcessorInfo::LLProcessorInfo() : mImpl(NULL) LLProcessorInfo::~LLProcessorInfo() {} -LLUnit LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); } +LLUnitImplicit LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); } bool LLProcessorInfo::hasSSE() const { return mImpl->hasSSE(); } bool LLProcessorInfo::hasSSE2() const { return mImpl->hasSSE2(); } bool LLProcessorInfo::hasAltivec() const { return mImpl->hasAltivec(); } diff --git a/indra/llcommon/llprocessor.h b/indra/llcommon/llprocessor.h index 2a21a5c115..fbd427f484 100644 --- a/indra/llcommon/llprocessor.h +++ b/indra/llcommon/llprocessor.h @@ -37,7 +37,7 @@ public: LLProcessorInfo(); ~LLProcessorInfo(); - LLUnit getCPUFrequency() const; + LLUnitImplicit getCPUFrequency() const; bool hasSSE() const; bool hasSSE2() const; bool hasAltivec() const; diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index 26063beff0..838155d54d 100644 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp @@ -285,14 +285,14 @@ LLTimer::~LLTimer() } // static -LLUnit LLTimer::getTotalTime() +LLUnitImplicit LLTimer::getTotalTime() { // simply call into the implementation function. return totalTime(); } // static -LLUnit LLTimer::getTotalSeconds() +LLUnitImplicit LLTimer::getTotalSeconds() { return U64_to_F64(getTotalTime()) * USEC_TO_SEC_F64; } @@ -341,23 +341,23 @@ U64 getElapsedTimeAndUpdate(U64& lastClockCount) } -LLUnit LLTimer::getElapsedTimeF64() const +LLUnitImplicit LLTimer::getElapsedTimeF64() const { U64 last = mLastClockCount; return (F64)getElapsedTimeAndUpdate(last) * gClockFrequencyInv; } -LLUnit LLTimer::getElapsedTimeF32() const +LLUnitImplicit LLTimer::getElapsedTimeF32() const { return (F32)getElapsedTimeF64(); } -LLUnit LLTimer::getElapsedTimeAndResetF64() +LLUnitImplicit LLTimer::getElapsedTimeAndResetF64() { return (F64)getElapsedTimeAndUpdate(mLastClockCount) * gClockFrequencyInv; } -LLUnit LLTimer::getElapsedTimeAndResetF32() +LLUnitImplicit LLTimer::getElapsedTimeAndResetF32() { return (F32)getElapsedTimeAndResetF64(); } @@ -370,7 +370,7 @@ void LLTimer::setTimerExpirySec(F32 expiration) + (U64)((F32)(expiration * gClockFrequency)); } -LLUnit LLTimer::getRemainingTimeF32() const +LLUnitImplicit LLTimer::getRemainingTimeF32() const { U64 cur_ticks = get_clock_count(); if (cur_ticks > mExpirationTicks) diff --git a/indra/llcommon/lltimer.h b/indra/llcommon/lltimer.h index 5cb2b18111..0ba87d1e15 100644 --- a/indra/llcommon/lltimer.h +++ b/indra/llcommon/lltimer.h @@ -67,16 +67,16 @@ public: // Return a high precision number of seconds since the start of // this application instance. - static LLUnit getElapsedSeconds() + static LLUnitImplicit getElapsedSeconds() { return sTimer->getElapsedTimeF64(); } // Return a high precision usec since epoch - static LLUnit getTotalTime(); + static LLUnitImplicit getTotalTime(); // Return a high precision seconds since epoch - static LLUnit getTotalSeconds(); + static LLUnitImplicit getTotalSeconds(); // MANIPULATORS @@ -87,16 +87,16 @@ public: void setTimerExpirySec(F32 expiration); BOOL checkExpirationAndReset(F32 expiration); BOOL hasExpired() const; - LLUnit getElapsedTimeAndResetF32(); // Returns elapsed time in seconds with reset - LLUnit getElapsedTimeAndResetF64(); + LLUnitImplicit getElapsedTimeAndResetF32(); // Returns elapsed time in seconds with reset + LLUnitImplicit getElapsedTimeAndResetF64(); - LLUnit getRemainingTimeF32() const; + LLUnitImplicit getRemainingTimeF32() const; static BOOL knownBadTimer(); // ACCESSORS - LLUnit getElapsedTimeF32() const; // Returns elapsed time in seconds - LLUnit getElapsedTimeF64() const; // Returns elapsed time in seconds + LLUnitImplicit getElapsedTimeF32() const; // Returns elapsed time in seconds + LLUnitImplicit getElapsedTimeF64() const; // Returns elapsed time in seconds bool getStarted() const { return mStarted; } diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 6e6bb51e47..25d95d9670 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -435,6 +435,9 @@ namespace LLTrace class TraceType : public TraceType { + public: + typedef F32 mean_t; + TraceType(const char* name, const char* description = "") : TraceType(name, description) {} @@ -465,7 +468,7 @@ namespace LLTrace void sample(UNIT_T value) { T converted_value(value); - getPrimaryAccumulator().sample((storage_t)converted_value); + getPrimaryAccumulator().sample(LLUnits::rawValue(converted_value)); } }; @@ -484,7 +487,7 @@ namespace LLTrace void add(UNIT_T value) { T converted_value(value); - getPrimaryAccumulator().add((storage_t)converted_value); + getPrimaryAccumulator().add(LLUnits::rawValue(converted_value)); } }; } diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index 6fd1a105d3..f92281cea8 100644 --- a/indra/llcommon/lltracerecording.h +++ b/indra/llcommon/lltracerecording.h @@ -205,7 +205,7 @@ namespace LLTrace U32 getSampleCount(const TraceType >& stat) const; U32 getSampleCount(const TraceType >& stat) const; - LLUnit getDuration() const { return mElapsedSeconds; } + LLUnit getDuration() const { return LLUnit(mElapsedSeconds); } private: friend class ThreadRecorder; diff --git a/indra/llcommon/llunit.h b/indra/llcommon/llunit.h index 1f3ed0237c..6b023f8287 100644 --- a/indra/llcommon/llunit.h +++ b/indra/llcommon/llunit.h @@ -65,6 +65,7 @@ struct ConversionFactor return 1; } }; + } template @@ -73,25 +74,25 @@ struct LLUnit typedef LLUnit self_t; typedef STORAGE_TYPE storage_t; + // value initialization LLUnit(storage_t value = storage_t()) : mValue(value) {} + // unit initialization and conversion template LLUnit(LLUnit other) : mValue(convert(other)) {} - - LLUnit(self_t& other) - : mValue(other.mValue) - {} - + + // value assignment self_t& operator = (storage_t value) { mValue = value; return *this; } + // unit assignment template self_t& operator = (LLUnit other) { @@ -99,11 +100,6 @@ struct LLUnit return *this; } - operator storage_t() const - { - return value(); - } - storage_t value() const { return mValue; @@ -157,7 +153,7 @@ struct LLUnit void operator /= (LLUnit divisor) { // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template - llstatic_assert(sizeof(OTHER_UNIT) == 0, "Division of unit types not supported."); + llstatic_assert(sizeof(OTHER_UNIT) == 0, "Illegal in-place division of unit types."); } template @@ -169,34 +165,30 @@ struct LLUnit } protected: - storage_t mValue; }; template -struct LLUnitStrict : public LLUnit +struct LLUnitImplicit : public LLUnit { - typedef LLUnitStrict self_t; + typedef LLUnitImplicit self_t; typedef typename LLUnit::storage_t storage_t; + typedef LLUnit base_t; - explicit LLUnitStrict(storage_t value = storage_t()) - : LLUnit(value) + LLUnitImplicit(storage_t value = storage_t()) + : base_t(value) {} template - LLUnitStrict(LLUnit other) - : LLUnit(convert(other)) + LLUnitImplicit(LLUnit other) + : base_t(convert(other)) {} - LLUnitStrict(self_t& other) - : LLUnit(other) - {} - - -private: + // unlike LLUnit, LLUnitImplicit is *implicitly* convertable to a POD scalar (F32, S32, etc) + // this allows for interoperability with legacy code operator storage_t() const { - return LLUnit::value(); + return value(); } }; @@ -204,7 +196,7 @@ private: // operator + // template -LLUnit operator + (LLUnit first, LLUnit second) +LLUnit operator + (LLUnit first, LLUnit second) { LLUnit result(first); result += second; @@ -227,6 +219,30 @@ LLUnit operator + (SCALAR_TYPE first, LLUnit +LLUnitImplicit operator + (LLUnitImplicit first, LLUnit second) +{ + LLUnitImplicit result(first); + result += second; + return result; +} + +template +LLUnitImplicit operator + (LLUnitImplicit first, SCALAR_TYPE second) +{ + LLUnitImplicit result(first); + result += second; + return result; +} + +template +LLUnitImplicit operator + (LLUnitImplicit first, LLUnitImplicit second) +{ + LLUnitImplicit result(first); + result += second; + return result; +} + // // operator - // @@ -238,7 +254,6 @@ LLUnit operator - (LLUnit return result; } - template LLUnit operator - (LLUnit first, SCALAR_TYPE second) { @@ -255,6 +270,30 @@ LLUnit operator - (SCALAR_TYPE first, LLUnit +LLUnitImplicit operator - (LLUnitImplicit first, LLUnitImplicit second) +{ + LLUnitImplicit result(first); + result -= second; + return result; +} + +template +LLUnitImplicit operator - (LLUnitImplicit first, SCALAR_TYPE second) +{ + LLUnitImplicit result(first); + result -= second; + return result; +} + +template +LLUnitImplicit operator - (SCALAR_TYPE first, LLUnitImplicit second) +{ + LLUnitImplicit result(first); + result -= second; + return result; +} + // // operator * // @@ -278,6 +317,26 @@ LLUnit operator * (LLUnit, return LLUnit(); } +template +LLUnitImplicit operator * (SCALAR_TYPE first, LLUnitImplicit second) +{ + return LLUnitImplicit(first * second.value()); +} + +template +LLUnitImplicit operator * (LLUnitImplicit first, SCALAR_TYPE second) +{ + return LLUnitImplicit(first.value() * second); +} + +template +LLUnitImplicit operator * (LLUnitImplicit, LLUnitImplicit) +{ + // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template + llstatic_assert(sizeof(STORAGE_TYPE1) == 0, "Multiplication of unit types results in new unit type - not supported."); + return LLUnitImplicit(); +} + // // operator / // @@ -300,23 +359,42 @@ STORAGE_TYPE1 operator / (LLUnit first, LLUnit \ -bool operator op (SCALAR_TYPE first, LLUnit second) \ -{ \ - return first op second.value(); \ -} \ - \ -template \ -bool operator op (LLUnit first, SCALAR_TYPE second) \ -{ \ - return first.value() op second; \ -} \ - \ -template \ -bool operator op (LLUnit first, LLUnit second) \ -{ \ - return first.value() op first.convert(second); \ +template +LLUnitImplicit operator / (LLUnitImplicit first, SCALAR_TYPE second) +{ + return LLUnitImplicit(first.value() / second); +} + +template +STORAGE_TYPE1 operator / (LLUnitImplicit first, LLUnitImplicit second) +{ + // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template + return STORAGE_TYPE1(first.value() / second.value()); +} + +#define COMPARISON_OPERATORS(op) \ +template \ +bool operator op (SCALAR_TYPE first, LLUnit second) \ +{ \ + return first op second.value(); \ +} \ + \ +template \ +bool operator op (LLUnit first, SCALAR_TYPE second) \ +{ \ + return first.value() op second; \ +} \ + \ +template \ +bool operator op (LLUnitImplicit first, LLUnitImplicit second) \ +{ \ + return first.value() op first.convert(second); \ +} \ + \ +template \ + bool operator op (LLUnit first, LLUnit second) \ +{ \ + return first.value() op first.convert(second); \ } COMPARISON_OPERATORS(<) @@ -328,6 +406,15 @@ COMPARISON_OPERATORS(!=) namespace LLUnits { +template +T rawValue(T val) { return val; } + +template +STORAGE_TYPE rawValue(LLUnit val) { return val.value(); } + +template +STORAGE_TYPE rawValue(LLUnitImplicit val) { return val.value(); } + template struct HighestPrecisionType > { @@ -361,22 +448,22 @@ struct Bytes { typedef Bytes base_unit_t; }; LL_DECLARE_DERIVED_UNIT(1024, Bytes, Kilobytes); LL_DECLARE_DERIVED_UNIT(1024 * 1024, Bytes, Megabytes); LL_DECLARE_DERIVED_UNIT(1024 * 1024 * 1024, Bytes, Gigabytes); -LL_DECLARE_DERIVED_UNIT((1.0 / 8.0), Bytes, Bits); -LL_DECLARE_DERIVED_UNIT((1024 / 8), Bytes, Kilobits); -LL_DECLARE_DERIVED_UNIT((1024 / 8), Bytes, Megabits); -LL_DECLARE_DERIVED_UNIT((1024 * 1024 * 1024 / 8), Bytes, Gigabits); +LL_DECLARE_DERIVED_UNIT(1.0 / 8.0, Bytes, Bits); +LL_DECLARE_DERIVED_UNIT(1024 / 8, Bytes, Kilobits); +LL_DECLARE_DERIVED_UNIT(1024 / 8, Bytes, Megabits); +LL_DECLARE_DERIVED_UNIT(1024 * 1024 * 1024 / 8, Bytes, Gigabits); struct Seconds { typedef Seconds base_unit_t; }; LL_DECLARE_DERIVED_UNIT(60, Seconds, Minutes); LL_DECLARE_DERIVED_UNIT(60 * 60, Seconds, Hours); -LL_DECLARE_DERIVED_UNIT((1.0 / 1000.0), Seconds, Milliseconds); -LL_DECLARE_DERIVED_UNIT((1.0 / (1000000.0)), Seconds, Microseconds); -LL_DECLARE_DERIVED_UNIT((1.0 / (1000000000.0)), Seconds, Nanoseconds); +LL_DECLARE_DERIVED_UNIT(1.0 / 1000.0, Seconds, Milliseconds); +LL_DECLARE_DERIVED_UNIT(1.0 / 1000000.0, Seconds, Microseconds); +LL_DECLARE_DERIVED_UNIT(1.0 / 1000000000.0, Seconds, Nanoseconds); struct Meters { typedef Meters base_unit_t; }; LL_DECLARE_DERIVED_UNIT(1000, Meters, Kilometers); -LL_DECLARE_DERIVED_UNIT((1.0 / 100.0), Meters, Centimeters); -LL_DECLARE_DERIVED_UNIT((1.0 / 1000.0), Meters, Millimeters); +LL_DECLARE_DERIVED_UNIT(1.0 / 100.0, Meters, Centimeters); +LL_DECLARE_DERIVED_UNIT(1.0 / 1000.0, Meters, Millimeters); struct Hertz { typedef Hertz base_unit_t; }; LL_DECLARE_DERIVED_UNIT(1000, Hertz, Kilohertz); diff --git a/indra/llcommon/tests/llunit_test.cpp b/indra/llcommon/tests/llunit_test.cpp deleted file mode 100644 index a7e9c00740..0000000000 --- a/indra/llcommon/tests/llunit_test.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/** - * @file llsingleton_test.cpp - * @date 2011-08-11 - * @brief Unit test for the LLSingleton class - * - * $LicenseInfo:firstyear=2011&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 "linden_common.h" - -#include "llunit.h" -#include "../test/lltut.h" - -namespace LLUnits -{ - // using powers of 2 to allow strict floating point equality - struct Quatloos { typedef Quatloos base_unit_t; }; - LL_DECLARE_DERIVED_UNIT(4, Quatloos, Latinum); - LL_DECLARE_DERIVED_UNIT((1.0 / 4.0), Quatloos, Solari); -} - -namespace tut -{ - using namespace LLUnits; - struct units - { - }; - - typedef test_group units_t; - typedef units_t::object units_object_t; - tut::units_t tut_singleton("LLUnit"); - - // storage type conversions - template<> template<> - void units_object_t::test<1>() - { - LLUnit float_quatloos; - ensure(float_quatloos.value() == 0.f); - - LLUnit int_quatloos; - ensure(int_quatloos.value() == 0); - - int_quatloos = 42; - ensure(int_quatloos.value() == 42); - float_quatloos = int_quatloos; - ensure(float_quatloos.value() == 42.f); - - int_quatloos = float_quatloos; - ensure(int_quatloos.value() == 42); - - float_quatloos = 42.1f; - ensure(float_quatloos == 42.1f); - int_quatloos = float_quatloos; - ensure(int_quatloos.value() == 42); - LLUnit unsigned_int_quatloos(float_quatloos); - ensure(unsigned_int_quatloos.value() == 42); - } - - // conversions to/from base unit - template<> template<> - void units_object_t::test<2>() - { - LLUnit quatloos(1.f); - ensure(quatloos.value() == 1.f); - LLUnit latinum_bars(quatloos); - ensure(latinum_bars.value() == 1.f / 4.f); - - latinum_bars = 256; - quatloos = latinum_bars; - ensure(quatloos.value() == 1024); - - LLUnit solari(quatloos); - ensure(solari.value() == 4096); - } - - // conversions across non-base units - template<> template<> - void units_object_t::test<3>() - { - LLUnit solari = 4.f; - LLUnit latinum_bars = solari; - ensure(latinum_bars.value() == 0.25f); - } - - // math operations - template<> template<> - void units_object_t::test<4>() - { - LLUnit quatloos = 1.f; - quatloos *= 4.f; - ensure(quatloos.value() == 4); - quatloos = quatloos * 2; - ensure(quatloos.value() == 8); - quatloos = 2.f * quatloos; - ensure(quatloos.value() == 16); - - quatloos += 4.f; - ensure(quatloos.value() == 20); - quatloos += 4; - ensure(quatloos.value() == 24); - quatloos = quatloos + 4; - ensure(quatloos.value() == 28); - quatloos = 4 + quatloos; - ensure(quatloos.value() == 32); - quatloos += quatloos * 3; - ensure(quatloos.value() == 128); - - quatloos -= quatloos / 4 * 3; - ensure(quatloos.value() == 32); - quatloos = quatloos - 8; - ensure(quatloos.value() == 24); - quatloos -= 4; - ensure(quatloos.value() == 20); - quatloos -= 4.f; - ensure(quatloos.value() == 16); - - quatloos *= 2.f; - ensure(quatloos.value() == 32); - quatloos = quatloos * 2.f; - ensure(quatloos.value() == 64); - quatloos = 0.5f * quatloos; - ensure(quatloos.value() == 32); - - quatloos /= 2.f; - ensure(quatloos.value() == 16); - quatloos = quatloos / 4; - ensure(quatloos.value() == 4); - - F32 ratio = quatloos / LLUnit(4.f); - ensure(ratio == 1); - - quatloos += LLUnit(4.f); - ensure(quatloos.value() == 5); - quatloos -= LLUnit(1.f); - ensure(quatloos.value() == 1); - } -} diff --git a/indra/llcommon/tests/llunits_test.cpp b/indra/llcommon/tests/llunits_test.cpp new file mode 100644 index 0000000000..2a941e8229 --- /dev/null +++ b/indra/llcommon/tests/llunits_test.cpp @@ -0,0 +1,208 @@ +/** + * @file llsingleton_test.cpp + * @date 2011-08-11 + * @brief Unit test for the LLSingleton class + * + * $LicenseInfo:firstyear=2011&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 "linden_common.h" + +#include "llunit.h" +#include "../test/lltut.h" + +namespace LLUnits +{ + // using powers of 2 to allow strict floating point equality + struct Quatloos { typedef Quatloos base_unit_t; }; + LL_DECLARE_DERIVED_UNIT(4, Quatloos, Latinum); + LL_DECLARE_DERIVED_UNIT((1.0 / 4.0), Quatloos, Solari); +} + +namespace tut +{ + using namespace LLUnits; + struct units + { + }; + + typedef test_group units_t; + typedef units_t::object units_object_t; + tut::units_t tut_singleton("LLUnit"); + + // storage type conversions + template<> template<> + void units_object_t::test<1>() + { + LLUnit float_quatloos; + ensure(float_quatloos.value() == 0.f); + + LLUnit int_quatloos; + ensure(int_quatloos.value() == 0); + + int_quatloos = 42; + ensure(int_quatloos.value() == 42); + float_quatloos = int_quatloos; + ensure(float_quatloos.value() == 42.f); + + int_quatloos = float_quatloos; + ensure(int_quatloos.value() == 42); + + float_quatloos = 42.1f; + ensure(float_quatloos.value() == 42.1f); + int_quatloos = float_quatloos; + ensure(int_quatloos.value() == 42); + LLUnit unsigned_int_quatloos(float_quatloos); + ensure(unsigned_int_quatloos.value() == 42); + } + + // conversions to/from base unit + template<> template<> + void units_object_t::test<2>() + { + LLUnit quatloos(1.f); + ensure(quatloos.value() == 1.f); + LLUnit latinum_bars(quatloos); + ensure(latinum_bars.value() == 1.f / 4.f); + + latinum_bars = 256; + quatloos = latinum_bars; + ensure(quatloos.value() == 1024); + + LLUnit solari(quatloos); + ensure(solari.value() == 4096); + } + + // conversions across non-base units + template<> template<> + void units_object_t::test<3>() + { + LLUnit solari = 4.f; + LLUnit latinum_bars = solari; + ensure(latinum_bars.value() == 0.25f); + } + + // math operations + template<> template<> + void units_object_t::test<4>() + { + LLUnit quatloos = 1.f; + quatloos *= 4.f; + ensure(quatloos.value() == 4); + quatloos = quatloos * 2; + ensure(quatloos.value() == 8); + quatloos = 2.f * quatloos; + ensure(quatloos.value() == 16); + + quatloos += 4.f; + ensure(quatloos.value() == 20); + quatloos += 4; + ensure(quatloos.value() == 24); + quatloos = quatloos + 4; + ensure(quatloos.value() == 28); + quatloos = 4 + quatloos; + ensure(quatloos.value() == 32); + quatloos += quatloos * 3; + ensure(quatloos.value() == 128); + + quatloos -= quatloos / 4 * 3; + ensure(quatloos.value() == 32); + quatloos = quatloos - 8; + ensure(quatloos.value() == 24); + quatloos -= 4; + ensure(quatloos.value() == 20); + quatloos -= 4.f; + ensure(quatloos.value() == 16); + + quatloos *= 2.f; + ensure(quatloos.value() == 32); + quatloos = quatloos * 2.f; + ensure(quatloos.value() == 64); + quatloos = 0.5f * quatloos; + ensure(quatloos.value() == 32); + + quatloos /= 2.f; + ensure(quatloos.value() == 16); + quatloos = quatloos / 4; + ensure(quatloos.value() == 4); + + F32 ratio = quatloos / LLUnit(4.f); + ensure(ratio == 1); + + quatloos += LLUnit(4.f); + ensure(quatloos.value() == 5); + quatloos -= LLUnit(1.f); + ensure(quatloos.value() == 1); + } + + // implicit units + template<> template<> + void units_object_t::test<5>() + { + // 0-initialized + LLUnit quatloos(0); + // initialize implicit unit from explicit + LLUnitImplicit quatloos_implicit = quatloos + 1; + ensure(quatloos_implicit.value() == 1); + + // assign implicit to explicit, or perform math operations + quatloos = quatloos_implicit; + ensure(quatloos.value() == 1); + quatloos += quatloos_implicit; + ensure(quatloos.value() == 2); + + // math operations on implicits + quatloos_implicit = 1; + ensure(quatloos_implicit == 1); + + quatloos_implicit += 2; + ensure(quatloos_implicit == 3); + + quatloos_implicit *= 2; + ensure(quatloos_implicit == 6); + + quatloos_implicit -= 1; + ensure(quatloos_implicit == 5); + + quatloos_implicit /= 5; + ensure(quatloos_implicit == 1); + + quatloos_implicit = quatloos_implicit + 3 + quatloos_implicit; + ensure(quatloos_implicit == 5); + + quatloos_implicit = 10 - quatloos_implicit - 1; + ensure(quatloos_implicit == 4); + + quatloos_implicit = 2 * quatloos_implicit * 2; + ensure(quatloos_implicit == 16); + + F32 one_half = quatloos_implicit / (quatloos_implicit * 2); + ensure(one_half == 0.5f); + + // implicit conversion to POD + F32 float_val = quatloos_implicit; + ensure(float_val == 16); + + S32 int_val = quatloos_implicit; + ensure(int_val == 16); + } +} diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 704b914b78..1c63022527 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -311,11 +311,11 @@ static std::string get_tooltip(LLTrace::TimeBlock& timer, S32 history_index, LLT if (history_index < 0) { // by default, show average number of call - tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)(frame_recording.getPeriodMean(timer) * ms_multiplier), (S32)frame_recording.getPeriodMean(timer.callCount())); + tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)(frame_recording.getPeriodMean(timer) * ms_multiplier).value(), (S32)frame_recording.getPeriodMean(timer.callCount())); } else { - tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)(frame_recording.getPrevRecordingPeriod(history_index).getSum(timer) * ms_multiplier), (S32)frame_recording.getPrevRecordingPeriod(history_index).getSum(timer.callCount())); + tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)(frame_recording.getPrevRecordingPeriod(history_index).getSum(timer) * ms_multiplier).value(), (S32)frame_recording.getPrevRecordingPeriod(history_index).getSum(timer.callCount())); } return tooltip; } @@ -601,22 +601,22 @@ void LLFastTimerView::draw() { LLUnit ms = total_time; - tdesc = llformat("%.1f ms |", (F32)ms*.25f); + tdesc = llformat("%.1f ms |", (F32)ms.value()*.25f); x = xleft + barw/4 - LLFontGL::getFontMonospace()->getWidth(tdesc); LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); - tdesc = llformat("%.1f ms |", (F32)ms*.50f); + tdesc = llformat("%.1f ms |", (F32)ms.value()*.50f); x = xleft + barw/2 - LLFontGL::getFontMonospace()->getWidth(tdesc); LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); - tdesc = llformat("%.1f ms |", (F32)ms*.75f); + tdesc = llformat("%.1f ms |", (F32)ms.value()*.75f); x = xleft + (barw*3)/4 - LLFontGL::getFontMonospace()->getWidth(tdesc); LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); - tdesc = llformat( "%d ms |", (U32)ms); + tdesc = llformat( "%d ms |", (U32)ms.value()); x = xleft + barw - LLFontGL::getFontMonospace()->getWidth(tdesc); LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); @@ -728,11 +728,11 @@ void LLFastTimerView::draw() ++it) { sublevelticks += (tidx == -1) - ? frame_recording.getPeriodMean(**it) - : frame_recording.getPrevRecordingPeriod(tidx).getSum(**it); + ? frame_recording.getPeriodMean(**it).value() + : frame_recording.getPrevRecordingPeriod(tidx).getSum(**it).value(); } - F32 subfrac = (F32)sublevelticks / (F32)total_time; + F32 subfrac = (F32)sublevelticks / (F32)total_time.value(); sublevel_dx[level] = (int)(subfrac * (F32)barw + .5f); if (mDisplayCenter == ALIGN_CENTER) @@ -819,7 +819,7 @@ void LLFastTimerView::draw() else if (mDisplayHz) tdesc = llformat("%d Hz", (int)(1.f / max_time.value())); else - tdesc = llformat("%4.2f ms", LLUnit(max_time).value()); + tdesc = llformat("%4.2f ms", max_time.value()); x = mGraphRect.mRight - LLFontGL::getFontMonospace()->getWidth(tdesc)-5; y = mGraphRect.mTop - LLFontGL::getFontMonospace()->getLineHeight(); @@ -900,7 +900,7 @@ void LLFastTimerView::draw() F32 x = mGraphRect.mRight - j * (F32)(mGraphRect.getWidth())/(LLTrace::TimeBlock::HISTORY_NUM-1); F32 y = mDisplayHz ? mGraphRect.mBottom + (1.f / time.value()) * ((F32) mGraphRect.getHeight() / (1.f / max_time.value())) - : mGraphRect.mBottom + time * ((F32)mGraphRect.getHeight() / max_time); + : mGraphRect.mBottom + time / max_time * (F32)mGraphRect.getHeight(); gGL.vertex2f(x,y); gGL.vertex2f(x,mGraphRect.mBottom); } @@ -920,22 +920,22 @@ void LLFastTimerView::draw() } //interpolate towards new maximum - max_time = lerp((F32)max_time, (F32) cur_max, LLCriticalDamp::getInterpolant(0.1f)); + max_time = lerp(max_time.value(), cur_max.value(), LLCriticalDamp::getInterpolant(0.1f)); if (max_time - cur_max <= 1 || cur_max - max_time <= 1) { max_time = llmax(LLUnit(1), LLUnit(cur_max)); } max_calls = lerp((F32)max_calls, (F32) cur_max_calls, LLCriticalDamp::getInterpolant(0.1f)); - if (llabs(max_calls - cur_max) <= 1) + if (llabs((S32)(max_calls - cur_max_calls)) <= 1) { max_calls = cur_max_calls; } // TODO: make sure alpha is correct in DisplayHz mode F32 alpha_target = (max_time > cur_max) - ? llmin((F32) max_time/ (F32) cur_max - 1.f,1.f) - : llmin((F32) cur_max/ (F32) max_time - 1.f,1.f); + ? llmin(max_time / cur_max - 1.f,1.f) + : llmin(cur_max/ max_time - 1.f,1.f); alpha_interp = lerp(alpha_interp, alpha_target, LLCriticalDamp::getInterpolant(0.1f)); if (mHoverID != NULL) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 813fc7db6a..3be19c3920 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2747,7 +2747,7 @@ void LLPipeline::updateGeom(F32 max_dtime) S32 count = 0; - max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, LLUnit(max_dtime)); + max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, LLUnitImplicit(max_dtime)); LLSpatialGroup* last_group = NULL; LLSpatialBridge* last_bridge = NULL; -- cgit v1.3 From f07b9c2c69f1f6882dcf249aacf33cdfacf878ab Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 6 Mar 2013 11:08:25 -0800 Subject: renamed LLTrace stat gathering classes/methods to make the structure of LLTrace clearer Count becomes CountStatHandle Count.sum becomes sum(Count, value), etc. --- indra/llcommon/lltrace.h | 832 +++++++++++++++++----------------- indra/llcommon/lltracerecording.h | 23 +- indra/llimage/llimage.cpp | 2 +- indra/llimage/llimage.h | 2 +- indra/llmessage/llassetstorage.cpp | 24 +- indra/llui/llstatbar.cpp | 16 +- indra/llui/lltextbase.cpp | 2 +- indra/llui/lltextbase.h | 2 +- indra/llui/llview.cpp | 2 +- indra/llui/llview.h | 2 +- indra/llui/llviewmodel.cpp | 2 +- indra/llui/llviewmodel.h | 2 +- indra/newview/llagent.cpp | 4 +- indra/newview/llappviewer.cpp | 2 +- indra/newview/lldrawable.cpp | 2 +- indra/newview/lldrawable.h | 2 +- indra/newview/llfloaterjoystick.cpp | 14 +- indra/newview/llfloatersnapshot.cpp | 2 +- indra/newview/llhudnametag.cpp | 2 +- indra/newview/llnearbychatbar.cpp | 2 +- indra/newview/llpanelface.cpp | 2 +- indra/newview/llpreviewscript.cpp | 4 +- indra/newview/llselectmgr.cpp | 4 +- indra/newview/llstartup.cpp | 2 +- indra/newview/lltexlayer.cpp | 2 +- indra/newview/lltexturefetch.cpp | 12 +- indra/newview/lltexturefetch.h | 4 +- indra/newview/lltooldraganddrop.cpp | 6 +- indra/newview/lltoolplacer.cpp | 2 +- indra/newview/llviewerassetstats.cpp | 12 +- indra/newview/llviewercamera.cpp | 4 +- indra/newview/llviewercamera.h | 8 +- indra/newview/llviewerdisplay.cpp | 4 +- indra/newview/llviewermenufile.cpp | 12 +- indra/newview/llviewermessage.cpp | 2 +- indra/newview/llviewerobject.cpp | 4 +- indra/newview/llviewerobject.h | 2 +- indra/newview/llviewerobjectlist.cpp | 14 +- indra/newview/llviewerobjectlist.h | 2 +- indra/newview/llviewerstats.cpp | 222 ++++----- indra/newview/llviewerstats.h | 35 +- indra/newview/llviewertexturelist.cpp | 20 +- indra/newview/llviewerwindow.cpp | 8 +- indra/newview/llviewerwindow.h | 4 +- indra/newview/llvoavatarself.cpp | 6 +- indra/newview/llworld.cpp | 14 +- indra/newview/pipeline.cpp | 4 +- 47 files changed, 677 insertions(+), 679 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 5d57327a14..44da1939c6 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -42,517 +42,519 @@ namespace LLTrace { - class Recording; - - typedef LLUnit Bytes; - typedef LLUnit Kilobytes; - typedef LLUnit Megabytes; - typedef LLUnit Gigabytes; - typedef LLUnit Bits; - typedef LLUnit Kilobits; - typedef LLUnit Megabits; - typedef LLUnit Gigabits; - - typedef LLUnit Seconds; - typedef LLUnit Milliseconds; - typedef LLUnit Minutes; - typedef LLUnit Hours; - typedef LLUnit Milliseconds; - typedef LLUnit Microseconds; - typedef LLUnit Nanoseconds; - - typedef LLUnit Meters; - typedef LLUnit Kilometers; - typedef LLUnit Centimeters; - typedef LLUnit Millimeters; - - void init(); - void cleanup(); - bool isInitialized(); - - const LLThreadLocalPointer& get_thread_recorder(); - void set_thread_recorder(class ThreadRecorder*); - - class MasterThreadRecorder& getMasterThreadRecorder(); - - // one per thread per type - template - class AccumulatorBuffer : public LLRefCount - { - typedef AccumulatorBuffer self_t; - static const U32 DEFAULT_ACCUMULATOR_BUFFER_SIZE = 64; - private: - struct StaticAllocationMarker { }; - - AccumulatorBuffer(StaticAllocationMarker m) - : mStorageSize(0), - mStorage(NULL), - mNextStorageSlot(0) - { - } +class Recording; + +typedef LLUnit Bytes; +typedef LLUnit Kilobytes; +typedef LLUnit Megabytes; +typedef LLUnit Gigabytes; +typedef LLUnit Bits; +typedef LLUnit Kilobits; +typedef LLUnit Megabits; +typedef LLUnit Gigabits; + +typedef LLUnit Seconds; +typedef LLUnit Milliseconds; +typedef LLUnit Minutes; +typedef LLUnit Hours; +typedef LLUnit Milliseconds; +typedef LLUnit Microseconds; +typedef LLUnit Nanoseconds; + +typedef LLUnit Meters; +typedef LLUnit Kilometers; +typedef LLUnit Centimeters; +typedef LLUnit Millimeters; + +void init(); +void cleanup(); +bool isInitialized(); + +const LLThreadLocalPointer& get_thread_recorder(); +void set_thread_recorder(class ThreadRecorder*); + +class MasterThreadRecorder& getMasterThreadRecorder(); + +// one per thread per type +template +class AccumulatorBuffer : public LLRefCount +{ + typedef AccumulatorBuffer self_t; + static const U32 DEFAULT_ACCUMULATOR_BUFFER_SIZE = 64; +private: + struct StaticAllocationMarker { }; - public: + AccumulatorBuffer(StaticAllocationMarker m) + : mStorageSize(0), + mStorage(NULL), + mNextStorageSlot(0) + { + } - AccumulatorBuffer(const AccumulatorBuffer& other = *getDefaultBuffer()) - : mStorageSize(0), - mStorage(NULL), - mNextStorageSlot(other.mNextStorageSlot) - { - resize(other.mStorageSize); - for (S32 i = 0; i < mNextStorageSlot; i++) - { - mStorage[i] = other.mStorage[i]; - } - } +public: - ~AccumulatorBuffer() + AccumulatorBuffer(const AccumulatorBuffer& other = *getDefaultBuffer()) + : mStorageSize(0), + mStorage(NULL), + mNextStorageSlot(other.mNextStorageSlot) + { + resize(other.mStorageSize); + for (S32 i = 0; i < mNextStorageSlot; i++) { - if (LLThreadLocalSingletonPointer::getInstance() == mStorage) - { - LLThreadLocalSingletonPointer::setInstance(getDefaultBuffer()->mStorage); - } - delete[] mStorage; + mStorage[i] = other.mStorage[i]; } + } - LL_FORCE_INLINE ACCUMULATOR& operator[](size_t index) - { - return mStorage[index]; + ~AccumulatorBuffer() + { + if (LLThreadLocalSingletonPointer::getInstance() == mStorage) + { + LLThreadLocalSingletonPointer::setInstance(getDefaultBuffer()->mStorage); } + delete[] mStorage; + } - LL_FORCE_INLINE const ACCUMULATOR& operator[](size_t index) const - { - return mStorage[index]; - } + LL_FORCE_INLINE ACCUMULATOR& operator[](size_t index) + { + return mStorage[index]; + } - void addSamples(const AccumulatorBuffer& other) - { - llassert(mNextStorageSlot == other.mNextStorageSlot); + LL_FORCE_INLINE const ACCUMULATOR& operator[](size_t index) const + { + return mStorage[index]; + } - for (size_t i = 0; i < mNextStorageSlot; i++) - { - mStorage[i].addSamples(other.mStorage[i]); - } - } + void addSamples(const AccumulatorBuffer& other) + { + llassert(mNextStorageSlot == other.mNextStorageSlot); - void copyFrom(const AccumulatorBuffer& other) + for (size_t i = 0; i < mNextStorageSlot; i++) { - for (size_t i = 0; i < mNextStorageSlot; i++) - { - mStorage[i] = other.mStorage[i]; - } + mStorage[i].addSamples(other.mStorage[i]); } + } - void reset(const AccumulatorBuffer* other = NULL) + void copyFrom(const AccumulatorBuffer& other) + { + for (size_t i = 0; i < mNextStorageSlot; i++) { - for (size_t i = 0; i < mNextStorageSlot; i++) - { - mStorage[i].reset(other ? &other->mStorage[i] : NULL); - } + mStorage[i] = other.mStorage[i]; } + } - void makePrimary() + void reset(const AccumulatorBuffer* other = NULL) + { + for (size_t i = 0; i < mNextStorageSlot; i++) { - LLThreadLocalSingletonPointer::setInstance(mStorage); + mStorage[i].reset(other ? &other->mStorage[i] : NULL); } + } - bool isPrimary() const - { - return LLThreadLocalSingletonPointer::getInstance() == mStorage; - } + void makePrimary() + { + LLThreadLocalSingletonPointer::setInstance(mStorage); + } - LL_FORCE_INLINE static ACCUMULATOR* getPrimaryStorage() - { - return LLThreadLocalSingletonPointer::getInstance(); - } + bool isPrimary() const + { + return LLThreadLocalSingletonPointer::getInstance() == mStorage; + } - // NOTE: this is not thread-safe. We assume that slots are reserved in the main thread before any child threads are spawned - size_t reserveSlot() + LL_FORCE_INLINE static ACCUMULATOR* getPrimaryStorage() + { + return LLThreadLocalSingletonPointer::getInstance(); + } + + // NOTE: this is not thread-safe. We assume that slots are reserved in the main thread before any child threads are spawned + size_t reserveSlot() + { + if (LLTrace::isInitialized()) { - if (LLTrace::isInitialized()) - { - llerrs << "Attempting to declare trace object after program initialization. Trace objects should be statically initialized." << llendl; - } - size_t next_slot = mNextStorageSlot++; - if (next_slot >= mStorageSize) - { - resize(mStorageSize + (mStorageSize >> 2)); - } - llassert(mStorage && next_slot < mStorageSize); - return next_slot; + llerrs << "Attempting to declare trace object after program initialization. Trace objects should be statically initialized." << llendl; } - - void resize(size_t new_size) + size_t next_slot = mNextStorageSlot++; + if (next_slot >= mStorageSize) { - if (new_size <= mStorageSize) return; + resize(mStorageSize + (mStorageSize >> 2)); + } + llassert(mStorage && next_slot < mStorageSize); + return next_slot; + } - ACCUMULATOR* old_storage = mStorage; - mStorage = new ACCUMULATOR[new_size]; - if (old_storage) - { - for (S32 i = 0; i < mStorageSize; i++) - { - mStorage[i] = old_storage[i]; - } - } - mStorageSize = new_size; - delete[] old_storage; + void resize(size_t new_size) + { + if (new_size <= mStorageSize) return; - self_t* default_buffer = getDefaultBuffer(); - if (this != default_buffer - && new_size > default_buffer->size()) + ACCUMULATOR* old_storage = mStorage; + mStorage = new ACCUMULATOR[new_size]; + if (old_storage) + { + for (S32 i = 0; i < mStorageSize; i++) { - //NB: this is not thread safe, but we assume that all resizing occurs during static initialization - default_buffer->resize(new_size); + mStorage[i] = old_storage[i]; } } + mStorageSize = new_size; + delete[] old_storage; - size_t size() const + self_t* default_buffer = getDefaultBuffer(); + if (this != default_buffer + && new_size > default_buffer->size()) { - return mNextStorageSlot; + //NB: this is not thread safe, but we assume that all resizing occurs during static initialization + default_buffer->resize(new_size); } + } + + size_t size() const + { + return mNextStorageSlot; + } - static self_t* getDefaultBuffer() + static self_t* getDefaultBuffer() + { + // this buffer is allowed to leak so that trace calls from global destructors have somewhere to put their data + // so as not to trigger an access violation + static self_t* sBuffer = new AccumulatorBuffer(StaticAllocationMarker()); + static bool sInitialized = false; + if (!sInitialized) { - // this buffer is allowed to leak so that trace calls from global destructors have somewhere to put their data - // so as not to trigger an access violation - static self_t* sBuffer = new AccumulatorBuffer(StaticAllocationMarker()); - static bool sInitialized = false; - if (!sInitialized) - { - sBuffer->resize(DEFAULT_ACCUMULATOR_BUFFER_SIZE); - sInitialized = true; - } - return sBuffer; + sBuffer->resize(DEFAULT_ACCUMULATOR_BUFFER_SIZE); + sInitialized = true; } + return sBuffer; + } - private: - ACCUMULATOR* mStorage; - size_t mStorageSize; - size_t mNextStorageSlot; - }; +private: + ACCUMULATOR* mStorage; + size_t mStorageSize; + size_t mNextStorageSlot; +}; - //TODO: replace with decltype when C++11 is enabled - template - struct MeanValueType - { - typedef F64 type; - }; +//TODO: replace with decltype when C++11 is enabled +template +struct MeanValueType +{ + typedef F64 type; +}; - template - class TraceType - : public LLInstanceTracker, std::string> +template +class TraceType +: public LLInstanceTracker, std::string> +{ +public: + TraceType(const char* name, const char* description = NULL) + : LLInstanceTracker, std::string>(name), + mName(name), + mDescription(description ? description : ""), + mAccumulatorIndex(AccumulatorBuffer::getDefaultBuffer()->reserveSlot()) + {} + + LL_FORCE_INLINE ACCUMULATOR* getPrimaryAccumulator() const { - public: - TraceType(const char* name, const char* description = NULL) - : LLInstanceTracker, std::string>(name), - mName(name), - mDescription(description ? description : ""), - mAccumulatorIndex(AccumulatorBuffer::getDefaultBuffer()->reserveSlot()) - {} + ACCUMULATOR* accumulator_storage = AccumulatorBuffer::getPrimaryStorage(); + return &accumulator_storage[mAccumulatorIndex]; + } - LL_FORCE_INLINE ACCUMULATOR* getPrimaryAccumulator() const - { - ACCUMULATOR* accumulator_storage = AccumulatorBuffer::getPrimaryStorage(); - return &accumulator_storage[mAccumulatorIndex]; - } + size_t getIndex() const { return mAccumulatorIndex; } - size_t getIndex() const { return mAccumulatorIndex; } + const std::string& getName() const { return mName; } - const std::string& getName() const { return mName; } +protected: + const std::string mName; + const std::string mDescription; + const size_t mAccumulatorIndex; +}; - protected: - const std::string mName; - const std::string mDescription; - const size_t mAccumulatorIndex; - }; +template +class MeasurementAccumulator +{ +public: + typedef T value_t; + typedef MeasurementAccumulator self_t; + + MeasurementAccumulator() + : mSum(0), + mMin((std::numeric_limits::max)()), + mMax((std::numeric_limits::min)()), + mMean(0), + mVarianceSum(0), + mNumSamples(0), + mLastValue(0) + {} - template - class MeasurementAccumulator + void sample(T value) { - public: - typedef T value_t; - typedef MeasurementAccumulator self_t; - - MeasurementAccumulator() - : mSum(0), - mMin((std::numeric_limits::max)()), - mMax((std::numeric_limits::min)()), - mMean(0), - mVarianceSum(0), - mNumSamples(0), - mLastValue(0) - {} + mNumSamples++; + mSum += value; + if (value < mMin) + { + mMin = value; + } + if (value > mMax) + { + mMax = value; + } + F64 old_mean = mMean; + mMean += ((F64)value - old_mean) / (F64)mNumSamples; + mVarianceSum += ((F64)value - old_mean) * ((F64)value - mMean); + mLastValue = value; + } - LL_FORCE_INLINE void sample(T value) + void addSamples(const self_t& other) + { + if (other.mNumSamples) { - T storage_value(value); - mNumSamples++; - mSum += storage_value; - if (storage_value < mMin) + mSum += other.mSum; + if (other.mMin < mMin) { - mMin = storage_value; + mMin = other.mMin; } - if (storage_value > mMax) + if (other.mMax > mMax) { - mMax = storage_value; + mMax = other.mMax; } - F64 old_mean = mMean; - mMean += ((F64)storage_value - old_mean) / (F64)mNumSamples; - mVarianceSum += ((F64)storage_value - old_mean) * ((F64)storage_value - mMean); - mLastValue = storage_value; - } - - void addSamples(const self_t& other) - { - if (other.mNumSamples) + F64 weight = (F64)mNumSamples / (F64)(mNumSamples + other.mNumSamples); + mNumSamples += other.mNumSamples; + mMean = mMean * weight + other.mMean * (1.f - weight); + + // combine variance (and hence standard deviation) of 2 different sized sample groups using + // the following formula: http://www.mrc-bsu.cam.ac.uk/cochrane/handbook/chapter_7/7_7_3_8_combining_groups.htm + F64 n_1 = (F64)mNumSamples, + n_2 = (F64)other.mNumSamples; + F64 m_1 = mMean, + m_2 = other.mMean; + F64 v_1 = mVarianceSum / mNumSamples, + v_2 = other.mVarianceSum / other.mNumSamples; + if (n_1 == 0) + { + mVarianceSum = other.mVarianceSum; + } + else if (n_2 == 0) { - mSum += other.mSum; - if (other.mMin < mMin) - { - mMin = other.mMin; - } - if (other.mMax > mMax) - { - mMax = other.mMax; - } - F64 weight = (F64)mNumSamples / (F64)(mNumSamples + other.mNumSamples); - mNumSamples += other.mNumSamples; - mMean = mMean * weight + other.mMean * (1.f - weight); - - // combine variance (and hence standard deviation) of 2 different sized sample groups using - // the following formula: http://www.mrc-bsu.cam.ac.uk/cochrane/handbook/chapter_7/7_7_3_8_combining_groups.htm - F64 n_1 = (F64)mNumSamples, - n_2 = (F64)other.mNumSamples; - F64 m_1 = mMean, - m_2 = other.mMean; - F64 sd_1 = getStandardDeviation(), - sd_2 = other.getStandardDeviation(); - if (n_1 == 0) - { - mVarianceSum = other.mVarianceSum; - } - else if (n_2 == 0) - { - // don't touch variance - // mVarianceSum = mVarianceSum; - } - else - { - mVarianceSum = (F64)mNumSamples - * ((((n_1 - 1.f) * sd_1 * sd_1) - + ((n_2 - 1.f) * sd_2 * sd_2) - + (((n_1 * n_2) / (n_1 + n_2)) - * ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2)))) - / (n_1 + n_2 - 1.f)); - } - mLastValue = other.mLastValue; + // don't touch variance + // mVarianceSum = mVarianceSum; } + else + { + mVarianceSum = (F64)mNumSamples + * ((((n_1 - 1.f) * v_1) + + ((n_2 - 1.f) * v_2) + + (((n_1 * n_2) / (n_1 + n_2)) + * ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2)))) + / (n_1 + n_2 - 1.f)); + } + mLastValue = other.mLastValue; } + } - void reset(const self_t* other) - { - mNumSamples = 0; - mSum = 0; - mMin = 0; - mMax = 0; - mMean = 0; - mVarianceSum = 0; - mLastValue = other ? other->mLastValue : 0; - } + void reset(const self_t* other) + { + mNumSamples = 0; + mSum = 0; + mMin = 0; + mMax = 0; + mMean = 0; + mVarianceSum = 0; + mLastValue = other ? other->mLastValue : 0; + } - T getSum() const { return (T)mSum; } - T getMin() const { return (T)mMin; } - T getMax() const { return (T)mMax; } - T getLastValue() const { return (T)mLastValue; } - F64 getMean() const { return mMean; } - F64 getStandardDeviation() const { return sqrtf(mVarianceSum / mNumSamples); } - U32 getSampleCount() const { return mNumSamples; } + T getSum() const { return (T)mSum; } + T getMin() const { return (T)mMin; } + T getMax() const { return (T)mMax; } + T getLastValue() const { return (T)mLastValue; } + F64 getMean() const { return mMean; } + F64 getStandardDeviation() const { return sqrtf(mVarianceSum / mNumSamples); } + U32 getSampleCount() const { return mNumSamples; } - private: - T mSum, - mMin, - mMax, - mLastValue; +private: + T mSum, + mMin, + mMax, + mLastValue; - F64 mMean, - mVarianceSum; + F64 mMean, + mVarianceSum; - U32 mNumSamples; - }; + U32 mNumSamples; +}; + +template +class CountAccumulator +{ +public: + typedef CountAccumulator self_t; + typedef T value_t; + + CountAccumulator() + : mSum(0), + mNumSamples(0) + {} - template - class CountAccumulator + void add(T value) { - public: - typedef CountAccumulator self_t; - typedef T value_t; + mNumSamples++; + mSum += value; + } - CountAccumulator() - : mSum(0), - mNumSamples(0) - {} + void addSamples(const CountAccumulator& other) + { + mSum += other.mSum; + mNumSamples += other.mNumSamples; + } - LL_FORCE_INLINE void add(T value) - { - mNumSamples++; - mSum += value; - } + void reset(const self_t* other) + { + mNumSamples = 0; + mSum = 0; + } - void addSamples(const CountAccumulator& other) - { - mSum += other.mSum; - mNumSamples += other.mNumSamples; - } + T getSum() const { return (T)mSum; } - void reset(const self_t* other) - { - mNumSamples = 0; - mSum = 0; - } + U32 getSampleCount() const { return mNumSamples; } - T getSum() const { return (T)mSum; } +private: + T mSum; - U32 getSampleCount() const { return mNumSamples; } + U32 mNumSamples; +}; - private: - T mSum; +class TimeBlockAccumulator +{ +public: + typedef LLUnit value_t; + typedef TimeBlockAccumulator self_t; - U32 mNumSamples; + // fake class that allows us to view call count aspect of timeblock accumulator + struct CallCountAspect + { + typedef U32 value_t; }; - class TimeBlockAccumulator + struct SelfTimeAspect { - public: typedef LLUnit value_t; - typedef TimeBlockAccumulator self_t; + }; - // fake class that allows us to view call count aspect of timeblock accumulator - struct CallCountAspect - { - typedef U32 value_t; - }; + TimeBlockAccumulator(); + void addSamples(const self_t& other); + void reset(const self_t* other); + + // + // members + // + U64 mStartTotalTimeCounter, + mTotalTimeCounter, + mSelfTimeCounter; + U32 mCalls; + class TimeBlock* mParent; // last acknowledged parent of this time block + class TimeBlock* mLastCaller; // used to bootstrap tree construction + U16 mActiveCount; // number of timers with this ID active on stack + bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame - struct SelfTimeAspect - { - typedef LLUnit value_t; - }; - - TimeBlockAccumulator(); - void addSamples(const self_t& other); - void reset(const self_t* other); - - // - // members - // - U64 mStartTotalTimeCounter, - mTotalTimeCounter, - mSelfTimeCounter; - U32 mCalls; - class TimeBlock* mParent; // last acknowledged parent of this time block - class TimeBlock* mLastCaller; // used to bootstrap tree construction - U16 mActiveCount; // number of timers with this ID active on stack - bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame +}; - }; +template<> +struct MeanValueType > +{ + typedef LLUnit type; +}; - template<> - struct MeanValueType > - { - typedef LLUnit type; - }; +template<> +class TraceType +: public TraceType +{ +public: - template<> - class TraceType + TraceType(const char* name, const char* description = "") + : TraceType(name, description) + {} +}; + +template<> +struct MeanValueType > +{ + typedef F64 type; +}; + + +template<> +class TraceType : public TraceType - { - public: +{ +public: - TraceType(const char* name, const char* description = "") + TraceType(const char* name, const char* description = "") : TraceType(name, description) - {} - }; - - template<> - struct MeanValueType > - { - typedef F64 type; - }; + {} +}; +template<> +struct MeanValueType > +{ + typedef LLUnit type; +}; - template<> - class TraceType - : public TraceType - { - public: - TraceType(const char* name, const char* description = "") - : TraceType(name, description) - {} - }; +class TimeBlock; +class TimeBlockTreeNode +{ +public: + TimeBlockTreeNode(); - template<> - struct MeanValueType > - { - typedef LLUnit type; - }; + void setParent(TimeBlock* parent); + TimeBlock* getParent() { return mParent; } + TimeBlock* mBlock; + TimeBlock* mParent; + std::vector mChildren; + bool mNeedsSorting; +}; - class TimeBlock; - class TimeBlockTreeNode - { - public: - TimeBlockTreeNode(); - void setParent(TimeBlock* parent); - TimeBlock* getParent() { return mParent; } +template +class MeasurementStatHandle +: public TraceType::type_t> > +{ +public: + typedef typename LLUnits::HighestPrecisionType::type_t storage_t; + typedef TraceType::type_t> > trace_t; - TimeBlock* mBlock; - TimeBlock* mParent; - std::vector mChildren; - bool mNeedsSorting; - }; + MeasurementStatHandle(const char* name, const char* description = NULL) + : trace_t(name, description) + {} +}; +template +void sample(MeasurementStatHandle& measurement, VALUE_T value) +{ + T converted_value(value); + measurement.getPrimaryAccumulator()->sample(LLUnits::rawValue(converted_value)); +} - template - class Measurement - : public TraceType::type_t> > - { - public: - typedef typename LLUnits::HighestPrecisionType::type_t storage_t; - typedef TraceType::type_t> > trace_t; - Measurement(const char* name, const char* description = NULL) - : trace_t(name, description) - {} +template +class CountStatHandle +: public TraceType::type_t> > +{ +public: + typedef typename LLUnits::HighestPrecisionType::type_t storage_t; + typedef TraceType::type_t> > trace_t; - template - void sample(UNIT_T value) - { - T converted_value(value); - trace_t::getPrimaryAccumulator()->sample(LLUnits::rawValue(converted_value)); - } - }; + CountStatHandle(const char* name, const char* description = NULL) + : trace_t(name) + {} - template - class Count - : public TraceType::type_t> > - { - public: - typedef typename LLUnits::HighestPrecisionType::type_t storage_t; - typedef TraceType::type_t> > trace_t; +}; - Count(const char* name, const char* description = NULL) - : trace_t(name) - {} +template +void add(CountStatHandle& count, VALUE_T value) +{ + T converted_value(value); + count.getPrimaryAccumulator()->add(LLUnits::rawValue(converted_value)); +} - template - void add(UNIT_T value) - { - T converted_value(value); - trace_t::getPrimaryAccumulator()->add(LLUnits::rawValue(converted_value)); - } - }; struct MemStatAccumulator { @@ -585,11 +587,11 @@ struct MemStatAccumulator mDeallocatedCount; }; -class MemStat : public TraceType +class MemStatHandle : public TraceType { public: typedef TraceType trace_t; - MemStat(const char* name) + MemStatHandle(const char* name) : trace_t(name) {} }; diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index af9ba02b29..6b4d4357db 100644 --- a/indra/llcommon/lltracerecording.h +++ b/indra/llcommon/lltracerecording.h @@ -135,11 +135,11 @@ namespace LLTrace LLUnit getSum(const TraceType& stat) const; LLUnit getPerSec(const TraceType& stat) const; - // Count accessors + // CountStatHandle accessors F64 getSum(const TraceType >& stat) const; S64 getSum(const TraceType >& stat) const; template - T getSum(const Count& stat) const + T getSum(const CountStatHandle& stat) const { return (T)getSum(static_cast::type_t> >&> (stat)); } @@ -147,7 +147,7 @@ namespace LLTrace F64 getPerSec(const TraceType >& stat) const; F64 getPerSec(const TraceType >& stat) const; template - T getPerSec(const Count& stat) const + T getPerSec(const CountStatHandle& stat) const { return (T)getPerSec(static_cast::type_t> >&> (stat)); } @@ -156,11 +156,11 @@ namespace LLTrace U32 getSampleCount(const TraceType >& stat) const; - // Measurement accessors + // MeasurementStatHandle accessors F64 getSum(const TraceType >& stat) const; S64 getSum(const TraceType >& stat) const; template - T getSum(const Measurement& stat) const + T getSum(const MeasurementStatHandle& stat) const { return (T)getSum(static_cast::type_t> >&> (stat)); } @@ -168,7 +168,7 @@ namespace LLTrace F64 getPerSec(const TraceType >& stat) const; F64 getPerSec(const TraceType >& stat) const; template - T getPerSec(const Measurement& stat) const + T getPerSec(const MeasurementStatHandle& stat) const { return (T)getPerSec(static_cast::type_t> >&> (stat)); } @@ -176,7 +176,7 @@ namespace LLTrace F64 getMin(const TraceType >& stat) const; S64 getMin(const TraceType >& stat) const; template - T getMin(const Measurement& stat) const + T getMin(const MeasurementStatHandle& stat) const { return (T)getMin(static_cast::type_t> >&> (stat)); } @@ -184,7 +184,7 @@ namespace LLTrace F64 getMax(const TraceType >& stat) const; S64 getMax(const TraceType >& stat) const; template - T getMax(const Measurement& stat) const + T getMax(const MeasurementStatHandle& stat) const { return (T)getMax(static_cast::type_t> >&> (stat)); } @@ -192,7 +192,7 @@ namespace LLTrace F64 getMean(const TraceType >& stat) const; F64 getMean(const TraceType >& stat) const; template - T getMean(Measurement& stat) const + T getMean(MeasurementStatHandle& stat) const { return (T)getMean(static_cast::type_t> >&> (stat)); } @@ -200,7 +200,7 @@ namespace LLTrace F64 getStandardDeviation(const TraceType >& stat) const; F64 getStandardDeviation(const TraceType >& stat) const; template - T getStandardDeviation(const Measurement& stat) const + T getStandardDeviation(const MeasurementStatHandle& stat) const { return (T)getMean(static_cast::type_t> >&> (stat)); } @@ -208,7 +208,7 @@ namespace LLTrace F64 getLastValue(const TraceType >& stat) const; S64 getLastValue(const TraceType >& stat) const; template - T getLastValue(const Measurement& stat) const + T getLastValue(const MeasurementStatHandle& stat) const { return (T)getLastValue(static_cast::type_t> >&> (stat)); } @@ -394,6 +394,7 @@ namespace LLTrace { public: void extend(); + Recording& getAcceptedRecording() { return mAcceptedRecording; } // implementation for LLStopWatchControlsMixin diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index f3452ce86a..f06547ed7d 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -50,7 +50,7 @@ LLMutex* LLImage::sMutex = NULL; bool LLImage::sUseNewByteRange = false; S32 LLImage::sMinimalReverseByteRangePercent = 75; LLPrivateMemoryPool* LLImageBase::sPrivatePoolp = NULL ; -LLTrace::MemStat LLImageBase::sMemStat("LLImage"); +LLTrace::MemStatHandle LLImageBase::sMemStat("LLImage"); //static void LLImage::initClass(bool use_new_byte_range, S32 minimal_reverse_byte_range_percent) diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 6eafcf1bf7..5487bc6370 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -165,7 +165,7 @@ public: static void destroyPrivatePool() ; static LLPrivateMemoryPool* getPrivatePool() {return sPrivatePoolp;} - static LLTrace::MemStat sMemStat; + static LLTrace::MemStatHandle sMemStat; private: U8 *mData; diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp index 328d15b4bc..430c9503ac 100644 --- a/indra/llmessage/llassetstorage.cpp +++ b/indra/llmessage/llassetstorage.cpp @@ -55,7 +55,7 @@ LLAssetStorage *gAssetStorage = NULL; LLMetrics *LLAssetStorage::metric_recipient = NULL; -static LLTrace::Count<> sFailedDownloadCount("faileddownloads", "Number of times LLAssetStorage::getAssetData() has failed"); +static LLTrace::CountStatHandle<> sFailedDownloadCount("faileddownloads", "Number of times LLAssetStorage::getAssetData() has failed"); const LLUUID CATEGORIZE_LOST_AND_FOUND_ID(std::string("00000000-0000-0000-0000-000000000010")); @@ -454,7 +454,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid, LLAssetType::EType type, LL if (callback) { - sFailedDownloadCount.add(1); + add(sFailedDownloadCount, 1); callback(mVFS, uuid, type, user_data, LL_ERR_ASSET_REQUEST_FAILED, LL_EXSTAT_NONE); } return; @@ -465,7 +465,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid, LLAssetType::EType type, LL // Special case early out for NULL uuid and for shutting down if (callback) { - sFailedDownloadCount.add(1); + add(sFailedDownloadCount, 1); callback(mVFS, uuid, type, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE, LL_EXSTAT_NULL_UUID); } return; @@ -578,7 +578,7 @@ void LLAssetStorage::_queueDataRequest(const LLUUID& uuid, LLAssetType::EType at llwarns << "Attempt to move asset data request upstream w/o valid upstream provider" << llendl; if (callback) { - sFailedDownloadCount.add(1); + add(sFailedDownloadCount, 1); callback(mVFS, uuid, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM); } } @@ -658,7 +658,7 @@ void LLAssetStorage::downloadCompleteCallback( { if (result != LL_ERR_NOERR) { - sFailedDownloadCount.add(1); + add(sFailedDownloadCount, 1); } tmp->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getType(), tmp->mUserData, result, ext_status); } @@ -680,7 +680,7 @@ void LLAssetStorage::getEstateAsset(const LLHost &object_sim, const LLUUID &agen // Special case early out for NULL uuid if (callback) { - sFailedDownloadCount.add(1); + add(sFailedDownloadCount, 1); callback(mVFS, asset_id, atype, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE, LL_EXSTAT_NULL_UUID); } return; @@ -753,7 +753,7 @@ void LLAssetStorage::getEstateAsset(const LLHost &object_sim, const LLUUID &agen llwarns << "Attempt to move asset data request upstream w/o valid upstream provider" << llendl; if (callback) { - sFailedDownloadCount.add(1); + add(sFailedDownloadCount, 1); callback(mVFS, asset_id, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM); } } @@ -798,7 +798,7 @@ void LLAssetStorage::downloadEstateAssetCompleteCallback( if (result != LL_ERR_NOERR) { - sFailedDownloadCount.add(1); + add(sFailedDownloadCount, 1); } req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getAType(), req->mUserData, result, ext_status); } @@ -900,7 +900,7 @@ void LLAssetStorage::getInvItemAsset(const LLHost &object_sim, const LLUUID &age llwarns << "Attempt to move asset data request upstream w/o valid upstream provider" << llendl; if (callback) { - sFailedDownloadCount.add(1); + add(sFailedDownloadCount, 1); callback(mVFS, asset_id, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM); } } @@ -945,7 +945,7 @@ void LLAssetStorage::downloadInvItemCompleteCallback( if (result != LL_ERR_NOERR) { - sFailedDownloadCount.add(1); + add(sFailedDownloadCount, 1); } req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getType(), req->mUserData, result, ext_status); } @@ -1259,7 +1259,7 @@ bool LLAssetStorage::deletePendingRequestImpl(LLAssetStorage::request_list_t* re } if (req->mDownCallback) { - sFailedDownloadCount.add(1); + add(sFailedDownloadCount, 1); req->mDownCallback(mVFS, req->getUUID(), req->getType(), req->mUserData, error, LL_EXSTAT_REQUEST_DROPPED); } if (req->mInfoCallback) @@ -1388,7 +1388,7 @@ void LLAssetStorage::legacyGetDataCallback(LLVFS *vfs, const LLUUID &uuid, LLAss if (status != LL_ERR_NOERR) { - sFailedDownloadCount.add(1); + add(sFailedDownloadCount, 1); } legacy->mDownCallback(filename.c_str(), uuid, legacy->mUserData, status, ext_status); delete legacy; diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp index 1bc9a9fc67..954f615210 100644 --- a/indra/llui/llstatbar.cpp +++ b/indra/llui/llstatbar.cpp @@ -45,10 +45,10 @@ LLStatBar::LLStatBar(const Params& p) mUnitLabel(p.unit_label), mMinBar(p.bar_min), mMaxBar(p.bar_max), - mCountFloatp(LLTrace::Count<>::getInstance(p.stat)), - mCountIntp(LLTrace::Count::getInstance(p.stat)), - mMeasurementFloatp(LLTrace::Measurement<>::getInstance(p.stat)), - mMeasurementIntp(LLTrace::Measurement::getInstance(p.stat)), + mCountFloatp(LLTrace::CountStatHandle<>::getInstance(p.stat)), + mCountIntp(LLTrace::CountStatHandle::getInstance(p.stat)), + mMeasurementFloatp(LLTrace::MeasurementStatHandle<>::getInstance(p.stat)), + mMeasurementIntp(LLTrace::MeasurementStatHandle::getInstance(p.stat)), mTickSpacing(p.tick_spacing), mLabelSpacing(p.label_spacing), mPrecision(p.precision), @@ -336,10 +336,10 @@ void LLStatBar::draw() void LLStatBar::setStat(const std::string& stat_name) { - mCountFloatp = LLTrace::Count<>::getInstance(stat_name); - mCountIntp = LLTrace::Count::getInstance(stat_name); - mMeasurementFloatp = LLTrace::Measurement<>::getInstance(stat_name); - mMeasurementIntp = LLTrace::Measurement::getInstance(stat_name); + mCountFloatp = LLTrace::CountStatHandle<>::getInstance(stat_name); + mCountIntp = LLTrace::CountStatHandle::getInstance(stat_name); + mMeasurementFloatp = LLTrace::MeasurementStatHandle<>::getInstance(stat_name); + mMeasurementIntp = LLTrace::MeasurementStatHandle::getInstance(stat_name); } diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 74e966560e..680b6ed16d 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -47,7 +47,7 @@ const F32 CURSOR_FLASH_DELAY = 1.0f; // in seconds const S32 CURSOR_THICKNESS = 2; -LLTrace::MemStat LLTextSegment::sMemStat("LLTextSegment"); +LLTrace::MemStatHandle LLTextSegment::sMemStat("LLTextSegment"); LLTextBase::line_info::line_info(S32 index_start, S32 index_end, LLRect rect, S32 line_num) : mDocIndexStart(index_start), diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 7d791ec75a..2ce15d891a 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -99,7 +99,7 @@ public: S32 getEnd() const { return mEnd; } void setEnd( S32 end ) { mEnd = end; } - static LLTrace::MemStat sMemStat; + static LLTrace::MemStatHandle sMemStat; protected: S32 mStart; diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 47bf410af6..587953477d 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -67,7 +67,7 @@ LLView* LLView::sPreviewClickedElement = NULL; BOOL LLView::sDrawPreviewHighlights = FALSE; S32 LLView::sLastLeftXML = S32_MIN; S32 LLView::sLastBottomXML = S32_MIN; -LLTrace::MemStat LLView::sMemStat("LLView"); +LLTrace::MemStatHandle LLView::sMemStat("LLView"); std::vector LLViewDrawContext::sDrawContextStack; LLView::DrilldownFunc LLView::sDrilldown = diff --git a/indra/llui/llview.h b/indra/llui/llview.h index 256f86c00d..e18cfff8e5 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -673,7 +673,7 @@ public: static S32 sLastLeftXML; static S32 sLastBottomXML; static BOOL sForceReshape; - static LLTrace::MemStat sMemStat; + static LLTrace::MemStatHandle sMemStat; }; class LLCompareByTabOrder diff --git a/indra/llui/llviewmodel.cpp b/indra/llui/llviewmodel.cpp index 1bd09e8086..901260bec8 100644 --- a/indra/llui/llviewmodel.cpp +++ b/indra/llui/llviewmodel.cpp @@ -35,7 +35,7 @@ // external library headers // other Linden headers -LLTrace::MemStat LLViewModel::sMemStat("LLViewModel"); +LLTrace::MemStatHandle LLViewModel::sMemStat("LLViewModel"); /// LLViewModel::LLViewModel() diff --git a/indra/llui/llviewmodel.h b/indra/llui/llviewmodel.h index 214780393b..2c016d2560 100644 --- a/indra/llui/llviewmodel.h +++ b/indra/llui/llviewmodel.h @@ -83,7 +83,7 @@ public: // void setDirty() { mDirty = true; } - static LLTrace::MemStat sMemStat; + static LLTrace::MemStatHandle sMemStat; protected: LLSD mValue; diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 14235bcee4..4fb298df13 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -752,7 +752,7 @@ void LLAgent::setFlying(BOOL fly) } if( !was_flying ) { - LLStatViewer::FLY.add(1); + add(LLStatViewer::FLY, 1); } setControlFlags(AGENT_CONTROL_FLY); } @@ -3806,7 +3806,7 @@ bool LLAgent::teleportCore(bool is_local) gAgentCamera.resetView(FALSE); // local logic - LLStatViewer::TELEPORT.add(1); + add(LLStatViewer::TELEPORT, 1); if (is_local) { gAgent.setTeleportState( LLAgent::TELEPORT_LOCAL ); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 3d7770c765..c00fddbb24 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4865,7 +4865,7 @@ void LLAppViewer::idleNetwork() gPrintMessagesThisFrame = FALSE; } } - LLStatViewer::NUM_NEW_OBJECTS.sample(gObjectList.mNumNewObjects); + sample(LLStatViewer::NUM_NEW_OBJECTS, gObjectList.mNumNewObjects); // Retransmit unacknowledged packets. gXferManager->retransmitUnackedPackets(); diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index ba970671af..9c3d9f4d34 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -59,7 +59,7 @@ const F32 MIN_SHADOW_CASTER_RADIUS = 2.0f; static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound"); extern bool gShiftFrame; -LLTrace::MemStat LLDrawable::sMemStat("LLDrawable"); +LLTrace::MemStatHandle LLDrawable::sMemStat("LLDrawable"); //////////////////////// diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 161f550bb6..3691bbf71b 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -292,7 +292,7 @@ public: F32 mDistanceWRTCamera; static F32 sCurPixelAngle; //current pixels per radian - static LLTrace::MemStat sMemStat; + static LLTrace::MemStatHandle sMemStat; private: typedef std::vector face_list_t; diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp index ab7fc1cf3f..25c119d9e1 100644 --- a/indra/newview/llfloaterjoystick.cpp +++ b/indra/newview/llfloaterjoystick.cpp @@ -42,13 +42,13 @@ #include "llviewerjoystick.h" #include "llcheckboxctrl.h" -static LLTrace::Measurement<> sJoystickAxis1("Joystick axis 1"), - sJoystickAxis2("Joystick axis 2"), - sJoystickAxis3("Joystick axis 3"), - sJoystickAxis4("Joystick axis 4"), - sJoystickAxis5("Joystick axis 5"), - sJoystickAxis6("Joystick axis 6"); -static LLTrace::Measurement<>* sJoystickAxes[6] = +static LLTrace::MeasurementStatHandle<> sJoystickAxis1("Joystick axis 1"), + sJoystickAxis2("Joystick axis 2"), + sJoystickAxis3("Joystick axis 3"), + sJoystickAxis4("Joystick axis 4"), + sJoystickAxis5("Joystick axis 5"), + sJoystickAxis6("Joystick axis 6"); +static LLTrace::MeasurementStatHandle<>* sJoystickAxes[6] = { &sJoystickAxis1, &sJoystickAxis2, diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 0d90037e7b..04fc572220 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -992,7 +992,7 @@ void LLSnapshotLivePreview::saveTexture() llwarns << "Error encoding snapshot" << llendl; } - LLStatViewer::SNAPSHOT.add(1); + add(LLStatViewer::SNAPSHOT, 1); mDataSize = 0; } diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index 56fbdb429a..c12916ec6b 100644 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -900,7 +900,7 @@ void LLHUDNameTag::updateAll() // } } - LLTrace::Count<>* camera_vel_stat = LLViewerCamera::getVelocityStat(); + LLTrace::CountStatHandle<>* camera_vel_stat = LLViewerCamera::getVelocityStat(); F32 camera_vel = LLTrace::get_frame_recording().getLastRecordingPeriod().getPerSec(*camera_vel_stat); if (camera_vel > MAX_STABLE_CAMERA_VELOCITY) { diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index 23cbfae044..142aaa795b 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -638,7 +638,7 @@ void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 gAgent.sendReliableMessage(); - LLStatViewer::CHAT_COUNT.add(1); + add(LLStatViewer::CHAT_COUNT, 1); } class LLChatCommandHandler : public LLCommandHandler diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 39ded21183..88f2c5ff52 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1049,7 +1049,7 @@ BOOL LLPanelFace::onDragTexture(LLUICtrl*, LLInventoryItem* item) void LLPanelFace::onCommitTexture( const LLSD& data ) { - LLStatViewer::EDIT_TEXTURE.add(1); + add(LLStatViewer::EDIT_TEXTURE, 1); sendTexture(); } diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 050db136bc..f87a958fbc 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -942,7 +942,7 @@ void LLScriptEdCore::onBtnInsertFunction(LLUICtrl *ui, void* userdata) void LLScriptEdCore::doSave( BOOL close_after_save ) { - LLStatViewer::LSL_SAVES.add(1); + add(LLStatViewer::LSL_SAVES, 1); if( mSaveCallback ) { @@ -1146,7 +1146,7 @@ void LLScriptEdCore::onBtnLoadFromFile( void* data ) void LLScriptEdCore::onBtnSaveToFile( void* userdata ) { - LLStatViewer::LSL_SAVES.add(1); + add(LLStatViewer::LSL_SAVES, 1); LLScriptEdCore* self = (LLScriptEdCore*) userdata; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 36ce7bb60e..bdbb1bb797 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1550,7 +1550,7 @@ void LLObjectSelection::applyNoCopyTextureToTEs(LLViewerInventoryItem* item) } // apply texture for the selected faces - LLStatViewer::EDIT_TEXTURE.add(1); + add(LLStatViewer::EDIT_TEXTURE, 1); object->setTEImage(te, image); dialog_refresh_all(); @@ -3424,7 +3424,7 @@ bool LLSelectMgr::confirmDelete(const LLSD& notification, const LLSD& response, gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR); // Keep track of how many objects have been deleted. - LLStatViewer::DELETE_OBJECT.add(LLSelectMgr::getInstance()->mSelectedObjects->getObjectCount()); + add(LLStatViewer::DELETE_OBJECT, LLSelectMgr::getInstance()->mSelectedObjects->getObjectCount()); } break; case 1: diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 648fb0f7b7..2effec7d3a 100755 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -2071,7 +2071,7 @@ bool idle_startup() if (wearables_time > MAX_WEARABLES_TIME) { LLNotificationsUtil::add("ClothingLoading"); - LLStatViewer::LOADING_WEARABLES_LONG_DELAY.add(1); + add(LLStatViewer::LOADING_WEARABLES_LONG_DELAY, 1); LLStartUp::setStartupState( STATE_CLEANUP ); return TRUE; } diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index fad7a73008..d6cd881894 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -460,7 +460,7 @@ BOOL LLTexLayerSetBuffer::requestUpdateImmediate() void LLTexLayerSetBuffer::doUpload() { llinfos << "Uploading baked " << mTexLayerSet->getBodyRegionName() << llendl; - LLStatViewer::TEX_BAKES.add(1); + add(LLStatViewer::TEX_BAKES, 1); // Don't need caches since we're baked now. (note: we won't *really* be baked // until this image is sent to the server and the Avatar Appearance message is received.) diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index fba636e8ef..0dc2601e60 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -65,8 +65,8 @@ #include "bufferstream.h" bool LLTextureFetchDebugger::sDebuggerEnabled = false ; -LLTrace::Measurement<> LLTextureFetch::sCacheHitRate("texture_cache_hits"); -LLTrace::Measurement<> LLTextureFetch::sCacheReadLatency("texture_cache_read_latency"); +LLTrace::MeasurementStatHandle<> LLTextureFetch::sCacheHitRate("texture_cache_hits"); +LLTrace::MeasurementStatHandle<> LLTextureFetch::sCacheReadLatency("texture_cache_read_latency"); ////////////////////////////////////////////////////////////////////////////// @@ -1237,7 +1237,7 @@ bool LLTextureFetchWorker::doWork(S32 param) LL_DEBUGS("Texture") << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize() << " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight()) << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL; - LLTextureFetch::sCacheHitRate.sample(100.f); + sample(LLTextureFetch::sCacheHitRate, 100.f); } else { @@ -1254,7 +1254,7 @@ bool LLTextureFetchWorker::doWork(S32 param) } // fall through - LLTextureFetch::sCacheHitRate.sample(0.f); + sample(LLTextureFetch::sCacheHitRate, 0.f); } } @@ -2706,7 +2706,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, F32 cache_read_time = worker->mCacheReadTime; if (cache_read_time != 0.f) { - sCacheReadLatency.sample(cache_read_time * 1000.f); + sample(sCacheReadLatency, cache_read_time * 1000.f); } res = true; LL_DEBUGS("Texture") << id << ": Request Finished. State: " << worker->mState << " Discard: " << discard_level << LL_ENDL; @@ -2832,7 +2832,7 @@ S32 LLTextureFetch::update(F32 max_time_ms) mNetworkQueueMutex.lock(); // +Mfnq mMaxBandwidth = band_width ; - LLStatViewer::TEXTURE_KBIT.add(mHTTPTextureBits); + add(LLStatViewer::TEXTURE_KBIT, mHTTPTextureBits); mHTTPTextureBits = 0; mNetworkQueueMutex.unlock(); // -Mfnq diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 2c1e7502e5..2e398023fe 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -308,8 +308,8 @@ private: LLMutex mQueueMutex; //to protect mRequestMap and mCommands only LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue. - static LLTrace::Measurement<> sCacheHitRate; - static LLTrace::Measurement<> sCacheReadLatency; + static LLTrace::MeasurementStatHandle<> sCacheHitRate; + static LLTrace::MeasurementStatHandle<> sCacheReadLatency; LLTextureCache* mTextureCache; LLImageDecodeThread* mImageDecodeThread; diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 652847aac9..90ae0b428b 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1062,7 +1062,7 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj, return; } LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); - LLStatViewer::EDIT_TEXTURE.add(1); + add(LLStatViewer::EDIT_TEXTURE, 1); S32 num_faces = hit_obj->getNumTEs(); for( S32 face = 0; face < num_faces; face++ ) { @@ -1130,7 +1130,7 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, } // update viewer side image in anticipation of update from simulator LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); - LLStatViewer::EDIT_TEXTURE.add(1); + add(LLStatViewer::EDIT_TEXTURE, 1); hit_obj->setTEImage(hit_face, image); dialog_refresh_all(); @@ -1354,7 +1354,7 @@ void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target, effectp->setDuration(LL_HUD_DUR_SHORT); effectp->setColor(LLColor4U(gAgent.getEffectColor())); - LLStatViewer::OBJECT_REZ.add(1); + add(LLStatViewer::OBJECT_REZ, 1); } void LLToolDragAndDrop::dropInventory(LLViewerObject* hit_obj, diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp index 329249eee8..c026ddd42e 100644 --- a/indra/newview/lltoolplacer.cpp +++ b/indra/newview/lltoolplacer.cpp @@ -433,7 +433,7 @@ BOOL LLToolPlacer::addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics ) effectp->setDuration(LL_HUD_DUR_SHORT); effectp->setColor(LLColor4U(gAgent.getEffectColor())); - LLStatViewer::OBJECT_CREATE.add(1); + add(LLStatViewer::OBJECT_CREATE, 1); return TRUE; } diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp index 890394dd22..0c72c3c5aa 100644 --- a/indra/newview/llviewerassetstats.cpp +++ b/indra/newview/llviewerassetstats.cpp @@ -177,7 +177,7 @@ namespace LLViewerAssetStatsFF return ret; } - static LLTrace::Count<> sEnqueueAssetRequestsTempTextureHTTP ("enqueuedassetrequeststemptexturehttp", + static LLTrace::CountStatHandle<> sEnqueueAssetRequestsTempTextureHTTP ("enqueuedassetrequeststemptexturehttp", "Number of temporary texture asset http requests enqueued"), sEnqueueAssetRequestsTempTextureUDP ("enqueuedassetrequeststemptextureudp", "Number of temporary texture asset udp requests enqueued"), @@ -194,7 +194,7 @@ namespace LLViewerAssetStatsFF sEnqueuedAssetRequestsOther ("enqueuedassetrequestsother", "Number of other asset requests enqueued"); - static LLTrace::Count<>* sEnqueued[EVACCount] = { + static LLTrace::CountStatHandle<>* sEnqueued[EVACCount] = { &sEnqueueAssetRequestsTempTextureHTTP, &sEnqueueAssetRequestsTempTextureUDP, &sEnqueueAssetRequestsNonTempTextureHTTP, @@ -205,7 +205,7 @@ namespace LLViewerAssetStatsFF &sEnqueuedAssetRequestsOther }; - static LLTrace::Count<> sDequeueAssetRequestsTempTextureHTTP ("dequeuedassetrequeststemptexturehttp", + static LLTrace::CountStatHandle<> sDequeueAssetRequestsTempTextureHTTP ("dequeuedassetrequeststemptexturehttp", "Number of temporary texture asset http requests dequeued"), sDequeueAssetRequestsTempTextureUDP ("dequeuedassetrequeststemptextureudp", "Number of temporary texture asset udp requests dequeued"), @@ -222,7 +222,7 @@ namespace LLViewerAssetStatsFF sDequeuedAssetRequestsOther ("dequeuedassetrequestsother", "Number of other asset requests dequeued"); - static LLTrace::Count<>* sDequeued[EVACCount] = { + static LLTrace::CountStatHandle<>* sDequeued[EVACCount] = { &sDequeueAssetRequestsTempTextureHTTP, &sDequeueAssetRequestsTempTextureUDP, &sDequeueAssetRequestsNonTempTextureHTTP, @@ -233,7 +233,7 @@ namespace LLViewerAssetStatsFF &sDequeuedAssetRequestsOther }; - static LLTrace::Measurement sResponseAssetRequestsTempTextureHTTP ("assetresponsetimestemptexturehttp", + static LLTrace::MeasurementStatHandle sResponseAssetRequestsTempTextureHTTP ("assetresponsetimestemptexturehttp", "Time spent responding to temporary texture asset http requests"), sResponseAssetRequestsTempTextureUDP ("assetresponsetimestemptextureudp", "Time spent responding to temporary texture asset udp requests"), @@ -250,7 +250,7 @@ namespace LLViewerAssetStatsFF sResponsedAssetRequestsOther ("assetresponsetimesother", "Time spent responding to other asset requests"); - static LLTrace::Measurement* sResponse[EVACCount] = { + static LLTrace::MeasurementStatHandle* sResponse[EVACCount] = { &sResponseAssetRequestsTempTextureHTTP, &sResponseAssetRequestsTempTextureUDP, &sResponseAssetRequestsNonTempTextureHTTP, diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index f74897daa7..6e0a2c88a8 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -54,8 +54,8 @@ // System includes #include // for setprecision -LLTrace::Count<> LLViewerCamera::sVelocityStat("camera_velocity"); -LLTrace::Count<> LLViewerCamera::sAngularVelocityStat("camera_angular_velocity"); +LLTrace::CountStatHandle<> LLViewerCamera::sVelocityStat("camera_velocity"); +LLTrace::CountStatHandle<> LLViewerCamera::sAngularVelocityStat("camera_angular_velocity"); U32 LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h index 607bfa7199..ffec284f72 100644 --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -101,8 +101,8 @@ public: BOOL projectPosAgentToScreenEdge(const LLVector3 &pos_agent, LLCoordGL &out_point) const; const LLVector3* getVelocityDir() const {return &mVelocityDir;} - static LLTrace::Count<>* getVelocityStat() {return &sVelocityStat; } - static LLTrace::Count<>* getAngularVelocityStat() {return &sAngularVelocityStat; } + static LLTrace::CountStatHandle<>* getVelocityStat() {return &sVelocityStat; } + static LLTrace::CountStatHandle<>* getAngularVelocityStat() {return &sAngularVelocityStat; } F32 getCosHalfFov() {return mCosHalfCameraFOV;} F32 getAverageSpeed() {return mAverageSpeed ;} F32 getAverageAngularSpeed() {return mAverageAngularSpeed;} @@ -130,8 +130,8 @@ public: protected: void calcProjection(const F32 far_distance) const; - static LLTrace::Count<> sVelocityStat; - static LLTrace::Count<> sAngularVelocityStat; + static LLTrace::CountStatHandle<> sVelocityStat; + static LLTrace::CountStatHandle<> sAngularVelocityStat; LLVector3 mVelocityDir ; F32 mAverageSpeed ; diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index fe83f80caa..2aec25b7aa 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -749,8 +749,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LLFastTimer t(FTM_IMAGE_UPDATE_CLASS); - LLTrace::Count<>* velocity_stat = LLViewerCamera::getVelocityStat(); - LLTrace::Count<>* angular_velocity_stat = LLViewerCamera::getAngularVelocityStat(); + LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat(); + LLTrace::CountStatHandle<>* angular_velocity_stat = LLViewerCamera::getAngularVelocityStat(); LLViewerTexture::updateClass(LLTrace::get_frame_recording().getPeriodMeanPerSec(*velocity_stat), LLTrace::get_frame_recording().getPeriodMeanPerSec(*angular_velocity_stat)); } diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 50ca8db267..b7282a8493 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -1096,17 +1096,17 @@ void upload_new_resource( if( LLAssetType::AT_SOUND == asset_type ) { - LLStatViewer::UPLOAD_SOUND.add(1); + add(LLStatViewer::UPLOAD_SOUND, 1); } else if( LLAssetType::AT_TEXTURE == asset_type ) { - LLStatViewer::UPLOAD_TEXTURE.add(1); + add(LLStatViewer::UPLOAD_TEXTURE, 1); } else if( LLAssetType::AT_ANIMATION == asset_type) { - LLStatViewer::ANIMATION_UPLOADS.add(1); + add(LLStatViewer::ANIMATION_UPLOADS, 1); } if(LLInventoryType::IT_NONE == inv_type) @@ -1231,15 +1231,15 @@ void increase_new_upload_stats(LLAssetType::EType asset_type) { if ( LLAssetType::AT_SOUND == asset_type ) { - LLStatViewer::UPLOAD_SOUND.add(1); + add(LLStatViewer::UPLOAD_SOUND, 1); } else if ( LLAssetType::AT_TEXTURE == asset_type ) { - LLStatViewer::UPLOAD_TEXTURE.add(1); + add(LLStatViewer::UPLOAD_TEXTURE, 1); } else if ( LLAssetType::AT_ANIMATION == asset_type ) { - LLStatViewer::ANIMATION_UPLOADS.add(1); + add(LLStatViewer::ANIMATION_UPLOADS, 1); } } diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 7a2025ed5b..db169b86a4 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -5824,7 +5824,7 @@ void process_alert_core(const std::string& message, BOOL modal) // HACK -- handle callbacks for specific alerts. It also is localized in notifications.xml if ( message == "You died and have been teleported to your home location") { - LLStatViewer::KILLED.add(1); + add(LLStatViewer::KILLED, 1); } else if( message == "Home position set." ) { diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index f5f5bdffbd..a5bd57145d 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -113,7 +113,7 @@ BOOL LLViewerObject::sMapDebug = TRUE; LLColor4 LLViewerObject::sEditSelectColor( 1.0f, 1.f, 0.f, 0.3f); // Edit OK LLColor4 LLViewerObject::sNoEditSelectColor( 1.0f, 0.f, 0.f, 0.3f); // Can't edit S32 LLViewerObject::sAxisArrowLength(50); -LLTrace::MemStat LLViewerObject::sMemStat("LLViewerObject"); +LLTrace::MemStatHandle LLViewerObject::sMemStat("LLViewerObject"); BOOL LLViewerObject::sPulseEnabled(FALSE); @@ -2103,7 +2103,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, // If we're snapping the position by more than 0.5m, update LLViewerStats::mAgentPositionSnaps if ( asAvatar() && asAvatar()->isSelf() && (mag_sqr > 0.25f) ) { - LLStatViewer::AGENT_POSITION_SNAP.sample(diff.length()); + sample(LLStatViewer::AGENT_POSITION_SNAP, LLTrace::Meters(diff.length())); } } diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 20254bfe02..aa30d1c790 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -636,7 +636,7 @@ public: LLPointer mIcon; static BOOL sUseSharedDrawables; - static LLTrace::MemStat sMemStat; + static LLTrace::MemStatHandle sMemStat; protected: // delete an item in the inventory, but don't tell the diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 0335cd769b..176ee49d31 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -94,7 +94,7 @@ extern LLPipeline gPipeline; U32 LLViewerObjectList::sSimulatorMachineIndex = 1; // Not zero deliberately, to speed up index check. std::map LLViewerObjectList::sIPAndPortToIndex; std::map LLViewerObjectList::sIndexAndLocalIDToUUID; -LLTrace::Measurement<> LLViewerObjectList::sCacheHitRate("object_cache_hits"); +LLTrace::MeasurementStatHandle<> LLViewerObjectList::sCacheHitRate("object_cache_hits"); LLViewerObjectList::LLViewerObjectList() { @@ -356,7 +356,7 @@ LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry* } justCreated = true; mNumNewObjects++; - sCacheHitRate.sample(100.f); + sample(sCacheHitRate, 100.f); } if (objectp->isDead()) @@ -670,7 +670,7 @@ void LLViewerObjectList::processCachedObjectUpdate(LLMessageSystem *mesgsys, continue; // no data packer, skip this object } - sCacheHitRate.sample(100.f); + sample(sCacheHitRate, 100.f); } return; @@ -1123,10 +1123,10 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) } */ - LLStatViewer::NUM_OBJECTS.sample(mObjects.size()); - LLStatViewer::NUM_ACTIVE_OBJECTS.sample(idle_count); - LLStatViewer::NUM_SIZE_CULLED.sample(mNumSizeCulled); - LLStatViewer::NUM_VIS_CULLED.sample(mNumVisCulled); + sample(LLStatViewer::NUM_OBJECTS, mObjects.size()); + sample(LLStatViewer::NUM_ACTIVE_OBJECTS, idle_count); + sample(LLStatViewer::NUM_SIZE_CULLED, mNumSizeCulled); + sample(LLStatViewer::NUM_VIS_CULLED, mNumVisCulled); } void LLViewerObjectList::fetchObjectCosts() diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index b92be61fae..cb11ef1f5e 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -198,7 +198,7 @@ protected: std::vector mOrphanChildren; // UUID's of orphaned objects S32 mNumOrphans; - static LLTrace::Measurement<> sCacheHitRate; + static LLTrace::MeasurementStatHandle<> sCacheHitRate; typedef std::vector > vobj_list_t; diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 136a4d0a9e..921c681e2a 100755 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -64,48 +64,48 @@ namespace LLStatViewer { -LLTrace::Count<> FPS("fpsstat"), - PACKETS_IN("packetsinstat"), - PACKETS_LOST("packetsloststat"), - PACKETS_OUT("packetsoutstat"), - TEXTURE_PACKETS("texturepacketsstat"), - TRIANGLES_DRAWN("trianglesdrawnstat"), - CHAT_COUNT("chatcount", "Chat messages sent"), - IM_COUNT("imcount", "IMs sent"), - OBJECT_CREATE("objectcreate"), - OBJECT_REZ("objectrez", "Object rez count"), - LOADING_WEARABLES_LONG_DELAY("loadingwearableslongdelay", "Wearables took too long to load"), - LOGIN_TIMEOUTS("logintimeouts", "Number of login attempts that timed out"), - LSL_SAVES("lslsaves", "Number of times user has saved a script"), - ANIMATION_UPLOADS("animationuploads", "Animations uploaded"), - FLY("fly", "Fly count"), - TELEPORT("teleport", "Teleport count"), - DELETE_OBJECT("deleteobject", "Objects deleted"), - SNAPSHOT("snapshot", "Snapshots taken"), - UPLOAD_SOUND("uploadsound", "Sounds uploaded"), - UPLOAD_TEXTURE("uploadtexture", "Textures uploaded"), - EDIT_TEXTURE("edittexture", "Changes to textures on objects"), - KILLED("killed", "Number of times killed"), - FRAMETIME_DOUBLED("frametimedoubled", "Ratio of frames 2x longer than previous"), - TEX_BAKES("texbakes"), - TEX_REBAKES("texrebakes"); -LLTrace::Count KBIT("kbitstat"), - LAYERS_KBIT("layerskbitstat"), - OBJECT_KBIT("objectkbitstat"), - ASSET_KBIT("assetkbitstat"), - TEXTURE_KBIT("texturekbitstat"), - ACTUAL_IN_KBIT("actualinkbitstat"), - ACTUAL_OUT_KBIT("actualoutkbitstat"); - -LLTrace::Count AVATAR_EDIT_TIME("avataredittime", "Seconds in Edit Appearence"), - TOOLBOX_TIME("toolboxtime", "Seconds using Toolbox"), - MOUSELOOK_TIME("mouselooktime", "Seconds in Mouselook"), - FPS_10_TIME("fps10time", "Seconds below 10 FPS"), - FPS_8_TIME("fps8time", "Seconds below 8 FPS"), - FPS_2_TIME("fps2time", "Seconds below 2 FPS"), - SIM_20_FPS_TIME("sim20fpstime", "Seconds with sim FPS below 20"), - SIM_PHYSICS_20_FPS_TIME("simphysics20fpstime", "Seconds with physics FPS below 20"), - LOSS_5_PERCENT_TIME("loss5percenttime", "Seconds with packet loss > 5%"); +LLTrace::CountStatHandle<> FPS("fpsstat"), + PACKETS_IN("packetsinstat"), + PACKETS_LOST("packetsloststat"), + PACKETS_OUT("packetsoutstat"), + TEXTURE_PACKETS("texturepacketsstat"), + TRIANGLES_DRAWN("trianglesdrawnstat"), + CHAT_COUNT("chatcount", "Chat messages sent"), + IM_COUNT("imcount", "IMs sent"), + OBJECT_CREATE("objectcreate"), + OBJECT_REZ("objectrez", "Object rez count"), + LOADING_WEARABLES_LONG_DELAY("loadingwearableslongdelay", "Wearables took too long to load"), + LOGIN_TIMEOUTS("logintimeouts", "Number of login attempts that timed out"), + LSL_SAVES("lslsaves", "Number of times user has saved a script"), + ANIMATION_UPLOADS("animationuploads", "Animations uploaded"), + FLY("fly", "Fly count"), + TELEPORT("teleport", "Teleport count"), + DELETE_OBJECT("deleteobject", "Objects deleted"), + SNAPSHOT("snapshot", "Snapshots taken"), + UPLOAD_SOUND("uploadsound", "Sounds uploaded"), + UPLOAD_TEXTURE("uploadtexture", "Textures uploaded"), + EDIT_TEXTURE("edittexture", "Changes to textures on objects"), + KILLED("killed", "Number of times killed"), + FRAMETIME_DOUBLED("frametimedoubled", "Ratio of frames 2x longer than previous"), + TEX_BAKES("texbakes"), + TEX_REBAKES("texrebakes"); +LLTrace::CountStatHandle KBIT("kbitstat"), + LAYERS_KBIT("layerskbitstat"), + OBJECT_KBIT("objectkbitstat"), + ASSET_KBIT("assetkbitstat"), + TEXTURE_KBIT("texturekbitstat"), + ACTUAL_IN_KBIT("actualinkbitstat"), + ACTUAL_OUT_KBIT("actualoutkbitstat"); + +LLTrace::CountStatHandle AVATAR_EDIT_TIME("avataredittime", "Seconds in Edit Appearence"), + TOOLBOX_TIME("toolboxtime", "Seconds using Toolbox"), + MOUSELOOK_TIME("mouselooktime", "Seconds in Mouselook"), + FPS_10_TIME("fps10time", "Seconds below 10 FPS"), + FPS_8_TIME("fps8time", "Seconds below 8 FPS"), + FPS_2_TIME("fps2time", "Seconds below 2 FPS"), + SIM_20_FPS_TIME("sim20fpstime", "Seconds with sim FPS below 20"), + SIM_PHYSICS_20_FPS_TIME("simphysics20fpstime", "Seconds with physics FPS below 20"), + LOSS_5_PERCENT_TIME("loss5percenttime", "Seconds with packet loss > 5%"); SimMeasurement<> SIM_TIME_DILATION("simtimedilation", "", LL_SIM_STAT_TIME_DILATION), SIM_FPS("simfps", "", LL_SIM_STAT_FPS), @@ -128,34 +128,34 @@ SimMeasurement<> SIM_TIME_DILATION("simtimedilation", "", LL_SIM_STAT_TIME_DIL SIM_PHYSICS_PINNED_TASKS("physicspinnedtasks", "", LL_SIM_STAT_PHYSICS_PINNED_TASKS), SIM_PHYSICS_LOD_TASKS("physicslodtasks", "", LL_SIM_STAT_PHYSICS_LOD_TASKS); -LLTrace::Measurement<> FPS_SAMPLE("fpssample"), - NUM_IMAGES("numimagesstat"), - NUM_RAW_IMAGES("numrawimagesstat"), - NUM_OBJECTS("numobjectsstat"), - NUM_ACTIVE_OBJECTS("numactiveobjectsstat"), - NUM_NEW_OBJECTS("numnewobjectsstat"), - NUM_SIZE_CULLED("numsizeculledstat"), - NUM_VIS_CULLED("numvisculledstat"), - ENABLE_VBO("enablevbo", "Vertex Buffers Enabled"), - LIGHTING_DETAIL("lightingdetail", "Lighting Detail"), - VISIBLE_AVATARS("visibleavatars", "Visible Avatars"), - SHADER_OBJECTS("shaderobjects", "Object Shaders"), - DRAW_DISTANCE("drawdistance", "Draw Distance"), - CHAT_BUBBLES("chatbubbles", "Chat Bubbles Enabled"), - PENDING_VFS_OPERATIONS("vfspendingoperations"), - PACKETS_LOST_PERCENT("packetslostpercentstat"), - WINDOW_WIDTH("windowwidth", "Window width"), - WINDOW_HEIGHT("windowheight", "Window height"); +LLTrace::MeasurementStatHandle<> FPS_SAMPLE("fpssample"), + NUM_IMAGES("numimagesstat"), + NUM_RAW_IMAGES("numrawimagesstat"), + NUM_OBJECTS("numobjectsstat"), + NUM_ACTIVE_OBJECTS("numactiveobjectsstat"), + NUM_NEW_OBJECTS("numnewobjectsstat"), + NUM_SIZE_CULLED("numsizeculledstat"), + NUM_VIS_CULLED("numvisculledstat"), + ENABLE_VBO("enablevbo", "Vertex Buffers Enabled"), + LIGHTING_DETAIL("lightingdetail", "Lighting Detail"), + VISIBLE_AVATARS("visibleavatars", "Visible Avatars"), + SHADER_OBJECTS("shaderobjects", "Object Shaders"), + DRAW_DISTANCE("drawdistance", "Draw Distance"), + CHAT_BUBBLES("chatbubbles", "Chat Bubbles Enabled"), + PENDING_VFS_OPERATIONS("vfspendingoperations"), + PACKETS_LOST_PERCENT("packetslostpercentstat"), + WINDOW_WIDTH("windowwidth", "Window width"), + WINDOW_HEIGHT("windowheight", "Window height"); -LLTrace::Measurement AGENT_POSITION_SNAP("agentpositionsnap", "agent position corrections"); +LLTrace::MeasurementStatHandle AGENT_POSITION_SNAP("agentpositionsnap", "agent position corrections"); -LLTrace::Measurement GL_TEX_MEM("gltexmemstat"), - GL_BOUND_MEM("glboundmemstat"), - RAW_MEM("rawmemstat"), - FORMATTED_MEM("formattedmemstat"), - DELTA_BANDWIDTH("deltabandwidth", "Increase/Decrease in bandwidth based on packet loss"), - MAX_BANDWIDTH("maxbandwidth", "Max bandwidth setting"); +LLTrace::MeasurementStatHandle GL_TEX_MEM("gltexmemstat"), + GL_BOUND_MEM("glboundmemstat"), + RAW_MEM("rawmemstat"), + FORMATTED_MEM("formattedmemstat"), + DELTA_BANDWIDTH("deltabandwidth", "Increase/Decrease in bandwidth based on packet loss"), + MAX_BANDWIDTH("maxbandwidth", "Max bandwidth setting"); SimMeasurement SIM_FRAME_TIME("simframemsec", "", LL_SIM_STAT_FRAMEMS), @@ -177,17 +177,17 @@ SimMeasurement SIM_UNACKED_BYTES("simtotalunackedbytes", "", LL_ SIM_PHYSICS_MEM("physicsmemoryallocated", "", LL_SIM_STAT_SIMPHYSICSMEMORY); -LLTrace::Measurement FRAMETIME_JITTER("frametimejitter", "Average delta between successive frame times"), - FRAMETIME_SLEW("frametimeslew", "Average delta between frame time and mean"), - LOGIN_SECONDS("loginseconds", "Time between LoginRequest and LoginReply"), - REGION_CROSSING_TIME("regioncrossingtime", "CROSSING_AVG"), - FRAME_STACKTIME("framestacktime", "FRAME_SECS"), - UPDATE_STACKTIME("updatestacktime", "UPDATE_SECS"), - NETWORK_STACKTIME("networkstacktime", "NETWORK_SECS"), - IMAGE_STACKTIME("imagestacktime", "IMAGE_SECS"), - REBUILD_STACKTIME("rebuildstacktime", "REBUILD_SECS"), - RENDER_STACKTIME("renderstacktime", "RENDER_SECS"), - SIM_PING("simpingstat"); +LLTrace::MeasurementStatHandle FRAMETIME_JITTER("frametimejitter", "Average delta between successive frame times"), + FRAMETIME_SLEW("frametimeslew", "Average delta between frame time and mean"), + LOGIN_SECONDS("loginseconds", "Time between LoginRequest and LoginReply"), + REGION_CROSSING_TIME("regioncrossingtime", "CROSSING_AVG"), + FRAME_STACKTIME("framestacktime", "FRAME_SECS"), + UPDATE_STACKTIME("updatestacktime", "UPDATE_SECS"), + NETWORK_STACKTIME("networkstacktime", "NETWORK_SECS"), + IMAGE_STACKTIME("imagestacktime", "IMAGE_SECS"), + REBUILD_STACKTIME("rebuildstacktime", "REBUILD_SECS"), + RENDER_STACKTIME("renderstacktime", "RENDER_SECS"), + SIM_PING("simpingstat"); } @@ -212,50 +212,50 @@ void LLViewerStats::updateFrameStats(const F64 time_diff) LLTrace::Seconds time_diff_seconds(time_diff); if (getRecording().getLastValue(LLStatViewer::PACKETS_LOST_PERCENT) > 5.0) { - LLStatViewer::LOSS_5_PERCENT_TIME.add(time_diff_seconds); + add(LLStatViewer::LOSS_5_PERCENT_TIME, time_diff_seconds); } F32 sim_fps = getRecording().getLastValue(LLStatViewer::SIM_FPS); if (0.f < sim_fps && sim_fps < 20.f) { - LLStatViewer::SIM_20_FPS_TIME.add(time_diff_seconds); + add(LLStatViewer::SIM_20_FPS_TIME, time_diff_seconds); } F32 sim_physics_fps = getRecording().getLastValue(LLStatViewer::SIM_PHYSICS_FPS); if (0.f < sim_physics_fps && sim_physics_fps < 20.f) { - LLStatViewer::SIM_PHYSICS_20_FPS_TIME.add(time_diff_seconds); + add(LLStatViewer::SIM_PHYSICS_20_FPS_TIME, time_diff_seconds); } if (time_diff >= 0.5) { - LLStatViewer::FPS_2_TIME.add(time_diff_seconds); + add(LLStatViewer::FPS_2_TIME, time_diff_seconds); } if (time_diff >= 0.125) { - LLStatViewer::FPS_8_TIME.add(time_diff_seconds); + add(LLStatViewer::FPS_8_TIME, time_diff_seconds); } if (time_diff >= 0.1) { - LLStatViewer::FPS_10_TIME.add(time_diff_seconds); + add(LLStatViewer::FPS_10_TIME, time_diff_seconds); } if (gFrameCount && mLastTimeDiff > 0.0) { // new "stutter" meter - LLStatViewer::FRAMETIME_DOUBLED.add(time_diff >= 2.0 * mLastTimeDiff ? 1 : 0); + add(LLStatViewer::FRAMETIME_DOUBLED, time_diff >= 2.0 * mLastTimeDiff ? 1 : 0); // old stats that were never really used - LLStatViewer::FRAMETIME_JITTER.sample(mLastTimeDiff - time_diff); + sample(LLStatViewer::FRAMETIME_JITTER, LLTrace::Milliseconds(mLastTimeDiff - time_diff)); F32 average_frametime = gRenderStartTime.getElapsedTimeF32() / (F32)gFrameCount; - LLStatViewer::FRAMETIME_SLEW.sample(average_frametime - time_diff); + sample(LLStatViewer::FRAMETIME_SLEW, LLTrace::Milliseconds(average_frametime - time_diff)); F32 max_bandwidth = gViewerThrottle.getMaxBandwidth(); F32 delta_bandwidth = gViewerThrottle.getCurrentBandwidth() - max_bandwidth; - LLStatViewer::DELTA_BANDWIDTH.sample(delta_bandwidth); - LLStatViewer::MAX_BANDWIDTH.sample(max_bandwidth); + sample(LLStatViewer::DELTA_BANDWIDTH, LLTrace::Bits(delta_bandwidth)); + sample(LLStatViewer::MAX_BANDWIDTH, LLTrace::Bits(max_bandwidth)); } mLastTimeDiff = time_diff; @@ -311,53 +311,53 @@ void update_statistics() { if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK) { - LLStatViewer::MOUSELOOK_TIME.add(gFrameIntervalSeconds); + add(LLStatViewer::MOUSELOOK_TIME, gFrameIntervalSeconds); } else if (gAgentCamera.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR) { - LLStatViewer::AVATAR_EDIT_TIME.add(gFrameIntervalSeconds); + add(LLStatViewer::AVATAR_EDIT_TIME, gFrameIntervalSeconds); } else if (LLFloaterReg::instanceVisible("build")) { - LLStatViewer::TOOLBOX_TIME.add(gFrameIntervalSeconds); + add(LLStatViewer::TOOLBOX_TIME, gFrameIntervalSeconds); } } - LLStatViewer::ENABLE_VBO.sample((F64)gSavedSettings.getBOOL("RenderVBOEnable")); - LLStatViewer::LIGHTING_DETAIL.sample((F64)gPipeline.getLightingDetail()); - LLStatViewer::DRAW_DISTANCE.sample((F64)gSavedSettings.getF32("RenderFarClip")); - LLStatViewer::CHAT_BUBBLES.sample((F64)gSavedSettings.getBOOL("UseChatBubbles")); + sample(LLStatViewer::ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable")); + sample(LLStatViewer::LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail()); + sample(LLStatViewer::DRAW_DISTANCE, (F64)gSavedSettings.getF32("RenderFarClip")); + sample(LLStatViewer::CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles")); - LLStatViewer::FRAME_STACKTIME.sample(gDebugView->mFastTimerView->getTime("Frame")); + sample(LLStatViewer::FRAME_STACKTIME, LLTrace::Seconds(gDebugView->mFastTimerView->getTime("Frame"))); F64 idle_secs = gDebugView->mFastTimerView->getTime("Idle"); F64 network_secs = gDebugView->mFastTimerView->getTime("Network"); - LLStatViewer::UPDATE_STACKTIME.sample(idle_secs - network_secs); - LLStatViewer::NETWORK_STACKTIME.sample(network_secs); - LLStatViewer::IMAGE_STACKTIME.sample(gDebugView->mFastTimerView->getTime("Update Images")); - LLStatViewer::REBUILD_STACKTIME.sample(gDebugView->mFastTimerView->getTime("Sort Draw State")); - LLStatViewer::RENDER_STACKTIME.sample(gDebugView->mFastTimerView->getTime("Geometry")); + sample(LLStatViewer::UPDATE_STACKTIME, LLTrace::Seconds(idle_secs - network_secs)); + sample(LLStatViewer::NETWORK_STACKTIME, LLTrace::Seconds(network_secs)); + sample(LLStatViewer::IMAGE_STACKTIME, LLTrace::Seconds(gDebugView->mFastTimerView->getTime("Update Images"))); + sample(LLStatViewer::REBUILD_STACKTIME, LLTrace::Seconds(gDebugView->mFastTimerView->getTime("Sort Draw State"))); + sample(LLStatViewer::RENDER_STACKTIME, LLTrace::Seconds(gDebugView->mFastTimerView->getTime("Geometry"))); LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost()); if (cdp) { - LLStatViewer::SIM_PING.sample(cdp->getPingDelay()); + sample(LLStatViewer::SIM_PING, LLTrace::Milliseconds(cdp->getPingDelay())); gAvgSimPing = ((gAvgSimPing * (F32)gSimPingCount) + (F32)(cdp->getPingDelay())) / ((F32)gSimPingCount + 1); gSimPingCount++; } else { - LLStatViewer::SIM_PING.sample(10); + sample(LLStatViewer::SIM_PING, LLTrace::Seconds(10)); } - LLStatViewer::FPS.add(1); + add(LLStatViewer::FPS, 1); if (LLTrace::get_frame_recording().getTotalRecording().getSampleCount(LLStatViewer::FPS)) { - LLStatViewer::FPS_SAMPLE.sample(LLTrace::get_frame_recording().getTotalRecording().getPerSec(LLStatViewer::FPS)); + sample(LLStatViewer::FPS_SAMPLE, LLTrace::get_frame_recording().getTotalRecording().getPerSec(LLStatViewer::FPS)); } F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits()); - LLStatViewer::LAYERS_KBIT.add(layer_bits); - LLStatViewer::OBJECT_KBIT.add(gObjectData); - LLStatViewer::PENDING_VFS_OPERATIONS.sample(LLVFile::getVFSThread()->getPending()); - LLStatViewer::ASSET_KBIT.add(gTransferManager.getTransferBitsIn(LLTCT_ASSET)); + add(LLStatViewer::LAYERS_KBIT, LLTrace::Bits(layer_bits)); + add(LLStatViewer::OBJECT_KBIT, gObjectData); + sample(LLStatViewer::PENDING_VFS_OPERATIONS, LLVFile::getVFSThread()->getPending()); + add(LLStatViewer::ASSET_KBIT, LLTrace::Bits(gTransferManager.getTransferBitsIn(LLTCT_ASSET))); gTransferManager.resetTransferBitsIn(LLTCT_ASSET); if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) @@ -378,7 +378,7 @@ void update_statistics() visible_avatar_frames = 1.f; avg_visible_avatars = (avg_visible_avatars * (F32)(visible_avatar_frames - 1.f) + visible_avatars) / visible_avatar_frames; } - LLStatViewer::VISIBLE_AVATARS.sample((F64)avg_visible_avatars); + sample(LLStatViewer::VISIBLE_AVATARS, (F64)avg_visible_avatars); } LLWorld::getInstance()->updateNetStats(); LLWorld::getInstance()->requestCacheMisses(); diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index 6b95c9359d..a82c64317e 100644 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -41,26 +41,21 @@ struct SimMeasurementSampler : public LLInstanceTracker(id) {} virtual ~SimMeasurementSampler() {} - virtual void sample(F64 value) = 0; }; template -struct SimMeasurement : public LLTrace::Measurement, public SimMeasurementSampler +struct SimMeasurement : public LLTrace::MeasurementStatHandle, public SimMeasurementSampler { SimMeasurement(const char* name, const char* description, ESimStatID stat_id) - : LLTrace::Measurement(name, description), + : LLTrace::MeasurementStatHandle(name, description), SimMeasurementSampler(stat_id) {} using SimMeasurementSampler::getInstance; - - /*virtual*/ void sample(F64 value) - { - LLTrace::Measurement::sample(T(value)); - } }; -extern LLTrace::Count<> FPS, + +extern LLTrace::CountStatHandle<> FPS, PACKETS_IN, PACKETS_LOST, PACKETS_OUT, @@ -87,7 +82,7 @@ extern LLTrace::Count<> FPS, TEX_REBAKES; -extern LLTrace::Count KBIT, +extern LLTrace::CountStatHandle KBIT, LAYERS_KBIT, OBJECT_KBIT, ASSET_KBIT, @@ -95,7 +90,7 @@ extern LLTrace::Count KBIT, ACTUAL_IN_KBIT, ACTUAL_OUT_KBIT; -extern LLTrace::Count AVATAR_EDIT_TIME, +extern LLTrace::CountStatHandle AVATAR_EDIT_TIME, TOOLBOX_TIME, MOUSELOOK_TIME, FPS_10_TIME, @@ -126,7 +121,7 @@ extern SimMeasurement<> SIM_TIME_DILATION, SIM_PHYSICS_PINNED_TASKS, SIM_PHYSICS_LOD_TASKS; -extern LLTrace::Measurement<> FPS_SAMPLE, +extern LLTrace::MeasurementStatHandle<> FPS_SAMPLE, NUM_IMAGES, NUM_RAW_IMAGES, NUM_OBJECTS, @@ -145,14 +140,14 @@ extern LLTrace::Measurement<> FPS_SAMPLE, WINDOW_WIDTH, WINDOW_HEIGHT; -extern LLTrace::Measurement AGENT_POSITION_SNAP; +extern LLTrace::MeasurementStatHandle AGENT_POSITION_SNAP; -extern LLTrace::Measurement DELTA_BANDWIDTH, - MAX_BANDWIDTH, - GL_TEX_MEM, - GL_BOUND_MEM, - RAW_MEM, - FORMATTED_MEM; +extern LLTrace::MeasurementStatHandle DELTA_BANDWIDTH, + MAX_BANDWIDTH, + GL_TEX_MEM, + GL_BOUND_MEM, + RAW_MEM, + FORMATTED_MEM; extern SimMeasurement SIM_FRAME_TIME, SIM_NET_TIME, @@ -173,7 +168,7 @@ extern SimMeasurement SIM_UNACKED_BYTES, SIM_PHYSICS_MEM; -extern LLTrace::Measurement FRAMETIME_JITTER, +extern LLTrace::MeasurementStatHandle FRAMETIME_JITTER, FRAMETIME_SLEW, LOGIN_SECONDS, REGION_CROSSING_TIME, diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 6f8b439049..899ef985ff 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -623,12 +623,12 @@ void LLViewerTextureList::updateImages(F32 max_time) { using namespace LLStatViewer; - NUM_IMAGES.sample(sNumImages); - NUM_RAW_IMAGES.sample(LLImageRaw::sRawImageCount); - GL_TEX_MEM.sample(LLImageGL::sGlobalTextureMemory); - GL_BOUND_MEM.sample(LLImageGL::sBoundTextureMemory); - RAW_MEM.sample(LLImageRaw::sGlobalRawMemory); - FORMATTED_MEM.sample(LLImageFormatted::sGlobalFormattedMemory); + sample(NUM_IMAGES, sNumImages); + sample(NUM_RAW_IMAGES, LLImageRaw::sRawImageCount); + sample(GL_TEX_MEM, LLImageGL::sGlobalTextureMemory); + sample(GL_BOUND_MEM, LLImageGL::sBoundTextureMemory); + sample(RAW_MEM, LLTrace::Bytes(LLImageRaw::sGlobalRawMemory)); + sample(FORMATTED_MEM, LLTrace::Bytes(LLImageFormatted::sGlobalFormattedMemory)); } { @@ -1324,8 +1324,8 @@ void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_d { received_size = msg->getReceiveSize() ; } - LLStatViewer::TEXTURE_KBIT.add(received_size); - LLStatViewer::TEXTURE_PACKETS.add(1); + add(LLStatViewer::TEXTURE_KBIT, LLTrace::Bytes(received_size)); + add(LLStatViewer::TEXTURE_PACKETS, 1); U8 codec; U16 packets; @@ -1398,8 +1398,8 @@ void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_d received_size = msg->getReceiveSize() ; } - LLStatViewer::TEXTURE_KBIT.add(received_size); - LLStatViewer::TEXTURE_PACKETS.add(1); + add(LLStatViewer::TEXTURE_KBIT, LLTrace::Bytes(received_size)); + add(LLStatViewer::TEXTURE_PACKETS, 1); //llprintline("Start decode, image header..."); msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 70792cd0a0..0bd0b2a769 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -248,7 +248,7 @@ std::string LLViewerWindow::sSnapshotDir; std::string LLViewerWindow::sMovieBaseName; -LLTrace::Measurement<> LLViewerWindow::sMouseVelocityStat("Mouse Velocity"); +LLTrace::MeasurementStatHandle<> LLViewerWindow::sMouseVelocityStat("Mouse Velocity"); class RecordToChatConsole : public LLError::Recorder, public LLSingleton @@ -2186,8 +2186,8 @@ void LLViewerWindow::reshape(S32 width, S32 height) } } - LLStatViewer::WINDOW_WIDTH.sample((F64)width); - LLStatViewer::WINDOW_HEIGHT.sample((F64)height); + sample(LLStatViewer::WINDOW_WIDTH, width); + sample(LLStatViewer::WINDOW_HEIGHT, height); LLLayoutStack::updateClass(); } @@ -3250,7 +3250,7 @@ void LLViewerWindow::updateMouseDelta() mouse_vel.setVec((F32) dx, (F32) dy); } - sMouseVelocityStat.sample(mouse_vel.magVec()); + sample(sMouseVelocityStat, mouse_vel.magVec()); } void LLViewerWindow::updateKeyboardFocus() diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index be2d6d885e..004a59fda5 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -250,7 +250,7 @@ public: S32 getCurrentMouseDX() const { return mCurrentMouseDelta.mX; } S32 getCurrentMouseDY() const { return mCurrentMouseDelta.mY; } LLCoordGL getCurrentMouseDelta() const { return mCurrentMouseDelta; } - static LLTrace::Measurement<>* getMouseVelocityStat() { return &sMouseVelocityStat; } + static LLTrace::MeasurementStatHandle<>* getMouseVelocityStat() { return &sMouseVelocityStat; } BOOL getLeftMouseDown() const { return mLeftMouseDown; } BOOL getMiddleMouseDown() const { return mMiddleMouseDown; } BOOL getRightMouseDown() const { return mRightMouseDown; } @@ -482,7 +482,7 @@ private: // Object temporarily hovered over while dragging LLPointer mDragHoveredObject; - static LLTrace::Measurement<> sMouseVelocityStat; + static LLTrace::MeasurementStatHandle<> sMouseVelocityStat; }; // diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index cd033c84bf..4ecb7f2fc7 100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -913,7 +913,7 @@ void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp) { ++mRegionCrossingCount; LLTrace::Seconds delta = mRegionCrossingTimer.getElapsedTimeF32(); - LLStatViewer::REGION_CROSSING_TIME.sample(delta); + sample(LLStatViewer::REGION_CROSSING_TIME, delta); // Diagnostics llinfos << "Region crossing took " << (F32)(delta * 1000.0).value() << " ms " << llendl; @@ -2583,7 +2583,7 @@ void LLVOAvatarSelf::processRebakeAvatarTextures(LLMessageSystem* msg, void**) llinfos << "TAT: rebake - matched entry " << (S32)index << llendl; gAgentAvatarp->invalidateComposite(layer_set, TRUE); found = TRUE; - LLStatViewer::TEX_REBAKES.add(1); + add(LLStatViewer::TEX_REBAKES, 1); } } } @@ -2628,7 +2628,7 @@ void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug) } invalidateComposite(layer_set, TRUE); - LLStatViewer::TEX_REBAKES.add(1); + add(LLStatViewer::TEX_REBAKES, 1); } else { diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 06e2302b0b..e088f94d64 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -720,15 +720,15 @@ void LLWorld::updateNetStats() S32 actual_in_bits = gMessageSystem->mPacketRing.getAndResetActualInBits(); S32 actual_out_bits = gMessageSystem->mPacketRing.getAndResetActualOutBits(); - LLStatViewer::ACTUAL_IN_KBIT.add(actual_in_bits); - LLStatViewer::ACTUAL_OUT_KBIT.add(actual_out_bits); - LLStatViewer::KBIT.add(bits); - LLStatViewer::PACKETS_IN.add(packets_in); - LLStatViewer::PACKETS_OUT.add(packets_out); - LLStatViewer::PACKETS_LOST.add(packets_lost); + add(LLStatViewer::ACTUAL_IN_KBIT, LLTrace::Bits(actual_in_bits)); + add(LLStatViewer::ACTUAL_OUT_KBIT, LLTrace::Bits(actual_out_bits)); + add(LLStatViewer::KBIT, LLTrace::Bits(bits)); + add(LLStatViewer::PACKETS_IN, packets_in); + add(LLStatViewer::PACKETS_OUT, packets_out); + add(LLStatViewer::PACKETS_LOST, packets_lost); if (packets_in) { - LLStatViewer::PACKETS_LOST_PERCENT.sample(100.f*((F32)packets_lost/(F32)packets_in)); + sample(LLStatViewer::PACKETS_LOST_PERCENT, 100.f * ((F32)packets_lost/(F32)packets_in)); } mLastPacketsIn = gMessageSystem->mPacketsIn; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 8d3075d1e1..355fa1350b 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1800,7 +1800,7 @@ void LLPipeline::resetFrameStats() { assertInitialized(); - LLStatViewer::TRIANGLES_DRAWN.add(mTrianglesDrawn); + add(LLStatViewer::TRIANGLES_DRAWN, mTrianglesDrawn); if (mBatchCount > 0) { @@ -9805,7 +9805,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) if (gen_shadow) { - LLTrace::Count<>* velocity_stat = LLViewerCamera::getVelocityStat(); + LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat(); F32 fade_amt = gFrameIntervalSeconds.value() * llmax(LLTrace::get_frame_recording().getLastRecordingPeriod().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecordingPeriod().getDuration().value(), 1.0); -- cgit v1.3 From 07ca6fce7c9cffe1b8f215f25bb826fedf57a5b7 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 10 Apr 2013 21:51:56 -0700 Subject: SH-3931 WIP Interesting: Add graphs to visualize scene load metrics removed PeriodicRecording::getTotalRecording as it was showing up at the top on the profiler renamed getPrevRecordingPeriod, etc. to getPrevRecording --- indra/llcommon/llfasttimer.cpp | 13 +++++---- indra/llcommon/lltracerecording.cpp | 55 +++++++++-------------------------- indra/llcommon/lltracerecording.h | 21 ++++++------- indra/llui/llstatbar.cpp | 37 ++++++++++------------- indra/llui/llstatgraph.cpp | 4 +-- indra/newview/llagentcamera.cpp | 2 +- indra/newview/llfasttimerview.cpp | 16 +++++----- indra/newview/llfloaterabout.cpp | 2 +- indra/newview/llhudnametag.cpp | 2 +- indra/newview/llviewerstats.cpp | 7 +++-- indra/newview/llviewertexturelist.cpp | 4 +-- indra/newview/pipeline.cpp | 2 +- 12 files changed, 65 insertions(+), 100 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index fbffe133f1..a7adcc6729 100644 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -176,11 +176,14 @@ TimeBlockTreeNode& TimeBlock::getTreeNode() const TimeBlockTreeNode* nodep = LLTrace::get_thread_recorder()->getTimeBlockTreeNode(getIndex()); llassert(nodep); return *nodep; - } +} + +static LLFastTimer::DeclareTimer FTM_PROCESS_TIMES("Process FastTimer Times"); //static void TimeBlock::processTimes() { + LLFastTimer _(FTM_PROCESS_TIMES); get_clock_count(); // good place to calculate clock frequency U64 cur_time = getCPUClockCount64(); @@ -329,12 +332,12 @@ void TimeBlock::logStats() { TimeBlock& timer = *it; LLTrace::PeriodicRecording& frame_recording = LLTrace::get_frame_recording(); - sd[timer.getName()]["Time"] = (LLSD::Real) (frame_recording.getLastRecordingPeriod().getSum(timer).value()); - sd[timer.getName()]["Calls"] = (LLSD::Integer) (frame_recording.getLastRecordingPeriod().getSum(timer.callCount())); + sd[timer.getName()]["Time"] = (LLSD::Real) (frame_recording.getLastRecording().getSum(timer).value()); + sd[timer.getName()]["Calls"] = (LLSD::Integer) (frame_recording.getLastRecording().getSum(timer.callCount())); // computing total time here because getting the root timer's getCountHistory // doesn't work correctly on the first frame - total_time += frame_recording.getLastRecordingPeriod().getSum(timer); + total_time += frame_recording.getLastRecording().getSum(timer); } } @@ -353,7 +356,7 @@ void TimeBlock::logStats() void TimeBlock::dumpCurTimes() { LLTrace::PeriodicRecording& frame_recording = LLTrace::get_frame_recording(); - LLTrace::Recording& last_frame_recording = frame_recording.getLastRecordingPeriod(); + LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording(); // walk over timers in depth order and output timings for(timer_tree_dfs_iterator_t it = begin_timer_tree(TimeBlock::getRootTimeBlock()); diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index f78b7942a7..21156b4d61 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -360,8 +360,7 @@ U32 Recording::getSampleCount( const TraceType >& st PeriodicRecording::PeriodicRecording( U32 num_periods, EPlayState state) : mAutoResize(num_periods == 0), - mCurPeriod(0), - mTotalValid(false) + mCurPeriod(0) { if (num_periods) { @@ -373,7 +372,7 @@ PeriodicRecording::PeriodicRecording( U32 num_periods, EPlayState state) void PeriodicRecording::nextPeriod() { EPlayState play_state = getPlayState(); - Recording& old_recording = getCurRecordingPeriod(); + Recording& old_recording = getCurRecording(); if (mAutoResize) { mRecordingPeriods.push_back(Recording()); @@ -382,87 +381,59 @@ void PeriodicRecording::nextPeriod() mCurPeriod = (num_periods > 0) ? (mCurPeriod + 1) % num_periods : mCurPeriod + 1; - old_recording.splitTo(getCurRecordingPeriod()); + old_recording.splitTo(getCurRecording()); switch(play_state) { case STOPPED: - getCurRecordingPeriod().stop(); + getCurRecording().stop(); break; case PAUSED: - getCurRecordingPeriod().pause(); + getCurRecording().pause(); break; case STARTED: break; } - // new period, need to recalculate total - mTotalValid = false; -} - -Recording& PeriodicRecording::getTotalRecording() -{ - if (!mTotalValid) - { - mTotalRecording.reset(); - U32 num_periods = mRecordingPeriods.size(); - - if (num_periods) - { - for (S32 i = mCurPeriod + 1; i < mCurPeriod + num_periods; i++) - { - mTotalRecording.appendRecording(mRecordingPeriods[i % num_periods]); - } - } - else - { - for (S32 i = 0; i < mCurPeriod; i++) - { - mTotalRecording.appendRecording(mRecordingPeriods[i]); - } - } - } - mTotalValid = true; - return mTotalRecording; } void PeriodicRecording::start() { - getCurRecordingPeriod().start(); + getCurRecording().start(); } void PeriodicRecording::stop() { - getCurRecordingPeriod().stop(); + getCurRecording().stop(); } void PeriodicRecording::pause() { - getCurRecordingPeriod().pause(); + getCurRecording().pause(); } void PeriodicRecording::resume() { - getCurRecordingPeriod().resume(); + getCurRecording().resume(); } void PeriodicRecording::restart() { - getCurRecordingPeriod().restart(); + getCurRecording().restart(); } void PeriodicRecording::reset() { - getCurRecordingPeriod().reset(); + getCurRecording().reset(); } void PeriodicRecording::splitTo(PeriodicRecording& other) { - getCurRecordingPeriod().splitTo(other.getCurRecordingPeriod()); + getCurRecording().splitTo(other.getCurRecording()); } void PeriodicRecording::splitFrom(PeriodicRecording& other) { - getCurRecordingPeriod().splitFrom(other.getCurRecordingPeriod()); + getCurRecording().splitFrom(other.getCurRecording()); } diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index b96d0666e5..0a3e9e5a0b 100644 --- a/indra/llcommon/lltracerecording.h +++ b/indra/llcommon/lltracerecording.h @@ -254,50 +254,48 @@ namespace LLTrace void nextPeriod(); U32 getNumPeriods() { return mRecordingPeriods.size(); } - Recording& getLastRecordingPeriod() + Recording& getLastRecording() { U32 num_periods = mRecordingPeriods.size(); return mRecordingPeriods[(mCurPeriod + num_periods - 1) % num_periods]; } - const Recording& getLastRecordingPeriod() const + const Recording& getLastRecording() const { - return getPrevRecordingPeriod(1); + return getPrevRecording(1); } - Recording& getCurRecordingPeriod() + Recording& getCurRecording() { return mRecordingPeriods[mCurPeriod]; } - const Recording& getCurRecordingPeriod() const + const Recording& getCurRecording() const { return mRecordingPeriods[mCurPeriod]; } - Recording& getPrevRecordingPeriod(U32 offset) + Recording& getPrevRecording(U32 offset) { U32 num_periods = mRecordingPeriods.size(); offset = llclamp(offset, 0u, num_periods - 1); return mRecordingPeriods[(mCurPeriod + num_periods - offset) % num_periods]; } - const Recording& getPrevRecordingPeriod(U32 offset) const + const Recording& getPrevRecording(U32 offset) const { U32 num_periods = mRecordingPeriods.size(); offset = llclamp(offset, 0u, num_periods - 1); return mRecordingPeriods[(mCurPeriod + num_periods - offset) % num_periods]; } - Recording snapshotCurRecordingPeriod() const + Recording snapshotCurRecording() const { - Recording recording_copy(getCurRecordingPeriod()); + Recording recording_copy(getCurRecording()); recording_copy.stop(); return recording_copy; } - Recording& getTotalRecording(); - template typename T::value_t getPeriodMin(const TraceType& stat) const { @@ -391,7 +389,6 @@ namespace LLTrace private: std::vector mRecordingPeriods; Recording mTotalRecording; - bool mTotalValid; const bool mAutoResize; S32 mCurPeriod; }; diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp index d9f3d14ef0..46eea368e5 100644 --- a/indra/llui/llstatbar.cpp +++ b/indra/llui/llstatbar.cpp @@ -103,12 +103,11 @@ void LLStatBar::draw() max = 0.f, mean = 0.f; - S32 num_samples = 0; LLTrace::PeriodicRecording& frame_recording = LLTrace::get_frame_recording(); if (mCountFloatp) { - LLTrace::Recording& last_frame_recording = frame_recording.getLastRecordingPeriod(); + LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording(); if (mPerSec) { @@ -116,7 +115,6 @@ void LLStatBar::draw() min = frame_recording.getPeriodMinPerSec(*mCountFloatp); max = frame_recording.getPeriodMaxPerSec(*mCountFloatp); mean = frame_recording.getPeriodMeanPerSec(*mCountFloatp); - num_samples = frame_recording.getTotalRecording().getSampleCount(*mCountFloatp); } else { @@ -124,12 +122,11 @@ void LLStatBar::draw() min = frame_recording.getPeriodMin(*mCountFloatp); max = frame_recording.getPeriodMax(*mCountFloatp); mean = frame_recording.getPeriodMean(*mCountFloatp); - num_samples = frame_recording.getTotalRecording().getSampleCount(*mCountFloatp); } } else if (mCountIntp) { - LLTrace::Recording& last_frame_recording = frame_recording.getLastRecordingPeriod(); + LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording(); if (mPerSec) { @@ -137,7 +134,6 @@ void LLStatBar::draw() min = frame_recording.getPeriodMinPerSec(*mCountIntp); max = frame_recording.getPeriodMaxPerSec(*mCountIntp); mean = frame_recording.getPeriodMeanPerSec(*mCountIntp); - num_samples = frame_recording.getTotalRecording().getSampleCount(*mCountIntp); } else { @@ -145,26 +141,25 @@ void LLStatBar::draw() min = frame_recording.getPeriodMin(*mCountIntp); max = frame_recording.getPeriodMax(*mCountIntp); mean = frame_recording.getPeriodMean(*mCountIntp); - num_samples = frame_recording.getTotalRecording().getSampleCount(*mCountIntp); } } else if (mMeasurementFloatp) { - LLTrace::Recording& recording = frame_recording.getTotalRecording(); - current = recording.getLastValue(*mMeasurementFloatp); - min = recording.getMin(*mMeasurementFloatp); - max = recording.getMax(*mMeasurementFloatp); - mean = recording.getMean(*mMeasurementFloatp); - num_samples = frame_recording.getTotalRecording().getSampleCount(*mMeasurementFloatp); + LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording(); + + current = last_frame_recording.getLastValue(*mMeasurementFloatp); + min = frame_recording.getPeriodMin(*mMeasurementFloatp); + max = frame_recording.getPeriodMax(*mMeasurementFloatp); + mean = frame_recording.getPeriodMean(*mMeasurementFloatp); } else if (mMeasurementIntp) { - LLTrace::Recording& recording = frame_recording.getTotalRecording(); - current = recording.getLastValue(*mMeasurementIntp); - min = recording.getMin(*mMeasurementIntp); - max = recording.getMax(*mMeasurementIntp); - mean = recording.getMean(*mMeasurementIntp); - num_samples = frame_recording.getTotalRecording().getSampleCount(*mMeasurementIntp); + LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording(); + + current = last_frame_recording.getLastValue(*mMeasurementIntp); + min = frame_recording.getPeriodMin(*mMeasurementIntp); + max = frame_recording.getPeriodMax(*mMeasurementIntp); + mean = frame_recording.getPeriodMean(*mMeasurementIntp); } current *= mUnitScale; @@ -203,7 +198,7 @@ void LLStatBar::draw() const S32 tick_length = 4; const S32 tick_width = 1; - if (mScaleRange && num_samples) + if (mScaleRange && min < max) { F32 cur_max = mTickSpacing; while(max > cur_max && mMaxBar > cur_max) @@ -352,7 +347,7 @@ void LLStatBar::draw() for (i = 1; i <= max_frame; i++) { F32 offset = ((F32)i / (F32)mNumFrames) * span; - LLTrace::Recording& recording = frame_recording.getPrevRecordingPeriod(i); + LLTrace::Recording& recording = frame_recording.getPrevRecording(i); if (mPerSec) { if (mCountFloatp) diff --git a/indra/llui/llstatgraph.cpp b/indra/llui/llstatgraph.cpp index bdb378c9c5..af01e66095 100644 --- a/indra/llui/llstatgraph.cpp +++ b/indra/llui/llstatgraph.cpp @@ -66,7 +66,7 @@ void LLStatGraph::draw() range = mMax - mMin; if (mNewStatFloatp) { - LLTrace::Recording& recording = LLTrace::get_frame_recording().getLastRecordingPeriod(); + LLTrace::Recording& recording = LLTrace::get_frame_recording().getLastRecording(); if (mPerSec) { @@ -79,7 +79,7 @@ void LLStatGraph::draw() } else if (mNewStatIntp) { - LLTrace::Recording& recording = LLTrace::get_frame_recording().getLastRecordingPeriod(); + LLTrace::Recording& recording = LLTrace::get_frame_recording().getLastRecording(); if (mPerSec) { diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 420220d21a..7c9fbccd7f 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -1082,7 +1082,7 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y) LLQuaternion av_inv_rot = ~gAgentAvatarp->mRoot.getWorldRotation(); LLVector3 root_at = LLVector3::x_axis * gAgentAvatarp->mRoot.getWorldRotation(); - if (LLTrace::get_frame_recording().getLastRecordingPeriod().getLastValue(*gViewerWindow->getMouseVelocityStat()) < 0.01f + if (LLTrace::get_frame_recording().getLastRecording().getLastValue(*gViewerWindow->getMouseVelocityStat()) < 0.01f && (root_at * last_at_axis > 0.95f)) { LLVector3 vel = gAgentAvatarp->getVelocity(); diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 80d845c70e..45ffe56ac1 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -333,7 +333,7 @@ static std::string get_tooltip(TimeBlock& timer, S32 history_index, PeriodicReco } else { - tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)LLUnit(frame_recording.getPrevRecordingPeriod(history_index).getSum(timer)).value(), (S32)frame_recording.getPrevRecordingPeriod(history_index).getSum(timer.callCount())); + tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)LLUnit(frame_recording.getPrevRecording(history_index).getSum(timer)).value(), (S32)frame_recording.getPrevRecording(history_index).getSum(timer.callCount())); } return tooltip; } @@ -417,7 +417,7 @@ void LLFastTimerView::draw() printLineStats(); LLView::draw(); - mAllTimeMax = llmax(mAllTimeMax, mRecording->getLastRecordingPeriod().getSum(FTM_FRAME)); + mAllTimeMax = llmax(mAllTimeMax, mRecording->getLastRecording().getSum(FTM_FRAME)); mHoverID = NULL; mHoverBarIndex = -1; } @@ -984,7 +984,7 @@ void LLFastTimerView::printLineStats() LLUnit ticks; if (mPrintStats > 0) { - ticks = mRecording->getPrevRecordingPeriod(mPrintStats).getSum(*idp); + ticks = mRecording->getPrevRecording(mPrintStats).getSum(*idp); } else { @@ -1096,8 +1096,8 @@ void LLFastTimerView::drawLineGraph() j > 0; j--) { - LLUnit time = llmax(mRecording->getPrevRecordingPeriod(j).getSum(*idp), LLUnit(0.000001)); - U32 calls = mRecording->getPrevRecordingPeriod(j).getSum(idp->callCount()); + LLUnit time = llmax(mRecording->getPrevRecording(j).getSum(*idp), LLUnit(0.000001)); + U32 calls = mRecording->getPrevRecording(j).getSum(idp->callCount()); if (alpha == 1.f) { @@ -1197,8 +1197,8 @@ void LLFastTimerView::drawLegend( S32 y ) if (mHoverBarIndex > 0 && mHoverID) { S32 hidx = mScrollIndex + mHoverBarIndex; - ms = mRecording->getPrevRecordingPeriod(hidx).getSum(*idp); - calls = mRecording->getPrevRecordingPeriod(hidx).getSum(idp->callCount()); + ms = mRecording->getPrevRecording(hidx).getSum(*idp); + calls = mRecording->getPrevRecording(hidx).getSum(idp->callCount()); } else { @@ -1455,7 +1455,7 @@ S32 LLFastTimerView::updateTimerBarWidths(LLTrace::TimeBlock* time_block, std::v LLFastTimer _(FTM_UPDATE_TIMER_BAR_WIDTHS); F32 self_time_frame_fraction = history_index == -1 ? (mRecording->getPeriodMean(time_block->selfTime()) / mTotalTimeDisplay) - : (mRecording->getPrevRecordingPeriod(history_index).getSum(time_block->selfTime()) / mTotalTimeDisplay); + : (mRecording->getPrevRecording(history_index).getSum(time_block->selfTime()) / mTotalTimeDisplay); S32 self_time_width = llround(self_time_frame_fraction * (F32)mBarRect.getWidth()); S32 full_width = self_time_width; diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 58701ca3c9..93502daac7 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -296,7 +296,7 @@ LLSD LLFloaterAbout::getInfo() if (gPacketsIn > 0) { - LLTrace::Recording cur_frame = LLTrace::get_frame_recording().snapshotCurRecordingPeriod(); + LLTrace::Recording cur_frame = LLTrace::get_frame_recording().snapshotCurRecording(); info["PACKETS_LOST"] = cur_frame.getSum(LLStatViewer::PACKETS_LOST); info["PACKETS_IN"] = F32(gPacketsIn); info["PACKETS_PCT"] = 100.f*info["PACKETS_LOST"].asReal() / info["PACKETS_IN"].asReal(); diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index 3ac11f906b..cdfe776589 100644 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -901,7 +901,7 @@ void LLHUDNameTag::updateAll() } LLTrace::CountStatHandle<>* camera_vel_stat = LLViewerCamera::getVelocityStat(); - F32 camera_vel = LLTrace::get_frame_recording().getLastRecordingPeriod().getPerSec(*camera_vel_stat); + F32 camera_vel = LLTrace::get_frame_recording().getLastRecording().getPerSec(*camera_vel_stat); if (camera_vel > MAX_STABLE_CAMERA_VELOCITY) { return; diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index fa4eb73180..13a005dcbf 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -348,11 +348,12 @@ void update_statistics() sample(LLStatViewer::SIM_PING, LLTrace::Seconds(10)); } - add(LLStatViewer::FPS, 1); - if (LLTrace::get_frame_recording().getTotalRecording().getSampleCount(LLStatViewer::FPS)) + if (LLViewerStats::instance().getRecording().getSum(LLStatViewer::FPS)) { - sample(LLStatViewer::FPS_SAMPLE, LLTrace::get_frame_recording().getTotalRecording().getPerSec(LLStatViewer::FPS)); + sample(LLStatViewer::FPS_SAMPLE, LLTrace::get_frame_recording().getPeriodMeanPerSec(LLStatViewer::FPS)); } + add(LLStatViewer::FPS, 1); + F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits()); add(LLStatViewer::LAYERS_KBIT, LLTrace::Bits(layer_bits)); add(LLStatViewer::OBJECT_KBIT, gObjectData); diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 0066c09720..1bb4041bbd 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -617,9 +617,7 @@ void LLViewerTextureList::updateImages(F32 max_time) } cleared = FALSE; - LLTrace::Recording& recording = LLTrace::get_frame_recording().getTotalRecording(); - - LLAppViewer::getTextureFetch()->setTextureBandwidth(recording.getPerSec(LLStatViewer::TEXTURE_KBIT).value()); + LLAppViewer::getTextureFetch()->setTextureBandwidth(LLTrace::get_frame_recording().getPeriodMeanPerSec(LLStatViewer::TEXTURE_KBIT).value()); { using namespace LLStatViewer; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 26ceaf512a..1b5148e560 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -9816,7 +9816,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) { LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat(); F32 fade_amt = gFrameIntervalSeconds.value() - * llmax(LLTrace::get_frame_recording().getLastRecordingPeriod().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecordingPeriod().getDuration().value(), 1.0); + * llmax(LLTrace::get_frame_recording().getLastRecording().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecording().getDuration().value(), 1.0); //update shadow targets for (U32 i = 0; i < 2; i++) -- cgit v1.3 From 34403a6138922da2d97c24b8413e3693ab1d788f Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 2 May 2013 13:02:16 -0700 Subject: SH-4080 WIP interesting: random crash on Mac changed sCurCameraID to enum in attempt to pinpoint memory stompage --- indra/newview/llviewercamera.cpp | 2 +- indra/newview/llviewercamera.h | 2 +- indra/newview/pipeline.cpp | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index 1f5bdc8589..45302ebb74 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -57,7 +57,7 @@ LLTrace::CountStatHandle<> LLViewerCamera::sVelocityStat("camera_velocity"); LLTrace::CountStatHandle<> LLViewerCamera::sAngularVelocityStat("camera_angular_velocity"); -U32 LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; +LLViewerCamera::eCameraID LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; //glu pick matrix implementation borrowed from Mesa3D glh::matrix4f gl_pick_matrix(GLfloat x, GLfloat y, GLfloat width, GLfloat height, GLint* viewport) diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h index d7835d8567..7b2887d725 100644 --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -80,7 +80,7 @@ public: NUM_CAMERAS } eCameraID; - static U32 sCurCameraID; + static eCameraID sCurCameraID; LLViewerCamera(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 1b5148e560..acf3e7aa07 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2252,7 +2252,7 @@ BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& min = LLVector3(X,X,X); max = LLVector3(-X,-X,-X); - U32 saved_camera_id = LLViewerCamera::sCurCameraID; + LLViewerCamera::eCameraID saved_camera_id = LLViewerCamera::sCurCameraID; LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; BOOL res = TRUE; @@ -9437,7 +9437,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mShadowFrustPoints[j].clear(); } - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+j; + LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0+j); //restore render matrices glh_set_current_modelview(saved_view); @@ -9821,7 +9821,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) //update shadow targets for (U32 i = 0; i < 2; i++) { //for each current shadow - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i; + LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW4+i); if (mShadowSpotLight[i].notNull() && (mShadowSpotLight[i] == mTargetShadowSpotLight[0] || @@ -9940,7 +9940,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) static LLCullResult result[2]; - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4; + LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0 + i + 4); renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE, target_width); -- cgit v1.3 From f850ae03b399a5cc7aa32f82b8ed996518a86a2a Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 20 May 2013 00:01:57 -0700 Subject: SH-3931 WIP Interesting: Add graphs to visualize scene load metrics fixed copy construction of Recorders, eliminated most zero-length frames fixed reset behavior of periodic recordings and extendable recordings to clear entire history removed busy-loop recording of stats from worker threads...stats reported only when work is done --- indra/llcommon/llqueuedthread.cpp | 11 ++++++----- indra/llcommon/lltracerecording.cpp | 38 +++++++++++++++++++++++++++---------- indra/newview/llscenemonitor.cpp | 4 ++-- indra/newview/llviewerdisplay.cpp | 2 ++ indra/newview/pipeline.cpp | 2 -- 5 files changed, 38 insertions(+), 19 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index 956642e97a..4339f203db 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -404,6 +404,7 @@ S32 LLQueuedThread::processNextRequest() QueuedRequest *req; // Get next request from pool lockData(); + while(1) { req = NULL; @@ -468,10 +469,11 @@ S32 LLQueuedThread::processNextRequest() ms_sleep(1); // sleep the thread a little } } + + LLTrace::get_thread_recorder()->pushToMaster(); } S32 pending = getPending(); - return pending; } @@ -500,6 +502,7 @@ void LLQueuedThread::run() if (isQuitting()) { + LLTrace::get_thread_recorder()->pushToMaster(); endThread(); break; } @@ -508,11 +511,9 @@ void LLQueuedThread::run() threadedUpdate(); - int res = processNextRequest(); - - LLTrace::get_thread_recorder()->pushToMaster(); + int pending_work = processNextRequest(); - if (res == 0) + if (pending_work == 0) { mIdleThread = TRUE; ms_sleep(1); diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index 6b5c6c7d3e..4aa3a5a0f7 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -133,11 +133,19 @@ Recording::Recording() {} Recording::Recording( const Recording& other ) -: RecordingBuffers(other), - mElapsedSeconds(other.mElapsedSeconds), - mSamplingTimer(other.mSamplingTimer) +: mSamplingTimer(other.mSamplingTimer) { - LLStopWatchControlsMixin::setPlayState(other.getPlayState()); + Recording& mutable_other = const_cast(other); + EPlayState other_play_state = other.getPlayState(); + mutable_other.pause(); + + appendBuffers(other); + + LLStopWatchControlsMixin::setPlayState(other_play_state); + mutable_other.setPlayState(other_play_state); + + // above call will clear mElapsedSeconds as a side effect, so copy it here + mElapsedSeconds = other.mElapsedSeconds; } @@ -380,9 +388,7 @@ void PeriodicRecording::nextPeriod() Recording& old_recording = getCurRecording(); - mCurPeriod = mRecordingPeriods.empty() - ? mCurPeriod + 1 - : (mCurPeriod + 1) % mRecordingPeriods.size(); + mCurPeriod = (mCurPeriod + 1) % mRecordingPeriods.size(); old_recording.splitTo(getCurRecording()); } @@ -526,9 +532,22 @@ void PeriodicRecording::handleStop() void PeriodicRecording::handleReset() { - mRecordingPeriods.clear(); - mRecordingPeriods.push_back(Recording()); + if (mAutoResize) + { + mRecordingPeriods.clear(); + mRecordingPeriods.push_back(Recording()); + } + else + { + for (std::vector::iterator it = mRecordingPeriods.begin(), end_it = mRecordingPeriods.end(); + it != end_it; + ++it) + { + it->reset(); + } + } mCurPeriod = 0; + getCurRecording().setPlayState(getPlayState()); } void PeriodicRecording::handleSplitTo(PeriodicRecording& other) @@ -656,7 +675,6 @@ void LLStopWatchControlsMixinCommon::stop() case STOPPED: break; case PAUSED: - handleStop(); break; case STARTED: handleStop(); diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp index c101fe7deb..c2e00384a1 100644 --- a/indra/newview/llscenemonitor.cpp +++ b/indra/newview/llscenemonitor.cpp @@ -481,13 +481,13 @@ void LLSceneMonitor::fetchQueryResult() LL_DEBUGS("SceneMonitor") << "Frame difference: " << std::setprecision(4) << mDiffResult << LL_ENDL; sample(sFramePixelDiff, mDiffResult); - mRecording->getPotentialRecording().nextPeriod(); - static LLCachedControl diff_threshold(gSavedSettings,"SceneLoadingPixelDiffThreshold"); if(mDiffResult > diff_threshold()) { mRecording->extend(); } + + mRecording->getPotentialRecording().nextPeriod(); } } } diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 970862892c..5974c84596 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -803,6 +803,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) } } + LLSceneMonitor::getInstance()->fetchQueryResult(); + LLGLState::checkStates(); LLGLState::checkClientArrays(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index acf3e7aa07..3f6269e768 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -3233,8 +3233,6 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } postSort(camera); - - LLSceneMonitor::getInstance()->fetchQueryResult(); } void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) -- cgit v1.3 From 16616ae48d86da75b3809fa6be6c846a9d420603 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Thu, 23 May 2013 18:25:21 -0600 Subject: for SH-4145: Interesting: Implement occlusion culling for object cache --- indra/newview/llappviewer.cpp | 31 +- indra/newview/llappviewer.h | 3 +- indra/newview/lldrawable.cpp | 2 +- indra/newview/lldrawpoolalpha.cpp | 10 +- indra/newview/llscenemonitor.cpp | 4 +- indra/newview/llspatialpartition.cpp | 678 ++--------------------------------- indra/newview/llspatialpartition.h | 79 +--- indra/newview/llvieweroctree.cpp | 620 +++++++++++++++++++++++++++++++- indra/newview/llvieweroctree.h | 99 ++++- indra/newview/llviewerwindow.cpp | 4 +- indra/newview/llvocache.cpp | 41 ++- indra/newview/llvovolume.cpp | 12 +- indra/newview/pipeline.cpp | 16 +- 13 files changed, 845 insertions(+), 754 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 0b0db432c8..cb813ea889 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1415,18 +1415,7 @@ bool LLAppViewer::mainLoop() S32 io_pending = 0; F32 max_time = llmin(gFrameIntervalSeconds.value() *10.f, 1.f); - { - LLFastTimer ftm(FTM_TEXTURE_CACHE); - work_pending += LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread - } - { - LLFastTimer ftm(FTM_DECODE); - work_pending += LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread - } - { - LLFastTimer ftm(FTM_DECODE); - work_pending += LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread - } + work_pending += updateTextureThreads(max_time); { LLFastTimer ftm(FTM_VFS); @@ -1544,6 +1533,24 @@ bool LLAppViewer::mainLoop() return true; } +S32 LLAppViewer::updateTextureThreads(F32 max_time) +{ + S32 work_pending = 0; + { + LLFastTimer ftm(FTM_TEXTURE_CACHE); + work_pending += LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread + } + { + LLFastTimer ftm(FTM_DECODE); + work_pending += LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread + } + { + LLFastTimer ftm(FTM_DECODE); + work_pending += LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread + } + return work_pending; +} + void LLAppViewer::flushVFSIO() { while (1) diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 627652dc30..30e208d01c 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -171,7 +171,8 @@ public: void purgeCache(); // Clear the local cache. void purgeCacheImmediate(); //clear local cache immediately. - + S32 updateTextureThreads(F32 max_time); + // mute/unmute the system's master audio virtual void setMasterSystemAudioMute(bool mute); virtual bool getMasterSystemAudioMute(); diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 4d72dd1343..17f610829d 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -1145,7 +1145,7 @@ LLSpatialBridge::~LLSpatialBridge() LLSpatialGroup* group = getSpatialGroup(); if (group) { - group->mSpatialPartition->remove(this, group); + group->getSpatialPartition()->remove(this, group); } } diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 313b310e1e..7020db917b 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -351,7 +351,7 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask) for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) { LLSpatialGroup* group = *i; - if (group->mSpatialPartition->mRenderByGroup && + if (group->getSpatialPartition()->mRenderByGroup && !group->isDead()) { LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA]; @@ -389,15 +389,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) { LLSpatialGroup* group = *i; llassert(group); - llassert(group->mSpatialPartition); + llassert(group->getSpatialPartition()); - if (group->mSpatialPartition->mRenderByGroup && + if (group->getSpatialPartition()->mRenderByGroup && !group->isDead()) { bool draw_glow_for_this_partition = mVertexShaderLevel > 0 && // no shaders = no glow. // All particle systems seem to come off the wire with texture entries which claim that they glow. This is probably a bug in the data. Suppress. - group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_PARTICLE && - group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD_PARTICLE; + group->getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_PARTICLE && + group->getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_HUD_PARTICLE; LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA]; diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp index 15fe77f028..c592fd0a38 100644 --- a/indra/newview/llscenemonitor.cpp +++ b/indra/newview/llscenemonitor.cpp @@ -107,7 +107,7 @@ void LLSceneMonitor::reset() if(mQueryObject > 0) { - release_occlusion_query_object_name(mQueryObject); + LLOcclusionCullingGroup::releaseOcclusionQueryObjectName(mQueryObject); mQueryObject = 0; } } @@ -437,7 +437,7 @@ void LLSceneMonitor::calcDiffAggregate() if(!mQueryObject) { - mQueryObject = get_new_occlusion_query_object_name(); + mQueryObject = LLOcclusionCullingGroup::getNewOcclusionQueryObjectName(); } LLGLDepthTest depth(true, false, GL_ALWAYS); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 53f5658815..3f426d8f8a 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -51,32 +51,16 @@ #include "llvoavatar.h" #include "llvolumemgr.h" #include "lltextureatlas.h" -#include "llglslshader.h" #include "llviewershadermgr.h" static LLFastTimer::DeclareTimer FTM_FRUSTUM_CULL("Frustum Culling"); static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound Partition"); -const F32 SG_OCCLUSION_FUDGE = 0.25f; -#define SG_DISCARD_TOLERANCE 0.01f - -#if LL_OCTREE_PARANOIA_CHECK -#define assert_octree_valid(x) x->validate() -#define assert_states_valid(x) ((LLSpatialGroup*) x->mSpatialPartition->mOctree->getListener(0))->checkStates() -#else -#define assert_octree_valid(x) -#define assert_states_valid(x) -#endif - extern bool gShiftFrame; static U32 sZombieGroups = 0; U32 LLSpatialGroup::sNodeCount = 0; -#define LL_TRACK_PENDING_OCCLUSION_QUERIES 0 - -std::set LLSpatialGroup::sPendingQueries; - U32 gOctreeMaxCapacity; BOOL LLSpatialGroup::sNoDelete = FALSE; @@ -84,57 +68,6 @@ BOOL LLSpatialGroup::sNoDelete = FALSE; static F32 sLastMaxTexPriority = 1.f; static F32 sCurMaxTexPriority = 1.f; -class LLOcclusionQueryPool : public LLGLNamePool -{ -public: - LLOcclusionQueryPool() - { - mCurQuery = 1; - } - -protected: - - std::list mAvailableName; - GLuint mCurQuery; - - virtual GLuint allocateName() - { - GLuint ret = 0; - - if (!mAvailableName.empty()) - { - ret = mAvailableName.front(); - mAvailableName.pop_front(); - } - else - { - ret = mCurQuery++; - } - - return ret; - } - - virtual void releaseName(GLuint name) - { -#if LL_TRACK_PENDING_OCCLUSION_QUERIES - LLSpatialGroup::sPendingQueries.erase(name); -#endif - llassert(std::find(mAvailableName.begin(), mAvailableName.end(), name) == mAvailableName.end()); - mAvailableName.push_back(name); - } -}; - -static LLOcclusionQueryPool sQueryPool; - -GLuint get_new_occlusion_query_object_name() -{ - return sQueryPool.allocate(); -} - -void release_occlusion_query_object_name(GLuint name) -{ - sQueryPool.release(name); -} //static counter for frame to switch LOD on @@ -148,97 +81,6 @@ void sg_assert(BOOL expr) #endif } -typedef enum -{ - b000 = 0x00, - b001 = 0x01, - b010 = 0x02, - b011 = 0x03, - b100 = 0x04, - b101 = 0x05, - b110 = 0x06, - b111 = 0x07, -} eLoveTheBits; - -//contact Runitai Linden for a copy of the SL object used to write this table -//basically, you give the table a bitmask of the look-at vector to a node and it -//gives you a triangle fan index array -static U16 sOcclusionIndices[] = -{ - //000 - b111, b110, b010, b011, b001, b101, b100, b110, - //001 - b011, b010, b000, b001, b101, b111, b110, b010, - //010 - b101, b100, b110, b111, b011, b001, b000, b100, - //011 - b001, b000, b100, b101, b111, b011, b010, b000, - //100 - b110, b000, b010, b011, b111, b101, b100, b000, - //101 - b010, b100, b000, b001, b011, b111, b110, b100, - //110 - b100, b010, b110, b111, b101, b001, b000, b010, - //111 - b000, b110, b100, b101, b001, b011, b010, b110, -}; - -U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center) -{ - LLVector4a origin; - origin.load3(camera->getOrigin().mV); - - S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7; - - return cypher*8; -} - -U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center) -{ - LLVector4a origin; - origin.load3(camera->getOrigin().mV); - - S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7; - - return (U8*) (sOcclusionIndices+cypher*8); -} - -//create a vertex buffer for efficiently rendering cubes -LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage) -{ - LLVertexBuffer* ret = new LLVertexBuffer(type_mask, usage); - - ret->allocateBuffer(8, 64, true); - - LLStrider pos; - LLStrider idx; - - ret->getVertexStrider(pos); - ret->getIndexStrider(idx); - - pos[0] = LLVector3(-1,-1,-1); - pos[1] = LLVector3(-1,-1, 1); - pos[2] = LLVector3(-1, 1,-1); - pos[3] = LLVector3(-1, 1, 1); - pos[4] = LLVector3( 1,-1,-1); - pos[5] = LLVector3( 1,-1, 1); - pos[6] = LLVector3( 1, 1,-1); - pos[7] = LLVector3( 1, 1, 1); - - for (U32 i = 0; i < 64; i++) - { - idx[i] = sOcclusionIndices[i]; - } - - ret->flush(); - - return ret; -} - -static LLFastTimer::DeclareTimer FTM_BUILD_OCCLUSION("Build Occlusion"); - -BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group); - //returns: // 0 if sphere and AABB are not intersecting // 1 if they are @@ -285,18 +127,7 @@ LLSpatialGroup::~LLSpatialGroup() sZombieGroups--; } - sNodeCount--; - - if (gGLManager.mHasOcclusionQuery) - { - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i) - { - if (mOcclusionQuery[i]) - { - release_occlusion_query_object_name(mOcclusionQuery[i]); - } - } - } + sNodeCount--; clearDrawMap(); clearAtlasList() ; @@ -431,7 +262,7 @@ void LLSpatialGroup::clearDrawMap() BOOL LLSpatialGroup::isHUDGroup() { - return mSpatialPartition && mSpatialPartition->isHUDPartition() ; + return getSpatialPartition() && getSpatialPartition()->isHUDPartition() ; } BOOL LLSpatialGroup::isRecentlyVisible() const @@ -461,7 +292,7 @@ void LLSpatialGroup::validate() sg_assert(drawable->getSpatialGroup() == this); if (drawable->getSpatialBridge()) { - sg_assert(drawable->getSpatialBridge() == mSpatialPartition->asBridge()); + sg_assert(drawable->getSpatialBridge() == getSpatialPartition()->asBridge()); } /*if (drawable->isSpatialBridge()) @@ -501,14 +332,6 @@ void LLSpatialGroup::validate() #endif } -void LLSpatialGroup::checkStates() -{ -#if LL_OCTREE_PARANOIA_CHECK - //LLOctreeStateCheck checker; - //checker.traverse(mOctreeNode); -#endif -} - void LLSpatialGroup::validateDrawMap() { #if LL_OCTREE_PARANOIA_CHECK @@ -574,7 +397,7 @@ void LLSpatialGroup::rebuildGeom() { if (!isDead()) { - mSpatialPartition->rebuildGeom(this); + getSpatialPartition()->rebuildGeom(this); if (hasState(LLSpatialGroup::MESH_DIRTY)) { @@ -587,7 +410,7 @@ void LLSpatialGroup::rebuildMesh() { if (!isDead()) { - mSpatialPartition->rebuildMesh(this); + getSpatialPartition()->rebuildMesh(this); } } @@ -665,23 +488,7 @@ void LLSpatialPartition::rebuildMesh(LLSpatialGroup* group) LLSpatialGroup* LLSpatialGroup::getParent() { - if (isDead()) - { - return NULL; - } - - if(!mOctreeNode) - { - return NULL; - } - OctreeNode* parent = mOctreeNode->getOctParent(); - - if (parent) - { - return (LLSpatialGroup*) parent->getListener(0); - } - - return NULL; + return (LLSpatialGroup*)LLviewerOctreeGroup::getParent(); } BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) @@ -735,10 +542,10 @@ void LLSpatialGroup::shift(const LLVector4a &offset) mObjectExtents[0].add(offset); mObjectExtents[1].add(offset); - if (!mSpatialPartition->mRenderByGroup && - mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_TREE && - mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_TERRAIN && - mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_BRIDGE) + if (!getSpatialPartition()->mRenderByGroup && + getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TREE && + getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TERRAIN && + getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_BRIDGE) { setState(GEOM_DIRTY); gPipeline.markRebuild(this, TRUE); @@ -839,135 +646,15 @@ void LLSpatialGroup::clearState(U32 state, S32 mode) } } -//===================================== -// Occlusion State Set/Clear -//===================================== -class LLSpatialSetOcclusionState : public OctreeTraveler -{ -public: - U32 mState; - LLSpatialSetOcclusionState(U32 state) : mState(state) { } - virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setOcclusionState(mState); } -}; - -class LLSpatialSetOcclusionStateDiff : public LLSpatialSetOcclusionState -{ -public: - LLSpatialSetOcclusionStateDiff(U32 state) : LLSpatialSetOcclusionState(state) { } - - virtual void traverse(const OctreeNode* n) - { - LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - - if (!group->isOcclusionState(mState)) - { - OctreeTraveler::traverse(n); - } - } -}; - - -void LLSpatialGroup::setOcclusionState(U32 state, S32 mode) -{ - if (mode > STATE_MODE_SINGLE) - { - if (mode == STATE_MODE_DIFF) - { - LLSpatialSetOcclusionStateDiff setter(state); - setter.traverse(mOctreeNode); - } - else if (mode == STATE_MODE_BRANCH) - { - LLSpatialSetOcclusionState setter(state); - setter.traverse(mOctreeNode); - } - else - { - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) - { - mOcclusionState[i] |= state; - - if ((state & DISCARD_QUERY) && mOcclusionQuery[i]) - { - release_occlusion_query_object_name(mOcclusionQuery[i]); - mOcclusionQuery[i] = 0; - } - } - } - } - else - { - mOcclusionState[LLViewerCamera::sCurCameraID] |= state; - if ((state & DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { - release_occlusion_query_object_name(mOcclusionQuery[LLViewerCamera::sCurCameraID]); - mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; - } - } -} - -class LLSpatialClearOcclusionState : public OctreeTraveler -{ -public: - U32 mState; - - LLSpatialClearOcclusionState(U32 state) : mState(state) { } - virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearOcclusionState(mState); } -}; - -class LLSpatialClearOcclusionStateDiff : public LLSpatialClearOcclusionState -{ -public: - LLSpatialClearOcclusionStateDiff(U32 state) : LLSpatialClearOcclusionState(state) { } - - virtual void traverse(const OctreeNode* n) - { - LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - - if (group->isOcclusionState(mState)) - { - OctreeTraveler::traverse(n); - } - } -}; - -void LLSpatialGroup::clearOcclusionState(U32 state, S32 mode) -{ - if (mode > STATE_MODE_SINGLE) - { - if (mode == STATE_MODE_DIFF) - { - LLSpatialClearOcclusionStateDiff clearer(state); - clearer.traverse(mOctreeNode); - } - else if (mode == STATE_MODE_BRANCH) - { - LLSpatialClearOcclusionState clearer(state); - clearer.traverse(mOctreeNode); - } - else - { - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) - { - mOcclusionState[i] &= ~state; - } - } - } - else - { - mOcclusionState[LLViewerCamera::sCurCameraID] &= ~state; - } -} //====================================== // Octree Listener Implementation //====================================== -LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLviewerOctreeGroup(node), +LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLOcclusionCullingGroup(node, part), mObjectBoxSize(1.f), mGeometryBytes(0), mSurfaceArea(0.f), - mBuilt(0.f), - mSpatialPartition(part), + mBuilt(0.f), mVertexBuffer(NULL), mBufferUsage(part->mBufferUsage), mDistance(0.f), @@ -990,21 +677,6 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLv setState(SG_INITIAL_STATE_MASK); gPipeline.markRebuild(this, TRUE); - part->mLODSeed = (part->mLODSeed+1)%part->mLODPeriod; - mLODHash = part->mLODSeed; - - OctreeNode* oct_parent = node->getOctParent(); - - LLSpatialGroup* parent = oct_parent ? (LLSpatialGroup*) oct_parent->getListener(0) : NULL; - - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) - { - mOcclusionQuery[i] = 0; - mOcclusionIssued[i] = 0; - mOcclusionState[i] = parent ? SG_STATE_INHERIT_MASK & parent->mOcclusionState[i] : 0; - mVisible[i] = 0; - } - mRadius = 1; mPixelArea = 1024.f; } @@ -1030,10 +702,10 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) #endif if (!isEmpty()) { - mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].getLength3().getF32() : + mRadius = getSpatialPartition()->mRenderByGroup ? mObjectBounds[1].getLength3().getF32() : (F32) mOctreeNode->getSize().getLength3().getF32(); - mDistance = mSpatialPartition->calcDistance(this, camera); - mPixelArea = mSpatialPartition->calcPixelArea(this, camera); + mDistance = getSpatialPartition()->calcDistance(this, camera); + mPixelArea = getSpatialPartition()->calcPixelArea(this, camera); } } @@ -1056,7 +728,7 @@ F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) if (!group->hasState(LLSpatialGroup::ALPHA_DIRTY)) { - if (!group->mSpatialPartition->isBridge()) + if (!group->getSpatialPartition()->isBridge()) { LLVector4a view_angle = eye; @@ -1124,11 +796,6 @@ F32 LLSpatialGroup::getUpdateUrgency() const } } -BOOL LLSpatialGroup::needsUpdate() -{ - return (LLDrawable::getCurrentFrame()%mSpatialPartition->mLODPeriod == mLODHash) ? TRUE : FALSE; -} - BOOL LLSpatialGroup::changeLOD() { if (hasState(ALPHA_DIRTY | OBJECT_DIRTY)) @@ -1136,11 +803,11 @@ BOOL LLSpatialGroup::changeLOD() return TRUE; } - if (mSpatialPartition->mSlopRatio > 0.f) + if (getSpatialPartition()->mSlopRatio > 0.f) { F32 ratio = (mDistance - mLastUpdateDistance)/(llmax(mLastUpdateDistance, mRadius)); - if (fabsf(ratio) >= mSpatialPartition->mSlopRatio) + if (fabsf(ratio) >= getSpatialPartition()->mSlopRatio) { return TRUE; } @@ -1193,7 +860,7 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node) } //clean up avatar attachment stats - LLSpatialBridge* bridge = mSpatialPartition->asBridge(); + LLSpatialBridge* bridge = getSpatialPartition()->asBridge(); if (bridge) { if (bridge->mAvatar.notNull()) @@ -1214,7 +881,7 @@ void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* c { if (child->getListenerCount() == 0) { - new LLSpatialGroup(child, mSpatialPartition); + new LLSpatialGroup(child, getSpatialPartition()); } else { @@ -1243,14 +910,7 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion) if (!keep_occlusion) { - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) - { - if (mOcclusionQuery[i]) - { - release_occlusion_query_object_name(mOcclusionQuery[i]); - mOcclusionQuery[i] = 0; - } - } + releaseOcclusionQueryObjectNames(); } @@ -1272,233 +932,13 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion) } } -static LLFastTimer::DeclareTimer FTM_OCCLUSION_READBACK("Readback Occlusion"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Occlusion Wait"); - -void LLSpatialGroup::checkOcclusion() -{ - if (LLPipeline::sUseOcclusion > 1) - { - LLFastTimer t(FTM_OCCLUSION_READBACK); - LLSpatialGroup* parent = getParent(); - if (parent && parent->isOcclusionState(LLSpatialGroup::OCCLUDED)) - { //if the parent has been marked as occluded, the child is implicitly occluded - clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); - } - else if (isOcclusionState(QUERY_PENDING)) - { //otherwise, if a query is pending, read it back - - GLuint available = 0; - if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { - glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); - - static LLCachedControl wait_for_query(gSavedSettings, "RenderSynchronousOcclusion"); - - if (wait_for_query && mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount) - { //query was issued last frame, wait until it's available - S32 max_loop = 1024; - LLFastTimer t(FTM_OCCLUSION_WAIT); - while (!available && max_loop-- > 0) - { - F32 max_time = llmin(gFrameIntervalSeconds.value()*10.f, 1.f); - //do some usefu work while we wait - LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread - LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread - LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread - - glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); - } - } - } - else - { - available = 1; - } - - if (available) - { //result is available, read it back, otherwise wait until next frame - GLuint res = 1; - if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { - glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &res); -#if LL_TRACK_PENDING_OCCLUSION_QUERIES - sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]); -#endif - } - else if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { //delete the query to avoid holding onto hundreds of pending queries - release_occlusion_query_object_name(mOcclusionQuery[LLViewerCamera::sCurCameraID]); - mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; - } - - if (isOcclusionState(DISCARD_QUERY)) - { - res = 2; - } - - if (res > 0) - { - assert_states_valid(this); - clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); - assert_states_valid(this); - } - else - { - assert_states_valid(this); - - setOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); - - assert_states_valid(this); - } - - clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); - } - } - else if (mSpatialPartition->isOcclusionEnabled() && isOcclusionState(LLSpatialGroup::OCCLUDED)) - { //check occlusion has been issued for occluded node that has not had a query issued - assert_states_valid(this); - clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); - assert_states_valid(this); - } - } -} - -static LLFastTimer::DeclareTimer FTM_PUSH_OCCLUSION_VERTS("Push Occlusion"); -static LLFastTimer::DeclareTimer FTM_SET_OCCLUSION_STATE("Occlusion State"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_EARLY_FAIL("Occlusion Early Fail"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_ALLOCATE("Allocate"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_BUILD("Build"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_BEGIN_QUERY("Begin Query"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_END_QUERY("End Query"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_SET_BUFFER("Set Buffer"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_DRAW_WATER("Draw Water"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_DRAW("Draw"); - - - -void LLSpatialGroup::doOcclusion(LLCamera* camera) -{ - if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1) - { - // Don't cull hole/edge water, unless we have the GL_ARB_depth_clamp extension - if (earlyFail(camera, this)) - { - LLFastTimer t(FTM_OCCLUSION_EARLY_FAIL); - setOcclusionState(LLSpatialGroup::DISCARD_QUERY); - assert_states_valid(this); - clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); - assert_states_valid(this); - } - else - { - if (!isOcclusionState(QUERY_PENDING) || isOcclusionState(DISCARD_QUERY)) - { - { //no query pending, or previous query to be discarded - LLFastTimer t(FTM_RENDER_OCCLUSION); - - if (!mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { - LLFastTimer t(FTM_OCCLUSION_ALLOCATE); - mOcclusionQuery[LLViewerCamera::sCurCameraID] = get_new_occlusion_query_object_name(); - } - - // Depth clamp all water to avoid it being culled as a result of being - // behind the far clip plane, and in the case of edge water to avoid - // it being culled while still visible. - bool const use_depth_clamp = gGLManager.mHasDepthClamp && - (mSpatialPartition->mDrawableType == LLDrawPool::POOL_WATER || - mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER); - - LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0); - -#if !LL_DARWIN - U32 mode = gGLManager.mHasOcclusionQuery2 ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED_ARB; -#else - U32 mode = GL_SAMPLES_PASSED_ARB; -#endif - -#if LL_TRACK_PENDING_OCCLUSION_QUERIES - sPendingQueries.insert(mOcclusionQuery[LLViewerCamera::sCurCameraID]); -#endif - - { - LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS); - - //store which frame this query was issued on - mOcclusionIssued[LLViewerCamera::sCurCameraID] = gFrameCount; - - { - LLFastTimer t(FTM_OCCLUSION_BEGIN_QUERY); - glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]); - } - - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - llassert(shader); - - shader->uniform3fv(LLShaderMgr::BOX_CENTER, 1, mBounds[0].getF32ptr()); - shader->uniform3f(LLShaderMgr::BOX_SIZE, mBounds[1][0]+SG_OCCLUSION_FUDGE, - mBounds[1][1]+SG_OCCLUSION_FUDGE, - mBounds[1][2]+SG_OCCLUSION_FUDGE); - - if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER) - { - LLFastTimer t(FTM_OCCLUSION_DRAW_WATER); - - LLGLSquashToFarClip squash(glh_get_current_projection(), 1); - if (camera->getOrigin().isExactlyZero()) - { //origin is invalid, draw entire box - gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); - gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8); - } - else - { - gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); - } - } - else - { - LLFastTimer t(FTM_OCCLUSION_DRAW); - if (camera->getOrigin().isExactlyZero()) - { //origin is invalid, draw entire box - gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); - gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8); - } - else - { - gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); - } - } - - - { - LLFastTimer t(FTM_OCCLUSION_END_QUERY); - glEndQueryARB(mode); - } - } - } - - { - LLFastTimer t(FTM_SET_OCCLUSION_STATE); - setOcclusionState(LLSpatialGroup::QUERY_PENDING); - clearOcclusionState(LLSpatialGroup::DISCARD_QUERY); - } - } - } - } -} - //============================================== LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage, LLViewerRegion* regionp) : mRenderByGroup(render_by_group), mBridge(NULL) { - mRegionp = regionp; - mOcclusionEnabled = TRUE; - mDrawableType = 0; - mPartitionType = LLViewerRegion::PARTITION_NONE; - mLODSeed = 0; - mLODPeriod = 1; + mRegionp = regionp; + mPartitionType = LLViewerRegion::PARTITION_NONE; mVertexDataMask = data_mask; mBufferUsage = buffer_usage; mDepthMask = FALSE; @@ -1566,11 +1006,11 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL BOOL was_visible = curp ? curp->isVisible() : FALSE; - if (curp && curp->mSpatialPartition != this) + if (curp && curp->getSpatialPartition() != this) { //keep drawable from being garbage collected LLPointer ptr = drawablep; - if (curp->mSpatialPartition->remove(drawablep, curp)) + if (curp->getSpatialPartition()->remove(drawablep, curp)) { put(drawablep, was_visible); return; @@ -1961,7 +1401,7 @@ public: { continue; } - if (drawable->getVObj().notNull() && !group->mSpatialPartition->mRenderByGroup) + if (drawable->getVObj().notNull() && !group->getSpatialPartition()->mRenderByGroup) { gPipeline.markRebuild(drawable, LLDrawable::REBUILD_ALL, TRUE); } @@ -1985,11 +1425,6 @@ void LLSpatialPartition::resetVertexBuffers() dirty.traverse(mOctree); } -BOOL LLSpatialPartition::isOcclusionEnabled() -{ - return mOcclusionEnabled || LLPipeline::sUseOcclusion > 2; -} - BOOL LLSpatialPartition::getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax) { LLVector4a visMina, visMaxa; @@ -2075,51 +1510,6 @@ S32 LLSpatialPartition::cull(LLCamera &camera) return 0; } -BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group) -{ - if (camera->getOrigin().isExactlyZero()) - { - return FALSE; - } - - const F32 vel = SG_OCCLUSION_FUDGE*2.f; - LLVector4a fudge; - fudge.splat(vel); - - const LLVector4a* bounds = group->getBounds(); - const LLVector4a& c = bounds[0]; - LLVector4a r; - r.setAdd(bounds[1], fudge); - - /*if (r.magVecSquared() > 1024.0*1024.0) - { - return TRUE; - }*/ - - LLVector4a e; - e.load3(camera->getOrigin().mV); - - LLVector4a min; - min.setSub(c,r); - LLVector4a max; - max.setAdd(c,r); - - S32 lt = e.lessThan(min).getGatheredBits() & 0x7; - if (lt) - { - return FALSE; - } - - S32 gt = e.greaterThan(max).getGatheredBits() & 0x7; - if (gt) - { - return FALSE; - } - - return TRUE; -} - - void pushVerts(LLDrawInfo* params, U32 mask) { LLRenderPass::applyModelMatrix(*params); @@ -2191,7 +1581,7 @@ void pushBufferVerts(LLVertexBuffer* buffer, U32 mask) void pushBufferVerts(LLSpatialGroup* group, U32 mask) { - if (group->mSpatialPartition->mRenderByGroup) + if (group->getSpatialPartition()->mRenderByGroup) { if (!group->mDrawMap.empty()) { @@ -2292,7 +1682,7 @@ void renderOctree(LLSpatialGroup* group) { continue; } - if (!group->mSpatialPartition->isBridge()) + if (!group->getSpatialPartition()->isBridge()) { gGL.pushMatrix(); LLVector3 trans = drawable->getRegion()->getOriginAgent(); @@ -2324,7 +1714,7 @@ void renderOctree(LLSpatialGroup* group) } } - if (!group->mSpatialPartition->isBridge()) + if (!group->getSpatialPartition()->isBridge()) { gGL.popMatrix(); } @@ -2336,7 +1726,7 @@ void renderOctree(LLSpatialGroup* group) else { if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->isEmpty() - && group->mSpatialPartition->mRenderByGroup) + && group->getSpatialPartition()->mRenderByGroup) { col.setVec(0.8f, 0.4f, 0.1f, 0.1f); } @@ -2373,7 +1763,7 @@ void renderOctree(LLSpatialGroup* group) drawBoxOutline(bounds[0], bounds[1]); //draw bounding box for draw info - /*if (group->mSpatialPartition->mRenderByGroup) + /*if (group->getSpatialPartition()->mRenderByGroup) { gGL.diffuseColor4f(1.0f, 0.75f, 0.25f, 0.6f); for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) @@ -3147,7 +2537,7 @@ void renderPhysicsShapes(LLSpatialGroup* group) LLVOVolume* volume = drawable->getVOVolume(); if (volume && !volume->isAttachment() && volume->getPhysicsShapeType() != LLViewerObject::PHYSICS_SHAPE_NONE ) { - if (!group->mSpatialPartition->isBridge()) + if (!group->getSpatialPartition()->isBridge()) { gGL.pushMatrix(); LLVector3 trans = drawable->getRegion()->getOriginAgent(); @@ -4225,9 +3615,9 @@ public: LLVector3 local_start = mStart; LLVector3 local_end = mEnd; - if (group->mSpatialPartition->isBridge()) + if (group->getSpatialPartition()->isBridge()) { - LLMatrix4 local_matrix = group->mSpatialPartition->asBridge()->mDrawable->getRenderMatrix(); + LLMatrix4 local_matrix = group->getSpatialPartition()->asBridge()->mDrawable->getRenderMatrix(); local_matrix.invert(); local_start = mStart * local_matrix; diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index b592e73403..406e796d4d 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -55,12 +55,6 @@ class LLViewerRegion; void pushVerts(LLFace* face, U32 mask); -// get index buffer for binary encoded axis vertex buffer given a box at center being viewed by given camera -U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center); -U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center); -GLuint get_new_occlusion_query_object_name(); -void release_occlusion_query_object_name(GLuint name); - class LLDrawInfo : public LLRefCount { protected: @@ -191,13 +185,13 @@ public: }; LL_ALIGN_PREFIX(16) -class LLSpatialGroup : public LLviewerOctreeGroup +class LLSpatialGroup : public LLOcclusionCullingGroup { friend class LLSpatialPartition; friend class LLOctreeStateCheck; public: - LLSpatialGroup(const LLSpatialGroup& rhs) : LLviewerOctreeGroup(rhs) + LLSpatialGroup(const LLSpatialGroup& rhs) : LLOcclusionCullingGroup(rhs) { *this = rhs; } @@ -218,7 +212,6 @@ public: return *this; } - static std::set sPendingQueries; //pending occlusion queries static U32 sNodeCount; static BOOL sNoDelete; //deletion of spatial groups and draw info not allowed if TRUE @@ -256,17 +249,7 @@ public: typedef enum { - OCCLUDED = 0x00010000, - QUERY_PENDING = 0x00020000, - ACTIVE_OCCLUSION = 0x00040000, - DISCARD_QUERY = 0x00080000, - EARLY_FAIL = 0x00100000, - } eOcclusionState; - - typedef enum - { - DEAD = LLviewerOctreeGroup::INVALID_STATE, - GEOM_DIRTY = (DEAD << 1), + GEOM_DIRTY = LLviewerOctreeGroup::INVALID_STATE, ALPHA_DIRTY = (GEOM_DIRTY << 1), IN_IMAGE_QUEUE = (ALPHA_DIRTY << 1), IMAGE_DIRTY = (IN_IMAGE_QUEUE << 1), @@ -275,33 +258,19 @@ public: IN_BUILD_Q1 = (NEW_DRAWINFO << 1), IN_BUILD_Q2 = (IN_BUILD_Q1 << 1), STATE_MASK = 0x0000FFFF, - } eSpatialState; - - typedef enum - { - STATE_MODE_SINGLE = 0, //set one node - STATE_MODE_BRANCH, //set entire branch - STATE_MODE_DIFF, //set entire branch as long as current state is different - STATE_MODE_ALL_CAMERAS, //used for occlusion state, set state for all cameras - } eSetStateMode; + } eSpatialState; LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part); - BOOL isHUDGroup() ; - BOOL isDead() { return hasState(DEAD); } - BOOL isOcclusionState(U32 state) const { return mOcclusionState[LLViewerCamera::sCurCameraID] & state ? TRUE : FALSE; } + BOOL isHUDGroup() ; void clearDrawMap(); void validate(); - void checkStates(); void validateDrawMap(); void setState(U32 state, S32 mode); void clearState(U32 state, S32 mode); - void clearState(U32 state) {mState &= ~state;} - - void setOcclusionState(U32 state, S32 mode = STATE_MODE_SINGLE); - void clearOcclusionState(U32 state, S32 mode = STATE_MODE_SINGLE); + void clearState(U32 state) {mState &= ~state;} LLSpatialGroup* getParent(); @@ -309,13 +278,10 @@ public: BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE); BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group BOOL isRecentlyVisible() const; - void shift(const LLVector4a &offset); - void checkOcclusion(); //read back last occlusion query (if any) - void doOcclusion(LLCamera* camera); //issue occlusion query + void shift(const LLVector4a &offset); void destroyGL(bool keep_occlusion = false); void updateDistance(LLCamera& camera); - BOOL needsUpdate(); F32 getUpdateUrgency() const; BOOL changeLOD(); void rebuildGeom(); @@ -327,6 +293,8 @@ public: void drawObjectBox(LLColor4 col); + LLSpatialPartition* getSpatialPartition() {return (LLSpatialPartition*)mSpatialPartition;} + //LISTENER FUNCTIONS virtual void handleInsertion(const TreeNode* node, LLViewerOctreeEntry* face); virtual void handleRemoval(const TreeNode* node, LLViewerOctreeEntry* face); @@ -372,12 +340,8 @@ private: //------------------- protected: - virtual ~LLSpatialGroup(); - - U32 mOcclusionState[LLViewerCamera::NUM_CAMERAS]; - U32 mOcclusionIssued[LLViewerCamera::NUM_CAMERAS]; - - S32 mLODHash; + virtual ~LLSpatialGroup(); + static S32 sLODSeed; public: @@ -387,11 +351,9 @@ public: 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; - LLSpatialPartition* mSpatialPartition; + F32 mBuilt; - LLPointer mVertexBuffer; - GLuint mOcclusionQuery[LLViewerCamera::NUM_CAMERAS]; + LLPointer mVertexBuffer; U32 mBufferUsage; draw_map_t mDrawMap; @@ -461,21 +423,18 @@ public: void renderDebug(); void renderIntersectingBBoxes(LLCamera* camera); void restoreGL(); - void resetVertexBuffers(); - BOOL isOcclusionEnabled(); + void resetVertexBuffers(); + BOOL getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax); public: 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 + // to call asBridge() from the destructor + BOOL mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane - U32 mBufferUsage; - U32 mDrawableType; - const BOOL mRenderByGroup; - U32 mLODSeed; - U32 mLODPeriod; //number of frames between LOD updates for a given spatial group (staggered by mLODSeed) + U32 mBufferUsage; + const BOOL mRenderByGroup; U32 mVertexDataMask; F32 mSlopRatio; //percentage distance must change before drawables receive LOD update (default is 0.25); BOOL mDepthMask; //if TRUE, objects in this partition will be written to depth during alpha rendering diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp index 926d791d1f..844075089f 100644 --- a/indra/newview/llvieweroctree.cpp +++ b/indra/newview/llvieweroctree.cpp @@ -27,6 +27,11 @@ #include "llviewerprecompiledheaders.h" #include "llvieweroctree.h" #include "llviewerregion.h" +#include "pipeline.h" +#include "llviewercontrol.h" +#include "llappviewer.h" +#include "llglslshader.h" +#include "llviewershadermgr.h" //----------------------------------------------------------------------------------- //static variables definitions @@ -37,6 +42,100 @@ BOOL LLViewerOctreeDebug::sInDebug = FALSE; //----------------------------------------------------------------------------------- //some global functions definitions //----------------------------------------------------------------------------------- +typedef enum +{ + b000 = 0x00, + b001 = 0x01, + b010 = 0x02, + b011 = 0x03, + b100 = 0x04, + b101 = 0x05, + b110 = 0x06, + b111 = 0x07, +} eLoveTheBits; + +//contact Runitai Linden for a copy of the SL object used to write this table +//basically, you give the table a bitmask of the look-at vector to a node and it +//gives you a triangle fan index array +static U16 sOcclusionIndices[] = +{ + //000 + b111, b110, b010, b011, b001, b101, b100, b110, + //001 + b011, b010, b000, b001, b101, b111, b110, b010, + //010 + b101, b100, b110, b111, b011, b001, b000, b100, + //011 + b001, b000, b100, b101, b111, b011, b010, b000, + //100 + b110, b000, b010, b011, b111, b101, b100, b000, + //101 + b010, b100, b000, b001, b011, b111, b110, b100, + //110 + b100, b010, b110, b111, b101, b001, b000, b010, + //111 + b000, b110, b100, b101, b001, b011, b010, b110, +}; + +U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center) +{ + LLVector4a origin; + origin.load3(camera->getOrigin().mV); + + S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7; + + return cypher*8; +} + +U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center) +{ + LLVector4a origin; + origin.load3(camera->getOrigin().mV); + + S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7; + + return (U8*) (sOcclusionIndices+cypher*8); +} + +//create a vertex buffer for efficiently rendering cubes +LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage) +{ + LLVertexBuffer* ret = new LLVertexBuffer(type_mask, usage); + + ret->allocateBuffer(8, 64, true); + + LLStrider pos; + LLStrider idx; + + ret->getVertexStrider(pos); + ret->getIndexStrider(idx); + + pos[0] = LLVector3(-1,-1,-1); + pos[1] = LLVector3(-1,-1, 1); + pos[2] = LLVector3(-1, 1,-1); + pos[3] = LLVector3(-1, 1, 1); + pos[4] = LLVector3( 1,-1,-1); + pos[5] = LLVector3( 1,-1, 1); + pos[6] = LLVector3( 1, 1,-1); + pos[7] = LLVector3( 1, 1, 1); + + for (U32 i = 0; i < 64; i++) + { + idx[i] = sOcclusionIndices[i]; + } + + ret->flush(); + + return ret; +} + + +#define LL_TRACK_PENDING_OCCLUSION_QUERIES 0 + +const F32 SG_OCCLUSION_FUDGE = 0.25f; +#define SG_DISCARD_TOLERANCE 0.01f + + S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad) { return AABBSphereIntersectR2(min, max, origin, rad*rad); @@ -540,6 +639,11 @@ void LLviewerOctreeGroup::handleChildRemoval(const OctreeNode* parent, const Oct LLviewerOctreeGroup* LLviewerOctreeGroup::getParent() { + if (isDead()) + { + return NULL; + } + if(!mOctreeNode) { return NULL; @@ -629,10 +733,519 @@ void LLviewerOctreeGroup::setVisible() { mVisible[LLViewerCamera::sCurCameraID] = LLViewerOctreeEntryData::getCurrentFrame(); } + +void LLviewerOctreeGroup::checkStates() +{ +#if LL_OCTREE_PARANOIA_CHECK + //LLOctreeStateCheck checker; + //checker.traverse(mOctreeNode); +#endif +} + +//------------------------------------------------------------------------------------------- +//occulsion culling functions and classes +//------------------------------------------------------------------------------------------- +std::set LLOcclusionCullingGroup::sPendingQueries; +class LLOcclusionQueryPool : public LLGLNamePool +{ +public: + LLOcclusionQueryPool() + { + mCurQuery = 1; + } + +protected: + + std::list mAvailableName; + GLuint mCurQuery; + + virtual GLuint allocateName() + { + GLuint ret = 0; + + if (!mAvailableName.empty()) + { + ret = mAvailableName.front(); + mAvailableName.pop_front(); + } + else + { + ret = mCurQuery++; + } + + return ret; + } + + virtual void releaseName(GLuint name) + { +#if LL_TRACK_PENDING_OCCLUSION_QUERIES + LLSpatialGroup::sPendingQueries.erase(name); +#endif + llassert(std::find(mAvailableName.begin(), mAvailableName.end(), name) == mAvailableName.end()); + mAvailableName.push_back(name); + } +}; + +static LLOcclusionQueryPool sQueryPool; +U32 LLOcclusionCullingGroup::getNewOcclusionQueryObjectName() +{ + return sQueryPool.allocate(); +} + +void LLOcclusionCullingGroup::releaseOcclusionQueryObjectName(GLuint name) +{ + sQueryPool.release(name); +} + +//===================================== +// Occlusion State Set/Clear +//===================================== +class LLSpatialSetOcclusionState : public OctreeTraveler +{ +public: + U32 mState; + LLSpatialSetOcclusionState(U32 state) : mState(state) { } + virtual void visit(const OctreeNode* branch) { ((LLOcclusionCullingGroup*) branch->getListener(0))->setOcclusionState(mState); } +}; + +class LLSpatialSetOcclusionStateDiff : public LLSpatialSetOcclusionState +{ +public: + LLSpatialSetOcclusionStateDiff(U32 state) : LLSpatialSetOcclusionState(state) { } + + virtual void traverse(const OctreeNode* n) + { + LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*) n->getListener(0); + + if (!group->isOcclusionState(mState)) + { + OctreeTraveler::traverse(n); + } + } +}; + + +LLOcclusionCullingGroup::LLOcclusionCullingGroup(OctreeNode* node, LLViewerOctreePartition* part) : + LLviewerOctreeGroup(node), + mSpatialPartition(part) +{ + part->mLODSeed = (part->mLODSeed+1)%part->mLODPeriod; + mLODHash = part->mLODSeed; + + OctreeNode* oct_parent = node->getOctParent(); + LLOcclusionCullingGroup* parent = oct_parent ? (LLOcclusionCullingGroup*) oct_parent->getListener(0) : NULL; + + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) + { + mOcclusionQuery[i] = 0; + mOcclusionIssued[i] = 0; + mOcclusionState[i] = parent ? SG_STATE_INHERIT_MASK & parent->mOcclusionState[i] : 0; + mVisible[i] = 0; + } +} + +LLOcclusionCullingGroup::~LLOcclusionCullingGroup() +{ + releaseOcclusionQueryObjectNames(); +} + +BOOL LLOcclusionCullingGroup::needsUpdate() +{ + return (LLDrawable::getCurrentFrame() % mSpatialPartition->mLODPeriod == mLODHash) ? TRUE : FALSE; +} + +//virtual +void LLOcclusionCullingGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child) +{ + if (child->getListenerCount() == 0) + { + new LLOcclusionCullingGroup(child, mSpatialPartition); + } + else + { + OCT_ERRS << "LLOcclusionCullingGroup redundancy detected." << llendl; + } + + unbound(); + + ((LLviewerOctreeGroup*)child->getListener(0))->unbound(); +} + +void LLOcclusionCullingGroup::releaseOcclusionQueryObjectNames() +{ + if (gGLManager.mHasOcclusionQuery) + { + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i) + { + if (mOcclusionQuery[i]) + { + releaseOcclusionQueryObjectName(mOcclusionQuery[i]); + mOcclusionQuery[i] = 0; + } + } + } +} + +void LLOcclusionCullingGroup::setOcclusionState(U32 state, S32 mode) +{ + if (mode > STATE_MODE_SINGLE) + { + if (mode == STATE_MODE_DIFF) + { + LLSpatialSetOcclusionStateDiff setter(state); + setter.traverse(mOctreeNode); + } + else if (mode == STATE_MODE_BRANCH) + { + LLSpatialSetOcclusionState setter(state); + setter.traverse(mOctreeNode); + } + else + { + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) + { + mOcclusionState[i] |= state; + + if ((state & DISCARD_QUERY) && mOcclusionQuery[i]) + { + releaseOcclusionQueryObjectName(mOcclusionQuery[i]); + mOcclusionQuery[i] = 0; + } + } + } + } + else + { + mOcclusionState[LLViewerCamera::sCurCameraID] |= state; + if ((state & DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) + { + releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]); + mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; + } + } +} + +class LLSpatialClearOcclusionState : public OctreeTraveler +{ +public: + U32 mState; + + LLSpatialClearOcclusionState(U32 state) : mState(state) { } + virtual void visit(const OctreeNode* branch) { ((LLOcclusionCullingGroup*) branch->getListener(0))->clearOcclusionState(mState); } +}; + +class LLSpatialClearOcclusionStateDiff : public LLSpatialClearOcclusionState +{ +public: + LLSpatialClearOcclusionStateDiff(U32 state) : LLSpatialClearOcclusionState(state) { } + + virtual void traverse(const OctreeNode* n) + { + LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*) n->getListener(0); + + if (group->isOcclusionState(mState)) + { + OctreeTraveler::traverse(n); + } + } +}; + +void LLOcclusionCullingGroup::clearOcclusionState(U32 state, S32 mode) +{ + if (mode > STATE_MODE_SINGLE) + { + if (mode == STATE_MODE_DIFF) + { + LLSpatialClearOcclusionStateDiff clearer(state); + clearer.traverse(mOctreeNode); + } + else if (mode == STATE_MODE_BRANCH) + { + LLSpatialClearOcclusionState clearer(state); + clearer.traverse(mOctreeNode); + } + else + { + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) + { + mOcclusionState[i] &= ~state; + } + } + } + else + { + mOcclusionState[LLViewerCamera::sCurCameraID] &= ~state; + } +} + +static LLFastTimer::DeclareTimer FTM_OCCLUSION_READBACK("Readback Occlusion"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Occlusion Wait"); + +BOOL LLOcclusionCullingGroup::earlyFail(LLCamera* camera) +{ + if (camera->getOrigin().isExactlyZero()) + { + return FALSE; + } + + const F32 vel = SG_OCCLUSION_FUDGE*2.f; + LLVector4a fudge; + fudge.splat(vel); + + const LLVector4a* bounds = getBounds(); + const LLVector4a& c = bounds[0]; + LLVector4a r; + r.setAdd(bounds[1], fudge); + + /*if (r.magVecSquared() > 1024.0*1024.0) + { + return TRUE; + }*/ + + LLVector4a e; + e.load3(camera->getOrigin().mV); + + LLVector4a min; + min.setSub(c,r); + LLVector4a max; + max.setAdd(c,r); + + S32 lt = e.lessThan(min).getGatheredBits() & 0x7; + if (lt) + { + return FALSE; + } + + S32 gt = e.greaterThan(max).getGatheredBits() & 0x7; + if (gt) + { + return FALSE; + } + + return TRUE; +} + +void LLOcclusionCullingGroup::checkOcclusion() +{ + if (LLPipeline::sUseOcclusion > 1) + { + LLFastTimer t(FTM_OCCLUSION_READBACK); + LLOcclusionCullingGroup* parent = (LLOcclusionCullingGroup*)getParent(); + if (parent && parent->isOcclusionState(LLOcclusionCullingGroup::OCCLUDED)) + { //if the parent has been marked as occluded, the child is implicitly occluded + clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); + } + else if (isOcclusionState(QUERY_PENDING)) + { //otherwise, if a query is pending, read it back + + GLuint available = 0; + if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) + { + glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); + + static LLCachedControl wait_for_query(gSavedSettings, "RenderSynchronousOcclusion"); + + if (wait_for_query && mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount) + { //query was issued last frame, wait until it's available + S32 max_loop = 1024; + LLFastTimer t(FTM_OCCLUSION_WAIT); + while (!available && max_loop-- > 0) + { + //do some usefu work while we wait + F32 max_time = llmin(gFrameIntervalSeconds.value()*10.f, 1.f); + LLAppViewer::instance()->updateTextureThreads(max_time); + + glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); + } + } + } + else + { + available = 1; + } + + if (available) + { //result is available, read it back, otherwise wait until next frame + GLuint res = 1; + if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) + { + glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &res); +#if LL_TRACK_PENDING_OCCLUSION_QUERIES + sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]); +#endif + } + else if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) + { //delete the query to avoid holding onto hundreds of pending queries + releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]); + mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; + } + + if (isOcclusionState(DISCARD_QUERY)) + { + res = 2; + } + + if (res > 0) + { + assert_states_valid(this); + clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF); + assert_states_valid(this); + } + else + { + assert_states_valid(this); + + setOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF); + + assert_states_valid(this); + } + + clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); + } + } + else if (mSpatialPartition->isOcclusionEnabled() && isOcclusionState(LLOcclusionCullingGroup::OCCLUDED)) + { //check occlusion has been issued for occluded node that has not had a query issued + assert_states_valid(this); + clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF); + assert_states_valid(this); + } + } +} + +static LLFastTimer::DeclareTimer FTM_PUSH_OCCLUSION_VERTS("Push Occlusion"); +static LLFastTimer::DeclareTimer FTM_SET_OCCLUSION_STATE("Occlusion State"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_EARLY_FAIL("Occlusion Early Fail"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_ALLOCATE("Allocate"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_BUILD("Build"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_BEGIN_QUERY("Begin Query"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_END_QUERY("End Query"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_SET_BUFFER("Set Buffer"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_DRAW_WATER("Draw Water"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_DRAW("Draw"); + +void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera) +{ + if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1) + { + // Don't cull hole/edge water, unless we have the GL_ARB_depth_clamp extension + if (earlyFail(camera)) + { + LLFastTimer t(FTM_OCCLUSION_EARLY_FAIL); + setOcclusionState(LLOcclusionCullingGroup::DISCARD_QUERY); + assert_states_valid(this); + clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF); + assert_states_valid(this); + } + else + { + if (!isOcclusionState(QUERY_PENDING) || isOcclusionState(DISCARD_QUERY)) + { + { //no query pending, or previous query to be discarded + LLFastTimer t(FTM_RENDER_OCCLUSION); + + if (!mOcclusionQuery[LLViewerCamera::sCurCameraID]) + { + LLFastTimer t(FTM_OCCLUSION_ALLOCATE); + mOcclusionQuery[LLViewerCamera::sCurCameraID] = getNewOcclusionQueryObjectName(); + } + + // Depth clamp all water to avoid it being culled as a result of being + // behind the far clip plane, and in the case of edge water to avoid + // it being culled while still visible. + bool const use_depth_clamp = gGLManager.mHasDepthClamp && + (mSpatialPartition->mDrawableType == LLDrawPool::POOL_WATER || + mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER); + + LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0); + +#if !LL_DARWIN + U32 mode = gGLManager.mHasOcclusionQuery2 ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED_ARB; +#else + U32 mode = GL_SAMPLES_PASSED_ARB; +#endif + +#if LL_TRACK_PENDING_OCCLUSION_QUERIES + sPendingQueries.insert(mOcclusionQuery[LLViewerCamera::sCurCameraID]); +#endif + + { + LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS); + + //store which frame this query was issued on + mOcclusionIssued[LLViewerCamera::sCurCameraID] = gFrameCount; + + { + LLFastTimer t(FTM_OCCLUSION_BEGIN_QUERY); + glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]); + } + + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + llassert(shader); + + shader->uniform3fv(LLShaderMgr::BOX_CENTER, 1, mBounds[0].getF32ptr()); + shader->uniform3f(LLShaderMgr::BOX_SIZE, mBounds[1][0]+SG_OCCLUSION_FUDGE, + mBounds[1][1]+SG_OCCLUSION_FUDGE, + mBounds[1][2]+SG_OCCLUSION_FUDGE); + + if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER) + { + LLFastTimer t(FTM_OCCLUSION_DRAW_WATER); + + LLGLSquashToFarClip squash(glh_get_current_projection(), 1); + if (camera->getOrigin().isExactlyZero()) + { //origin is invalid, draw entire box + gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); + gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8); + } + else + { + gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); + } + } + else + { + LLFastTimer t(FTM_OCCLUSION_DRAW); + if (camera->getOrigin().isExactlyZero()) + { //origin is invalid, draw entire box + gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); + gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8); + } + else + { + gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); + } + } + + + { + LLFastTimer t(FTM_OCCLUSION_END_QUERY); + glEndQueryARB(mode); + } + } + } + + { + LLFastTimer t(FTM_SET_OCCLUSION_STATE); + setOcclusionState(LLOcclusionCullingGroup::QUERY_PENDING); + clearOcclusionState(LLOcclusionCullingGroup::DISCARD_QUERY); + } + } + } + } +} +//------------------------------------------------------------------------------------------- +//end of occulsion culling functions and classes +//------------------------------------------------------------------------------------------- + //----------------------------------------------------------------------------------- //class LLViewerOctreePartition definitions //----------------------------------------------------------------------------------- -LLViewerOctreePartition::LLViewerOctreePartition() : mRegionp(NULL) +LLViewerOctreePartition::LLViewerOctreePartition() : + mRegionp(NULL), + mOcclusionEnabled(TRUE), + mDrawableType(0), + mLODSeed(0), + mLODPeriod(1) { LLVector4a center, size; center.splat(0.f); @@ -647,6 +1260,11 @@ LLViewerOctreePartition::~LLViewerOctreePartition() mOctree = NULL; } +BOOL LLViewerOctreePartition::isOcclusionEnabled() +{ + return mOcclusionEnabled || LLPipeline::sUseOcclusion > 2; +} + //----------------------------------------------------------------------------------- //class LLViewerOctreeCull definitions //----------------------------------------------------------------------------------- diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h index b6faf4c7ba..ed77e4bb7e 100644 --- a/indra/newview/llvieweroctree.h +++ b/indra/newview/llvieweroctree.h @@ -43,6 +43,7 @@ class LLViewerRegion; class LLViewerOctreeEntryData; class LLviewerOctreeGroup; class LLViewerOctreeEntry; +class LLViewerOctreePartition; typedef LLOctreeListener OctreeListener; typedef LLTreeNode TreeNode; @@ -50,6 +51,18 @@ typedef LLOctreeNode OctreeNode; typedef LLOctreeRoot OctreeRoot; typedef LLOctreeTraveler OctreeTraveler; +#if LL_OCTREE_PARANOIA_CHECK +#define assert_octree_valid(x) x->validate() +#define assert_states_valid(x) ((LLviewerOctreeGroup*) x->mSpatialPartition->mOctree->getListener(0))->checkStates() +#else +#define assert_octree_valid(x) +#define assert_states_valid(x) +#endif + +// get index buffer for binary encoded axis vertex buffer given a box at center being viewed by given camera +U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center); +U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center); + S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad); S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &radius_squared); @@ -181,14 +194,15 @@ class LLviewerOctreeGroup : public LLOctreeListener protected: ~LLviewerOctreeGroup(); -public: +public: enum { CLEAN = 0x00000000, DIRTY = 0x00000001, OBJECT_DIRTY = 0x00000002, SKIP_FRUSTUM_CHECK = 0x00000004, - INVALID_STATE = 0x00000008, + DEAD = 0x00000008, + INVALID_STATE = 0x00000010, }; public: @@ -216,6 +230,8 @@ public: virtual void unbound(); virtual void rebound(); + + BOOL isDead() { return hasState(DEAD); } void setVisible(); BOOL isVisible() const; @@ -251,9 +267,11 @@ public: U32 getElementCount() const { return mOctreeNode->getElementCount(); } bool hasElement(LLViewerOctreeEntryData* data); +protected: + void checkStates(); private: - virtual bool boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut); - + virtual bool boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut); + protected: U32 mState; OctreeNode* mOctreeNode; @@ -261,12 +279,76 @@ protected: LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects) LL_ALIGN_16(LLVector4a mObjectBounds[2]); // bounding box (center, size) of objects in this node LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children - LL_ALIGN_16(LLVector4a mObjectExtents[2]); // extents (min, max) of objects in this node + LL_ALIGN_16(LLVector4a mObjectExtents[2]); // extents (min, max) of objects in this node public: - S32 mVisible[LLViewerCamera::NUM_CAMERAS]; + S32 mVisible[LLViewerCamera::NUM_CAMERAS]; + }LL_ALIGN_POSTFIX(16); +//octree group which has capability to support occlusion culling +//LL_ALIGN_PREFIX(16) +class LLOcclusionCullingGroup : public LLviewerOctreeGroup +{ +public: + typedef enum + { + OCCLUDED = 0x00010000, + QUERY_PENDING = 0x00020000, + ACTIVE_OCCLUSION = 0x00040000, + DISCARD_QUERY = 0x00080000, + EARLY_FAIL = 0x00100000, + } eOcclusionState; + + typedef enum + { + STATE_MODE_SINGLE = 0, //set one node + STATE_MODE_BRANCH, //set entire branch + STATE_MODE_DIFF, //set entire branch as long as current state is different + STATE_MODE_ALL_CAMERAS, //used for occlusion state, set state for all cameras + } eSetStateMode; + +public: + LLOcclusionCullingGroup(OctreeNode* node, LLViewerOctreePartition* part); + LLOcclusionCullingGroup(const LLOcclusionCullingGroup& rhs) : LLviewerOctreeGroup(rhs) + { + *this = rhs; + } + ~LLOcclusionCullingGroup(); + + void setOcclusionState(U32 state, S32 mode = STATE_MODE_SINGLE); + void clearOcclusionState(U32 state, S32 mode = STATE_MODE_SINGLE); + void checkOcclusion(); //read back last occlusion query (if any) + void doOcclusion(LLCamera* camera); //issue occlusion query + BOOL isOcclusionState(U32 state) const { return mOcclusionState[LLViewerCamera::sCurCameraID] & state ? TRUE : FALSE; } + + BOOL needsUpdate(); + + //virtual + void handleChildAddition(const OctreeNode* parent, OctreeNode* child); + + static U32 getNewOcclusionQueryObjectName(); + static void releaseOcclusionQueryObjectName(U32 name); + +protected: + void releaseOcclusionQueryObjectNames(); + +private: + BOOL earlyFail(LLCamera* camera); + +protected: + U32 mOcclusionState[LLViewerCamera::NUM_CAMERAS]; + U32 mOcclusionIssued[LLViewerCamera::NUM_CAMERAS]; + + S32 mLODHash; + + LLViewerOctreePartition* mSpatialPartition; + U32 mOcclusionQuery[LLViewerCamera::NUM_CAMERAS]; + +public: + static std::set sPendingQueries; +};//LL_ALIGN_POSTFIX(16); + class LLViewerOctreePartition { public: @@ -275,11 +357,16 @@ public: // Cull on arbitrary frustum virtual S32 cull(LLCamera &camera) = 0; + BOOL isOcclusionEnabled(); public: U32 mPartitionType; + U32 mDrawableType; OctreeNode* mOctree; LLViewerRegion* mRegionp; // the region this partition belongs to. + BOOL mOcclusionEnabled; // if TRUE, occlusion culling is performed + U32 mLODSeed; + U32 mLODPeriod; //number of frames between LOD updates for a given spatial group (staggered by mLODSeed) }; class LLViewerOctreeCull : public OctreeTraveler diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index fea44a38c6..eb004106c3 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -594,9 +594,9 @@ public: ypos += y_inc; - if (!LLSpatialGroup::sPendingQueries.empty()) + if (!LLOcclusionCullingGroup::sPendingQueries.empty()) { - addText(xpos,ypos, llformat("%d Queries pending", LLSpatialGroup::sPendingQueries.size())); + addText(xpos,ypos, llformat("%d Queries pending", LLOcclusionCullingGroup::sPendingQueries.size())); ypos += y_inc; } diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index eba768fef4..6261540765 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -372,10 +372,11 @@ void LLVOCacheEntry::setBoundingInfo(const LLVector3& pos, const LLVector3& scal //------------------------------------------------------------------- LLVOCachePartition::LLVOCachePartition(LLViewerRegion* regionp) { + mLODPeriod = 16; mRegionp = regionp; mPartitionType = LLViewerRegion::PARTITION_VO_CACHE; - new LLviewerOctreeGroup(mOctree); + new LLOcclusionCullingGroup(mOctree, this); } void LLVOCachePartition::addEntry(LLViewerOctreeEntry* entry) @@ -400,11 +401,31 @@ public: mLocalShift = shift; } + virtual bool earlyFail(LLviewerOctreeGroup* base_group) + { + LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)base_group; + if(group->needsUpdate()) + { + return false; //needs to issue new occlusion culling check. + } + + group->checkOcclusion(); + + if (group->getOctreeNode()->getParent() && //never occlusion cull the root node + LLPipeline::sUseOcclusion && //ignore occlusion if disabled + group->isOcclusionState(LLSpatialGroup::OCCLUDED)) + { + return true; + } + + return false; + } + virtual S32 frustumCheck(const LLviewerOctreeGroup* group) { - //S32 res = AABBInRegionFrustumGroupBounds(group); + S32 res = AABBInRegionFrustumGroupBounds(group); - S32 res = AABBInRegionFrustumNoFarClipGroupBounds(group); + //S32 res = AABBInRegionFrustumNoFarClipGroupBounds(group); if (res != 0) { res = llmin(res, AABBRegionSphereIntersectGroupExtents(group, mLocalShift)); @@ -414,9 +435,9 @@ public: virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group) { - //S32 res = AABBInRegionFrustumObjectBounds(group); + S32 res = AABBInRegionFrustumObjectBounds(group); - S32 res = AABBInRegionFrustumNoFarClipObjectBounds(group); + //S32 res = AABBInRegionFrustumNoFarClipObjectBounds(group); if (res != 0) { res = llmin(res, AABBRegionSphereIntersectObjectExtents(group, mLocalShift)); @@ -426,7 +447,15 @@ public: virtual void processGroup(LLviewerOctreeGroup* base_group) { - mRegionp->addVisibleGroup(base_group); + LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)base_group; + if (group->needsUpdate() || group->mVisible[LLViewerCamera::sCurCameraID] < LLDrawable::getCurrentFrame() - 1) + { + ((LLOcclusionCullingGroup*)group)->doOcclusion(mCamera); + group->setVisible(); + return; //wait for occlusion culling results + } + + mRegionp->addVisibleGroup(group); } private: diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 12f268d324..d1c1602437 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4190,7 +4190,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) LLVOAvatar* pAvatarVO = NULL; - LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); + LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge(); if (bridge) { if (bridge->mAvatar.isNull()) @@ -4227,10 +4227,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) std::vector simple_faces; std::vector alpha_faces; - U32 useage = group->mSpatialPartition->mBufferUsage; + U32 useage = group->getSpatialPartition()->mBufferUsage; - U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); - U32 max_total = (gSavedSettings.getS32("RenderMaxNodeSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); + U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); + U32 max_total = (gSavedSettings.getS32("RenderMaxNodeSize")*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); max_vertices = llmin(max_vertices, (U32) 65535); U32 cur_total = 0; @@ -4837,7 +4837,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: #endif //calculate maximum number of vertices to store in a single buffer - U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); + U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); max_vertices = llmin(max_vertices, (U32) 65535); { @@ -5228,7 +5228,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count) { //initialize to default usage for this partition - U32 usage = group->mSpatialPartition->mBufferUsage; + U32 usage = group->getSpatialPartition()->mBufferUsage; //clear off any old faces mFaceList.clear(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 1b5148e560..a8156b46ed 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1663,7 +1663,7 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) if (drawablep->getSpatialGroup()) { LLFastTimer t(FTM_REMOVE_FROM_SPATIAL_PARTITION); - if (!drawablep->getSpatialGroup()->mSpatialPartition->remove(drawablep, drawablep->getSpatialGroup())) + if (!drawablep->getSpatialGroup()->getSpatialPartition()->remove(drawablep, drawablep->getSpatialGroup())) { #ifdef LL_RELEASE_FOR_DOWNLOAD llwarns << "Couldn't remove object from spatial group!" << llendl; @@ -2480,7 +2480,7 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) assertInitialized(); - if (!group->mSpatialPartition->mRenderByGroup) + if (!group->getSpatialPartition()->mRenderByGroup) { //render by drawable sCull->pushDrawableGroup(group); } @@ -2729,7 +2729,7 @@ void LLPipeline::rebuildGroups() { group->rebuildGeom(); - if (group->mSpatialPartition->mRenderByGroup) + if (group->getSpatialPartition()->mRenderByGroup) { count++; } @@ -3052,9 +3052,9 @@ void LLPipeline::markMeshDirty(LLSpatialGroup* group) void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) { - if (group && !group->isDead() && group->mSpatialPartition) + if (group && !group->isDead() && group->getSpatialPartition()) { - if (group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_HUD) + if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD) { priority = TRUE; } @@ -3631,7 +3631,7 @@ void LLPipeline::postSort(LLCamera& camera) if (alpha != group->mDrawMap.end()) { //store alpha groups for sorting - LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); + LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge(); if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) { if (bridge) @@ -5202,7 +5202,7 @@ void LLPipeline::renderDebug() continue; } - LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); + LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge(); if (bridge && (!bridge->mDrawable || bridge->mDrawable->isDead())) { @@ -9990,7 +9990,7 @@ void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL textu LLSpatialGroup* group = *i; if (!group->isDead() && (!sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && - gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) && + gPipeline.hasRenderType(group->getSpatialPartition()->mDrawableType) && group->mDrawMap.find(type) != group->mDrawMap.end()) { pass->renderGroup(group,type,mask,texture); -- cgit v1.3 From 9ae76d12157641033431381959ef4f798a119b8d Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 29 May 2013 17:00:50 -0700 Subject: SH-3931 WIP Interesting: Add graphs to visualize scene load metrics fixed copy construction behavior of Recordings to not zero out data split measurement into event and sample, with sample representing a continuous function --- indra/llcommon/llthread.cpp | 2 +- indra/llcommon/llthreadlocalstorage.h | 4 + indra/llcommon/lltrace.cpp | 14 +- indra/llcommon/lltrace.h | 234 +++++++++++++++++++++++++---- indra/llcommon/lltracerecording.cpp | 188 ++++++++++++++++++------ indra/llcommon/lltracerecording.h | 244 ++++++++++++++++++++++++++----- indra/llcommon/lltracethreadrecorder.cpp | 78 +++++----- indra/llcommon/lltracethreadrecorder.h | 13 +- indra/llui/llstatbar.cpp | 118 ++++++++++----- indra/llui/llstatbar.h | 10 +- indra/llui/llstatgraph.h | 10 +- indra/newview/llappviewer.cpp | 2 +- indra/newview/llfloaterjoystick.cpp | 14 +- indra/newview/llscenemonitor.cpp | 57 +++++++- indra/newview/llstartup.cpp | 2 +- indra/newview/llstatusbar.cpp | 2 +- indra/newview/lltexturefetch.cpp | 10 +- indra/newview/lltexturefetch.h | 4 +- indra/newview/llviewerassetstats.cpp | 9 +- indra/newview/llviewerassetstats.h | 2 +- indra/newview/llviewerassetstorage.cpp | 2 +- indra/newview/llviewerobject.cpp | 2 +- indra/newview/llviewerobjectlist.cpp | 2 +- indra/newview/llviewerobjectlist.h | 2 +- indra/newview/llviewerstats.cpp | 125 ++++++++-------- indra/newview/llviewerstats.h | 103 ++++++------- indra/newview/llviewerwindow.cpp | 19 +-- indra/newview/llviewerwindow.h | 4 +- indra/newview/llvoavatarself.cpp | 2 +- indra/newview/pipeline.cpp | 28 +--- indra/newview/pipeline.h | 11 +- 31 files changed, 919 insertions(+), 398 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 6374b5398b..118568d5ef 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -93,7 +93,7 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap { LLThread *threadp = (LLThread *)datap; - LLTrace::ThreadRecorder* thread_recorder = new LLTrace::SlaveThreadRecorder(); + LLTrace::ThreadRecorder* thread_recorder = new LLTrace::SlaveThreadRecorder(LLTrace::getUIThreadRecorder()); #if !LL_DARWIN sThreadID = threadp->mID; diff --git a/indra/llcommon/llthreadlocalstorage.h b/indra/llcommon/llthreadlocalstorage.h index 4873b2740d..471784749b 100644 --- a/indra/llcommon/llthreadlocalstorage.h +++ b/indra/llcommon/llthreadlocalstorage.h @@ -131,6 +131,10 @@ public: if (!sInitialized) return false; return get() == other; } + + bool isNull() const { return !sInitialized || get() == NULL; } + + bool notNull() const { return sInitialized && get() != NULL; } }; template diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp index 463048008f..c831a1548d 100644 --- a/indra/llcommon/lltrace.cpp +++ b/indra/llcommon/lltrace.cpp @@ -35,13 +35,13 @@ static S32 sInitializationCount = 0; namespace LLTrace { -static MasterThreadRecorder* gMasterThreadRecorder = NULL; +static MasterThreadRecorder* gUIThreadRecorder = NULL; void init() { if (sInitializationCount++ == 0) { - gMasterThreadRecorder = new MasterThreadRecorder(); + gUIThreadRecorder = new MasterThreadRecorder(); } } @@ -54,15 +54,15 @@ void cleanup() { if (--sInitializationCount == 0) { - delete gMasterThreadRecorder; - gMasterThreadRecorder = NULL; + delete gUIThreadRecorder; + gUIThreadRecorder = NULL; } } -MasterThreadRecorder& getMasterThreadRecorder() +MasterThreadRecorder& getUIThreadRecorder() { - llassert(gMasterThreadRecorder != NULL); - return *gMasterThreadRecorder; + llassert(gUIThreadRecorder != NULL); + return *gUIThreadRecorder; } LLThreadLocalPointer& get_thread_recorder_ptr() diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index d1edaf969b..f94576de45 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -73,7 +73,7 @@ bool isInitialized(); const LLThreadLocalPointer& get_thread_recorder(); void set_thread_recorder(class ThreadRecorder*); -class MasterThreadRecorder& getMasterThreadRecorder(); +class MasterThreadRecorder& getUIThreadRecorder(); // one per thread per type template @@ -148,6 +148,15 @@ public: } } + void flush() + { + llassert(mStorageSize >= sNextStorageSlot); + for (size_t i = 0; i < sNextStorageSlot; i++) + { + mStorage[i].flush(); + } + } + void makePrimary() { LLThreadLocalSingletonPointer::setInstance(mStorage); @@ -260,14 +269,14 @@ protected: }; template -class MeasurementAccumulator +class EventAccumulator { public: typedef T value_t; typedef F64 mean_t; - typedef MeasurementAccumulator self_t; + typedef EventAccumulator self_t; - MeasurementAccumulator() + EventAccumulator() : mSum(0), mMin((std::numeric_limits::max)()), mMax((std::numeric_limits::min)()), @@ -277,7 +286,7 @@ public: mLastValue(0) {} - void sample(T value) + void record(T value) { mNumSamples++; mSum += value; @@ -301,17 +310,10 @@ public: if (other.mNumSamples) { mSum += other.mSum; - if (other.mMin < mMin) - { - mMin = other.mMin; - } - if (other.mMax > mMax) - { - mMax = other.mMax; - } - F64 weight = (F64)mNumSamples / (F64)(mNumSamples + other.mNumSamples); - mNumSamples += other.mNumSamples; - mMean = mMean * weight + other.mMean * (1.f - weight); + + // NOTE: both conditions will hold first time through + if (other.mMin < mMin) { mMin = other.mMin; } + if (other.mMax > mMax) { mMax = other.mMax; } // combine variance (and hence standard deviation) of 2 different sized sample groups using // the following formula: http://www.mrc-bsu.cam.ac.uk/cochrane/handbook/chapter_7/7_7_3_8_combining_groups.htm @@ -333,12 +335,16 @@ public: else { mVarianceSum = (F64)mNumSamples - * ((((n_1 - 1.f) * v_1) - + ((n_2 - 1.f) * v_2) - + (((n_1 * n_2) / (n_1 + n_2)) - * ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2)))) - / (n_1 + n_2 - 1.f)); + * ((((n_1 - 1.f) * v_1) + + ((n_2 - 1.f) * v_2) + + (((n_1 * n_2) / (n_1 + n_2)) + * ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2)))) + / (n_1 + n_2 - 1.f)); } + + F64 weight = (F64)mNumSamples / (F64)(mNumSamples + other.mNumSamples); + mNumSamples += other.mNumSamples; + mMean = mMean * weight + other.mMean * (1.f - weight); mLastValue = other.mLastValue; } } @@ -347,13 +353,15 @@ public: { mNumSamples = 0; mSum = 0; - mMin = 0; - mMax = 0; + mMin = std::numeric_limits::max(); + mMax = std::numeric_limits::min(); mMean = 0; mVarianceSum = 0; mLastValue = other ? other->mLastValue : 0; } + void flush() {} + T getSum() const { return (T)mSum; } T getMin() const { return (T)mMin; } T getMax() const { return (T)mMax; } @@ -375,6 +383,150 @@ private: }; +template +class SampleAccumulator +{ +public: + typedef T value_t; + typedef F64 mean_t; + typedef SampleAccumulator self_t; + + SampleAccumulator() + : mSum(0), + mMin((std::numeric_limits::max)()), + mMax((std::numeric_limits::min)()), + mMean(0), + mVarianceSum(0), + mLastSampleTimeStamp(LLTimer::getTotalSeconds()), + mTotalSamplingTime(0), + mNumSamples(0), + mLastValue(0), + mHasValue(false) + {} + + void sample(T value) + { + LLUnitImplicit time_stamp = LLTimer::getTotalSeconds(); + LLUnitImplicit delta_time = time_stamp - mLastSampleTimeStamp; + mLastSampleTimeStamp = time_stamp; + + if (mHasValue) + { + mTotalSamplingTime += delta_time; + mSum += (F64)mLastValue * delta_time; + + // NOTE: both conditions will hold first time through + if (value < mMin) { mMin = value; } + if (value > mMax) { mMax = value; } + + F64 old_mean = mMean; + mMean += (delta_time / mTotalSamplingTime) * ((F64)mLastValue - old_mean); + mVarianceSum += delta_time * ((F64)mLastValue - old_mean) * ((F64)mLastValue - mMean); + } + + mLastValue = value; + mNumSamples++; + mHasValue = true; + } + + void addSamples(const self_t& other) + { + if (other.mTotalSamplingTime) + { + mSum += other.mSum; + + // NOTE: both conditions will hold first time through + if (other.mMin < mMin) { mMin = other.mMin; } + if (other.mMax > mMax) { mMax = other.mMax; } + + // combine variance (and hence standard deviation) of 2 different sized sample groups using + // the following formula: http://www.mrc-bsu.cam.ac.uk/cochrane/handbook/chapter_7/7_7_3_8_combining_groups.htm + F64 n_1 = mTotalSamplingTime, + n_2 = other.mTotalSamplingTime; + F64 m_1 = mMean, + m_2 = other.mMean; + F64 v_1 = mVarianceSum / mTotalSamplingTime, + v_2 = other.mVarianceSum / other.mTotalSamplingTime; + if (n_1 == 0) + { + mVarianceSum = other.mVarianceSum; + } + else if (n_2 == 0) + { + // variance is unchanged + // mVarianceSum = mVarianceSum; + } + else + { + mVarianceSum = mTotalSamplingTime + * ((((n_1 - 1.f) * v_1) + + ((n_2 - 1.f) * v_2) + + (((n_1 * n_2) / (n_1 + n_2)) + * ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2)))) + / (n_1 + n_2 - 1.f)); + } + + llassert(other.mTotalSamplingTime > 0); + F64 weight = mTotalSamplingTime / (mTotalSamplingTime + other.mTotalSamplingTime); + mNumSamples += other.mNumSamples; + mTotalSamplingTime += other.mTotalSamplingTime; + mMean = (mMean * weight) + (other.mMean * (1.0 - weight)); + mLastValue = other.mLastValue; + mLastSampleTimeStamp = other.mLastSampleTimeStamp; + mHasValue |= other.mHasValue; + } + } + + void reset(const self_t* other) + { + mNumSamples = 0; + mSum = 0; + mMin = std::numeric_limits::max(); + mMax = std::numeric_limits::min(); + mMean = other ? other->mLastValue : 0; + mVarianceSum = 0; + mLastSampleTimeStamp = LLTimer::getTotalSeconds(); + mTotalSamplingTime = 0; + mLastValue = other ? other->mLastValue : 0; + mHasValue = other ? other->mHasValue : false; + } + + void flush() + { + LLUnitImplicit time_stamp = LLTimer::getTotalSeconds(); + LLUnitImplicit delta_time = time_stamp - mLastSampleTimeStamp; + + mSum += (F64)mLastValue * delta_time; + + mTotalSamplingTime += delta_time; + mLastSampleTimeStamp = time_stamp; + } + + T getSum() const { return (T)mSum; } + T getMin() const { return (T)mMin; } + T getMax() const { return (T)mMax; } + T getLastValue() const { return (T)mLastValue; } + F64 getMean() const { return mMean; } + F64 getStandardDeviation() const { return sqrtf(mVarianceSum / mTotalSamplingTime); } + U32 getSampleCount() const { return mNumSamples; } + +private: + T mSum, + mMin, + mMax, + mLastValue; + + bool mHasValue; + + F64 mMean, + mVarianceSum; + + LLUnitImplicit mLastSampleTimeStamp, + mTotalSamplingTime; + + U32 mNumSamples; +}; + template class CountAccumulator { @@ -406,6 +558,8 @@ public: mSum = 0; } + void flush() {} + T getSum() const { return (T)mSum; } U32 getSampleCount() const { return mNumSamples; } @@ -439,6 +593,7 @@ public: TimeBlockAccumulator(); void addSamples(const self_t& other); void reset(const self_t* other); + void flush() {} // // members @@ -493,25 +648,44 @@ public: template -class MeasurementStatHandle -: public TraceType::type_t> > +class EventStatHandle +: public TraceType::type_t> > { public: typedef typename LLUnits::HighestPrecisionType::type_t storage_t; - typedef TraceType::type_t> > trace_t; + typedef TraceType::type_t> > trace_t; - MeasurementStatHandle(const char* name, const char* description = NULL) + EventStatHandle(const char* name, const char* description = NULL) : trace_t(name, description) {} }; template -void sample(MeasurementStatHandle& measurement, VALUE_T value) +void record(EventStatHandle& measurement, VALUE_T value) { T converted_value(value); - measurement.getPrimaryAccumulator()->sample(LLUnits::rawValue(converted_value)); + measurement.getPrimaryAccumulator()->record(LLUnits::rawValue(converted_value)); } +template +class SampleStatHandle +: public TraceType::type_t> > +{ +public: + typedef typename LLUnits::HighestPrecisionType::type_t storage_t; + typedef TraceType::type_t> > trace_t; + + SampleStatHandle(const char* name, const char* description = NULL) + : trace_t(name, description) + {} +}; + +template +void sample(SampleStatHandle& measurement, VALUE_T value) +{ + T converted_value(value); + measurement.getPrimaryAccumulator()->sample(LLUnits::rawValue(converted_value)); +} template class CountStatHandle @@ -560,6 +734,8 @@ struct MemStatAccumulator mDeallocatedCount = 0; } + void flush() {} + size_t mSize, mChildSize; int mAllocatedCount, diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index cced6546ba..5b0b74524f 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -45,9 +45,11 @@ RecordingBuffers::RecordingBuffers() void RecordingBuffers::handOffTo(RecordingBuffers& other) { other.mCountsFloat.reset(&mCountsFloat); - other.mMeasurementsFloat.reset(&mMeasurementsFloat); other.mCounts.reset(&mCounts); - other.mMeasurements.reset(&mMeasurements); + other.mSamplesFloat.reset(&mSamplesFloat); + other.mSamples.reset(&mSamples); + other.mEventsFloat.reset(&mEventsFloat); + other.mEvents.reset(&mEvents); other.mStackTimers.reset(&mStackTimers); other.mMemStats.reset(&mMemStats); } @@ -55,9 +57,11 @@ void RecordingBuffers::handOffTo(RecordingBuffers& other) void RecordingBuffers::makePrimary() { mCountsFloat.makePrimary(); - mMeasurementsFloat.makePrimary(); mCounts.makePrimary(); - mMeasurements.makePrimary(); + mSamplesFloat.makePrimary(); + mSamples.makePrimary(); + mEventsFloat.makePrimary(); + mEvents.makePrimary(); mStackTimers.makePrimary(); mMemStats.makePrimary(); @@ -82,9 +86,11 @@ bool RecordingBuffers::isPrimary() const void RecordingBuffers::append( const RecordingBuffers& other ) { mCountsFloat.addSamples(other.mCountsFloat); - mMeasurementsFloat.addSamples(other.mMeasurementsFloat); mCounts.addSamples(other.mCounts); - mMeasurements.addSamples(other.mMeasurements); + mSamplesFloat.addSamples(other.mSamplesFloat); + mSamples.addSamples(other.mSamples); + mEventsFloat.addSamples(other.mEventsFloat); + mEvents.addSamples(other.mEvents); mMemStats.addSamples(other.mMemStats); mStackTimers.addSamples(other.mStackTimers); } @@ -92,22 +98,32 @@ void RecordingBuffers::append( const RecordingBuffers& other ) void RecordingBuffers::merge( const RecordingBuffers& other) { mCountsFloat.addSamples(other.mCountsFloat); - mMeasurementsFloat.addSamples(other.mMeasurementsFloat); mCounts.addSamples(other.mCounts); - mMeasurements.addSamples(other.mMeasurements); + mSamplesFloat.addSamples(other.mSamplesFloat); + mSamples.addSamples(other.mSamples); + mEventsFloat.addSamples(other.mEventsFloat); + mEvents.addSamples(other.mEvents); mMemStats.addSamples(other.mMemStats); } void RecordingBuffers::reset(RecordingBuffers* other) { mCountsFloat.reset(other ? &other->mCountsFloat : NULL); - mMeasurementsFloat.reset(other ? &other->mMeasurementsFloat : NULL); mCounts.reset(other ? &other->mCounts : NULL); - mMeasurements.reset(other ? &other->mMeasurements : NULL); + mSamplesFloat.reset(other ? &other->mSamplesFloat : NULL); + mSamples.reset(other ? &other->mSamples : NULL); + mEventsFloat.reset(other ? &other->mEventsFloat : NULL); + mEvents.reset(other ? &other->mEvents : NULL); mStackTimers.reset(other ? &other->mStackTimers : NULL); mMemStats.reset(other ? &other->mMemStats : NULL); } +void RecordingBuffers::flush() +{ + mSamplesFloat.flush(); + mSamples.flush(); +} + /////////////////////////////////////////////////////////////////////// // Recording /////////////////////////////////////////////////////////////////////// @@ -120,6 +136,9 @@ Recording::Recording() Recording::Recording( const Recording& other ) { + // this will allow us to seamlessly start without affecting any data we've acquired from other + setPlayState(PAUSED); + Recording& mutable_other = const_cast(other); EPlayState other_play_state = other.getPlayState(); mutable_other.pause(); @@ -137,15 +156,18 @@ Recording::Recording( const Recording& other ) Recording::~Recording() { - stop(); - llassert(isStopped()); + if (isStarted() && LLTrace::get_thread_recorder().notNull()) + { + LLTrace::get_thread_recorder()->deactivate(this); + } } void Recording::update() { if (isStarted()) { - LLTrace::get_thread_recorder()->update(this); + mBuffers.write()->flush(); + LLTrace::get_thread_recorder()->bringUpToDate(this); mSamplingTimer.reset(); } } @@ -167,6 +189,7 @@ void Recording::handleStart() void Recording::handleStop() { mElapsedSeconds += mSamplingTimer.getElapsedTimeF64(); + mBuffers.write()->flush(); LLTrace::TimeBlock::processTimes(); LLTrace::get_thread_recorder()->deactivate(this); } @@ -178,13 +201,23 @@ void Recording::handleSplitTo(Recording& other) void Recording::appendRecording( const Recording& other ) { - mBuffers.write()->append(*other.mBuffers); - mElapsedSeconds += other.mElapsedSeconds; + EPlayState play_state = getPlayState(); + { + pause(); + mBuffers.write()->append(*other.mBuffers); + mElapsedSeconds += other.mElapsedSeconds; + } + setPlayState(play_state); } void Recording::mergeRecording( const Recording& other) { - mBuffers.write()->merge(*other.mBuffers); + EPlayState play_state = getPlayState(); + { + pause(); + mBuffers.write()->merge(*other.mBuffers); + } + setPlayState(play_state); } LLUnit Recording::getSum(const TraceType& stat) const @@ -248,14 +281,14 @@ S64 Recording::getSum( const TraceType >& stat ) const return mBuffers->mCounts[stat.getIndex()].getSum(); } -F64 Recording::getSum( const TraceType >& stat ) const +F64 Recording::getSum( const TraceType >& stat ) const { - return (F64)mBuffers->mMeasurementsFloat[stat.getIndex()].getSum(); + return (F64)mBuffers->mEventsFloat[stat.getIndex()].getSum(); } -S64 Recording::getSum( const TraceType >& stat ) const +S64 Recording::getSum( const TraceType >& stat ) const { - return (S64)mBuffers->mMeasurements[stat.getIndex()].getSum(); + return (S64)mBuffers->mEvents[stat.getIndex()].getSum(); } @@ -283,67 +316,127 @@ U32 Recording::getSampleCount( const TraceType >& stat ) c U32 Recording::getSampleCount( const TraceType >& stat ) const { - return mBuffers->mMeasurementsFloat[stat.getIndex()].getSampleCount(); + return mBuffers->mCounts[stat.getIndex()].getSampleCount(); +} + +F64 Recording::getMin( const TraceType >& stat ) const +{ + return mBuffers->mSamplesFloat[stat.getIndex()].getMin(); +} + +S64 Recording::getMin( const TraceType >& stat ) const +{ + return mBuffers->mSamples[stat.getIndex()].getMin(); +} + +F64 Recording::getMax( const TraceType >& stat ) const +{ + return mBuffers->mSamplesFloat[stat.getIndex()].getMax(); +} + +S64 Recording::getMax( const TraceType >& stat ) const +{ + return mBuffers->mSamples[stat.getIndex()].getMax(); +} + +F64 Recording::getMean( const TraceType >& stat ) const +{ + return mBuffers->mSamplesFloat[stat.getIndex()].getMean(); +} + +F64 Recording::getMean( const TraceType >& stat ) const +{ + return mBuffers->mSamples[stat.getIndex()].getMean(); } -F64 Recording::getMin( const TraceType >& stat ) const +F64 Recording::getStandardDeviation( const TraceType >& stat ) const { - return mBuffers->mMeasurementsFloat[stat.getIndex()].getMin(); + return mBuffers->mSamplesFloat[stat.getIndex()].getStandardDeviation(); } -S64 Recording::getMin( const TraceType >& stat ) const +F64 Recording::getStandardDeviation( const TraceType >& stat ) const { - return mBuffers->mMeasurements[stat.getIndex()].getMin(); + return mBuffers->mSamples[stat.getIndex()].getStandardDeviation(); } -F64 Recording::getMax( const TraceType >& stat ) const +F64 Recording::getLastValue( const TraceType >& stat ) const { - return mBuffers->mMeasurementsFloat[stat.getIndex()].getMax(); + return mBuffers->mSamplesFloat[stat.getIndex()].getLastValue(); } -S64 Recording::getMax( const TraceType >& stat ) const +S64 Recording::getLastValue( const TraceType >& stat ) const { - return mBuffers->mMeasurements[stat.getIndex()].getMax(); + return mBuffers->mSamples[stat.getIndex()].getLastValue(); } -F64 Recording::getMean( const TraceType >& stat ) const +U32 Recording::getSampleCount( const TraceType >& stat ) const { - return mBuffers->mMeasurementsFloat[stat.getIndex()].getMean(); + return mBuffers->mSamplesFloat[stat.getIndex()].getSampleCount(); } -F64 Recording::getMean( const TraceType >& stat ) const +U32 Recording::getSampleCount( const TraceType >& stat ) const { - return mBuffers->mMeasurements[stat.getIndex()].getMean(); + return mBuffers->mSamples[stat.getIndex()].getSampleCount(); } -F64 Recording::getStandardDeviation( const TraceType >& stat ) const +F64 Recording::getMin( const TraceType >& stat ) const { - return mBuffers->mMeasurementsFloat[stat.getIndex()].getStandardDeviation(); + return mBuffers->mEventsFloat[stat.getIndex()].getMin(); } -F64 Recording::getStandardDeviation( const TraceType >& stat ) const +S64 Recording::getMin( const TraceType >& stat ) const { - return mBuffers->mMeasurements[stat.getIndex()].getStandardDeviation(); + return mBuffers->mEvents[stat.getIndex()].getMin(); } -F64 Recording::getLastValue( const TraceType >& stat ) const +F64 Recording::getMax( const TraceType >& stat ) const { - return mBuffers->mMeasurementsFloat[stat.getIndex()].getLastValue(); + return mBuffers->mEventsFloat[stat.getIndex()].getMax(); } -S64 Recording::getLastValue( const TraceType >& stat ) const +S64 Recording::getMax( const TraceType >& stat ) const { - return mBuffers->mMeasurements[stat.getIndex()].getLastValue(); + return mBuffers->mEvents[stat.getIndex()].getMax(); } -U32 Recording::getSampleCount( const TraceType >& stat ) const +F64 Recording::getMean( const TraceType >& stat ) const { - return mBuffers->mMeasurementsFloat[stat.getIndex()].getSampleCount(); + return mBuffers->mEventsFloat[stat.getIndex()].getMean(); } -U32 Recording::getSampleCount( const TraceType >& stat ) const +F64 Recording::getMean( const TraceType >& stat ) const { - return mBuffers->mMeasurements[stat.getIndex()].getSampleCount(); + return mBuffers->mEvents[stat.getIndex()].getMean(); +} + +F64 Recording::getStandardDeviation( const TraceType >& stat ) const +{ + return mBuffers->mEventsFloat[stat.getIndex()].getStandardDeviation(); +} + +F64 Recording::getStandardDeviation( const TraceType >& stat ) const +{ + return mBuffers->mEvents[stat.getIndex()].getStandardDeviation(); +} + +F64 Recording::getLastValue( const TraceType >& stat ) const +{ + return mBuffers->mEventsFloat[stat.getIndex()].getLastValue(); +} + +S64 Recording::getLastValue( const TraceType >& stat ) const +{ + return mBuffers->mEvents[stat.getIndex()].getLastValue(); +} + +U32 Recording::getSampleCount( const TraceType >& stat ) const +{ + return mBuffers->mEventsFloat[stat.getIndex()].getSampleCount(); +} + +U32 Recording::getSampleCount( const TraceType >& stat ) const +{ + return mBuffers->mEvents[stat.getIndex()].getSampleCount(); } /////////////////////////////////////////////////////////////////////// @@ -377,7 +470,7 @@ void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other ) if (other.mRecordingPeriods.empty()) return; EPlayState play_state = getPlayState(); - stop(); + pause(); EPlayState other_play_state = other.getPlayState(); other.pause(); @@ -466,8 +559,7 @@ LLTrace::Recording PeriodicRecording::snapshotCurRecording() const Recording& PeriodicRecording::getLastRecording() { - U32 num_periods = mRecordingPeriods.size(); - return mRecordingPeriods[(mCurPeriod + num_periods - 1) % num_periods]; + return getPrevRecording(1); } const Recording& PeriodicRecording::getLastRecording() const diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index b339e72e5c..19a4fae737 100644 --- a/indra/llcommon/lltracerecording.h +++ b/indra/llcommon/lltracerecording.h @@ -117,11 +117,14 @@ namespace LLTrace void append(const RecordingBuffers& other); void merge(const RecordingBuffers& other); void reset(RecordingBuffers* other = NULL); + void flush(); AccumulatorBuffer > mCountsFloat; - AccumulatorBuffer > mMeasurementsFloat; AccumulatorBuffer > mCounts; - AccumulatorBuffer > mMeasurements; + AccumulatorBuffer > mSamplesFloat; + AccumulatorBuffer > mSamples; + AccumulatorBuffer > mEventsFloat; + AccumulatorBuffer > mEvents; AccumulatorBuffer mStackTimers; AccumulatorBuffer mMemStats; }; @@ -181,57 +184,101 @@ namespace LLTrace U32 getSampleCount(const TraceType >& stat) const; - // MeasurementStatHandle accessors - F64 getSum(const TraceType >& stat) const; - S64 getSum(const TraceType >& stat) const; + // SampleStatHandle accessors + F64 getMin(const TraceType >& stat) const; + S64 getMin(const TraceType >& stat) const; template - T getSum(const MeasurementStatHandle& stat) const + T getMin(const SampleStatHandle& stat) const { - return (T)getSum(static_cast::type_t> >&> (stat)); + return (T)getMin(static_cast::type_t> >&> (stat)); } - F64 getMin(const TraceType >& stat) const; - S64 getMin(const TraceType >& stat) const; + F64 getMax(const TraceType >& stat) const; + S64 getMax(const TraceType >& stat) const; template - T getMin(const MeasurementStatHandle& stat) const + T getMax(const SampleStatHandle& stat) const { - return (T)getMin(static_cast::type_t> >&> (stat)); + return (T)getMax(static_cast::type_t> >&> (stat)); } - F64 getMax(const TraceType >& stat) const; - S64 getMax(const TraceType >& stat) const; + F64 getMean(const TraceType >& stat) const; + F64 getMean(const TraceType >& stat) const; template - T getMax(const MeasurementStatHandle& stat) const + T getMean(SampleStatHandle& stat) const { - return (T)getMax(static_cast::type_t> >&> (stat)); + return (T)getMean(static_cast::type_t> >&> (stat)); } - F64 getMean(const TraceType >& stat) const; - F64 getMean(const TraceType >& stat) const; + F64 getStandardDeviation(const TraceType >& stat) const; + F64 getStandardDeviation(const TraceType >& stat) const; template - T getMean(MeasurementStatHandle& stat) const + T getStandardDeviation(const SampleStatHandle& stat) const { - return (T)getMean(static_cast::type_t> >&> (stat)); + return (T)getStandardDeviation(static_cast::type_t> >&> (stat)); } - F64 getStandardDeviation(const TraceType >& stat) const; - F64 getStandardDeviation(const TraceType >& stat) const; + F64 getLastValue(const TraceType >& stat) const; + S64 getLastValue(const TraceType >& stat) const; template - T getStandardDeviation(const MeasurementStatHandle& stat) const + T getLastValue(const SampleStatHandle& stat) const { - return (T)getMean(static_cast::type_t> >&> (stat)); + return (T)getLastValue(static_cast::type_t> >&> (stat)); } - F64 getLastValue(const TraceType >& stat) const; - S64 getLastValue(const TraceType >& stat) const; + U32 getSampleCount(const TraceType >& stat) const; + U32 getSampleCount(const TraceType >& stat) const; + + // EventStatHandle accessors + F64 getSum(const TraceType >& stat) const; + S64 getSum(const TraceType >& stat) const; + template + T getSum(const EventStatHandle& stat) const + { + return (T)getSum(static_cast::type_t> >&> (stat)); + } + + F64 getMin(const TraceType >& stat) const; + S64 getMin(const TraceType >& stat) const; + template + T getMin(const EventStatHandle& stat) const + { + return (T)getMin(static_cast::type_t> >&> (stat)); + } + + F64 getMax(const TraceType >& stat) const; + S64 getMax(const TraceType >& stat) const; + template + T getMax(const EventStatHandle& stat) const + { + return (T)getMax(static_cast::type_t> >&> (stat)); + } + + F64 getMean(const TraceType >& stat) const; + F64 getMean(const TraceType >& stat) const; + template + T getMean(EventStatHandle& stat) const + { + return (T)getMean(static_cast::type_t> >&> (stat)); + } + + F64 getStandardDeviation(const TraceType >& stat) const; + F64 getStandardDeviation(const TraceType >& stat) const; + template + T getStandardDeviation(const EventStatHandle& stat) const + { + return (T)getStandardDeviation(static_cast::type_t> >&> (stat)); + } + + F64 getLastValue(const TraceType >& stat) const; + S64 getLastValue(const TraceType >& stat) const; template - T getLastValue(const MeasurementStatHandle& stat) const + T getLastValue(const EventStatHandle& stat) const { - return (T)getLastValue(static_cast::type_t> >&> (stat)); + return (T)getLastValue(static_cast::type_t> >&> (stat)); } - U32 getSampleCount(const TraceType >& stat) const; - U32 getSampleCount(const TraceType >& stat) const; + U32 getSampleCount(const TraceType >& stat) const; + U32 getSampleCount(const TraceType >& stat) const; LLUnit getDuration() const { return LLUnit(mElapsedSeconds); } @@ -272,13 +319,14 @@ namespace LLTrace const Recording& getPrevRecording(U32 offset) const; Recording snapshotCurRecording() const; + // catch all for stats that have a defined sum template typename T::value_t getPeriodMin(const TraceType& stat, size_t num_periods = U32_MAX) const { size_t total_periods = mRecordingPeriods.size(); num_periods = llmin(num_periods, total_periods); - typename T::value_t min_val = (std::numeric_limits::max)(); + typename T::value_t min_val = std::numeric_limits::max(); for (S32 i = 1; i <= num_periods; i++) { S32 index = (mCurPeriod + total_periods - i) % total_periods; @@ -287,13 +335,43 @@ namespace LLTrace return min_val; } + template + typename T getPeriodMin(const TraceType >& stat, size_t num_periods = U32_MAX) const + { + size_t total_periods = mRecordingPeriods.size(); + num_periods = llmin(num_periods, total_periods); + + typename T min_val = std::numeric_limits::max(); + for (S32 i = 1; i <= num_periods; i++) + { + S32 index = (mCurPeriod + total_periods - i) % total_periods; + min_val = llmin(min_val, mRecordingPeriods[index].getMin(stat)); + } + return min_val; + } + + template + typename T getPeriodMin(const TraceType >& stat, size_t num_periods = U32_MAX) const + { + size_t total_periods = mRecordingPeriods.size(); + num_periods = llmin(num_periods, total_periods); + + typename T min_val = std::numeric_limits::max(); + for (S32 i = 1; i <= num_periods; i++) + { + S32 index = (mCurPeriod + total_periods - i) % total_periods; + min_val = llmin(min_val, mRecordingPeriods[index].getMin(stat)); + } + return min_val; + } + template F64 getPeriodMinPerSec(const TraceType& stat, size_t num_periods = U32_MAX) const { size_t total_periods = mRecordingPeriods.size(); num_periods = llmin(num_periods, total_periods); - F64 min_val = (std::numeric_limits::max)(); + F64 min_val = std::numeric_limits::max(); for (S32 i = 1; i <= num_periods; i++) { S32 index = (mCurPeriod + total_periods - i) % total_periods; @@ -302,13 +380,14 @@ namespace LLTrace return min_val; } + // catch all for stats that have a defined sum template typename T::value_t getPeriodMax(const TraceType& stat, size_t num_periods = U32_MAX) const { size_t total_periods = mRecordingPeriods.size(); num_periods = llmin(num_periods, total_periods); - typename T::value_t max_val = (std::numeric_limits::min)(); + typename T::value_t max_val = std::numeric_limits::min(); for (S32 i = 1; i <= num_periods; i++) { S32 index = (mCurPeriod + total_periods - i) % total_periods; @@ -317,13 +396,43 @@ namespace LLTrace return max_val; } + template + typename T getPeriodMax(const TraceType >& stat, size_t num_periods = U32_MAX) const + { + size_t total_periods = mRecordingPeriods.size(); + num_periods = llmin(num_periods, total_periods); + + typename T max_val = std::numeric_limits::min(); + for (S32 i = 1; i <= num_periods; i++) + { + S32 index = (mCurPeriod + total_periods - i) % total_periods; + max_val = llmax(max_val, mRecordingPeriods[index].getMax(stat)); + } + return max_val; + } + + template + typename T getPeriodMax(const TraceType >& stat, size_t num_periods = U32_MAX) const + { + size_t total_periods = mRecordingPeriods.size(); + num_periods = llmin(num_periods, total_periods); + + typename T max_val = std::numeric_limits::min(); + for (S32 i = 1; i <= num_periods; i++) + { + S32 index = (mCurPeriod + total_periods - i) % total_periods; + max_val = llmax(max_val, mRecordingPeriods[index].getMax(stat)); + } + return max_val; + } + template F64 getPeriodMaxPerSec(const TraceType& stat, size_t num_periods = U32_MAX) const { size_t total_periods = mRecordingPeriods.size(); num_periods = llmin(num_periods, total_periods); - F64 max_val = (std::numeric_limits::min)(); + F64 max_val = std::numeric_limits::min(); for (S32 i = 1; i <= num_periods; i++) { S32 index = (mCurPeriod + total_periods - i) % total_periods; @@ -332,13 +441,14 @@ namespace LLTrace return max_val; } + // catch all for stats that have a defined sum template - typename T::mean_t getPeriodMean(const TraceType& stat, size_t num_periods = U32_MAX) const + typename T::mean_t getPeriodMean(const TraceType& stat, size_t num_periods = U32_MAX) const { size_t total_periods = mRecordingPeriods.size(); num_periods = llmin(num_periods, total_periods); - typename T::mean_t mean = typename T::mean_t(); + typename T::mean_t mean = 0; if (num_periods <= 0) { return mean; } for (S32 i = 1; i <= num_periods; i++) @@ -349,7 +459,65 @@ namespace LLTrace mean += mRecordingPeriods[index].getSum(stat); } } - mean /= num_periods; + mean = mean / num_periods; + return mean; + } + + template + typename SampleAccumulator::mean_t getPeriodMean(const TraceType >& stat, size_t num_periods = U32_MAX) const + { + size_t total_periods = mRecordingPeriods.size(); + num_periods = llmin(num_periods, total_periods); + + LLUnit total_duration = 0.f; + + typename SampleAccumulator::mean_t mean = 0; + if (num_periods <= 0) { return mean; } + + for (S32 i = 1; i <= num_periods; i++) + { + S32 index = (mCurPeriod + total_periods - i) % total_periods; + if (mRecordingPeriods[index].getDuration() > 0.f) + { + LLUnit recording_duration = mRecordingPeriods[index].getDuration(); + mean += mRecordingPeriods[index].getMean(stat) * recording_duration.value(); + total_duration += recording_duration; + } + } + + if (total_duration.value()) + { + mean = mean / total_duration; + } + return mean; + } + + template + typename EventAccumulator::mean_t getPeriodMean(const TraceType >& stat, size_t num_periods = U32_MAX) const + { + size_t total_periods = mRecordingPeriods.size(); + num_periods = llmin(num_periods, total_periods); + + typename EventAccumulator::mean_t mean = 0; + if (num_periods <= 0) { return mean; } + + S32 total_sample_count = 0; + + for (S32 i = 1; i <= num_periods; i++) + { + S32 index = (mCurPeriod + total_periods - i) % total_periods; + if (mRecordingPeriods[index].getDuration() > 0.f) + { + S32 period_sample_count = mRecordingPeriods[index].getSampleCount(stat); + mean += mRecordingPeriods[index].getMean(stat) * period_sample_count; + total_sample_count += period_sample_count; + } + } + + if (total_sample_count) + { + mean = mean / total_sample_count; + } return mean; } @@ -359,7 +527,7 @@ namespace LLTrace size_t total_periods = mRecordingPeriods.size(); num_periods = llmin(num_periods, total_periods); - typename T::mean_t mean = typename T::mean_t(); + typename T::mean_t mean = 0; if (num_periods <= 0) { return mean; } for (S32 i = 1; i <= num_periods; i++) @@ -370,7 +538,7 @@ namespace LLTrace mean += mRecordingPeriods[index].getPerSec(stat); } } - mean /= num_periods; + mean = mean / num_periods; return mean; } diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 2001b9cd7f..75c7cb2ff1 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -74,10 +74,12 @@ ThreadRecorder::~ThreadRecorder() { delete mRootTimer; - while(mActiveRecordings.size()) + if (!mActiveRecordings.empty()) { - mActiveRecordings.front()->mTargetRecording->stop(); + std::for_each(mActiveRecordings.begin(), mActiveRecordings.end(), DeletePointer()); + mActiveRecordings.clear(); } + set_thread_recorder(NULL); delete[] mTimeBlockTreeNodes; } @@ -97,34 +99,40 @@ void ThreadRecorder::activate( Recording* recording ) ActiveRecording* active_recording = new ActiveRecording(recording); if (!mActiveRecordings.empty()) { - mActiveRecordings.front()->mPartialRecording.handOffTo(active_recording->mPartialRecording); + mActiveRecordings.back()->mPartialRecording.handOffTo(active_recording->mPartialRecording); } - mActiveRecordings.push_front(active_recording); + mActiveRecordings.push_back(active_recording); - mActiveRecordings.front()->mPartialRecording.makePrimary(); + mActiveRecordings.back()->mPartialRecording.makePrimary(); } -ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::update( Recording* recording ) +ThreadRecorder::active_recording_list_t::reverse_iterator ThreadRecorder::bringUpToDate( Recording* recording ) { - active_recording_list_t::iterator it, end_it; - for (it = mActiveRecordings.begin(), end_it = mActiveRecordings.end(); + if (mActiveRecordings.empty()) return mActiveRecordings.rend(); + + mActiveRecordings.back()->mPartialRecording.flush(); + + active_recording_list_t::reverse_iterator it, end_it; + for (it = mActiveRecordings.rbegin(), end_it = mActiveRecordings.rend(); it != end_it; ++it) { - active_recording_list_t::iterator next_it = it; + ActiveRecording* cur_recording = *it; + + active_recording_list_t::reverse_iterator next_it = it; ++next_it; // if we have another recording further down in the stack... - if (next_it != mActiveRecordings.end()) + if (next_it != mActiveRecordings.rend()) { // ...push our gathered data down to it - (*next_it)->mPartialRecording.append((*it)->mPartialRecording); + (*next_it)->mPartialRecording.append(cur_recording->mPartialRecording); } // copy accumulated measurements into result buffer and clear accumulator (mPartialRecording) - (*it)->moveBaselineToTarget(); + cur_recording->movePartialToTarget(); - if ((*it)->mTargetRecording == recording) + if (cur_recording->mTargetRecording == recording) { // found the recording, so return it break; @@ -139,28 +147,30 @@ ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::update( Record return it; } -AccumulatorBuffer > gCountsFloat; -AccumulatorBuffer > gMeasurementsFloat; -AccumulatorBuffer > gCounts; -AccumulatorBuffer > gMeasurements; -AccumulatorBuffer gStackTimers; -AccumulatorBuffer gMemStats; +AccumulatorBuffer > gCountsFloat; +AccumulatorBuffer > gMeasurementsFloat; +AccumulatorBuffer > gCounts; +AccumulatorBuffer > gMeasurements; +AccumulatorBuffer gStackTimers; +AccumulatorBuffer gMemStats; void ThreadRecorder::deactivate( Recording* recording ) { - active_recording_list_t::iterator it = update(recording); - if (it != mActiveRecordings.end()) + active_recording_list_t::reverse_iterator it = bringUpToDate(recording); + if (it != mActiveRecordings.rend()) { // and if we've found the recording we wanted to update - active_recording_list_t::iterator next_it = it; + active_recording_list_t::reverse_iterator next_it = it; ++next_it; - if (next_it != mActiveRecordings.end()) + if (next_it != mActiveRecordings.rend()) { - (*next_it)->mTargetRecording->mBuffers.write()->makePrimary(); + (*next_it)->mPartialRecording.makePrimary(); } - delete *it; - mActiveRecordings.erase(it); + active_recording_list_t::iterator recording_to_remove = (++it).base(); + llassert((*recording_to_remove)->mTargetRecording == recording); + delete *recording_to_remove; + mActiveRecordings.erase(recording_to_remove); } } @@ -169,10 +179,11 @@ ThreadRecorder::ActiveRecording::ActiveRecording( Recording* target ) { } -void ThreadRecorder::ActiveRecording::moveBaselineToTarget() +void ThreadRecorder::ActiveRecording::movePartialToTarget() { mTargetRecording->mBuffers.write()->append(mPartialRecording); - mPartialRecording.reset(); + // reset based on self to keep history + mPartialRecording.reset(&mPartialRecording); } @@ -180,21 +191,22 @@ void ThreadRecorder::ActiveRecording::moveBaselineToTarget() // SlaveThreadRecorder /////////////////////////////////////////////////////////////////////// -SlaveThreadRecorder::SlaveThreadRecorder() +SlaveThreadRecorder::SlaveThreadRecorder(MasterThreadRecorder& master) +: mMasterRecorder(master) { - getMasterThreadRecorder().addSlaveThread(this); + mMasterRecorder.addSlaveThread(this); } SlaveThreadRecorder::~SlaveThreadRecorder() { - getMasterThreadRecorder().removeSlaveThread(this); + mMasterRecorder.removeSlaveThread(this); } void SlaveThreadRecorder::pushToMaster() { mThreadRecording.stop(); { - LLMutexLock(getMasterThreadRecorder().getSlaveListMutex()); + LLMutexLock(mMasterRecorder.getSlaveListMutex()); mSharedData.appendFrom(mThreadRecording); } mThreadRecording.start(); @@ -243,7 +255,7 @@ void MasterThreadRecorder::pullFromSlaveThreads() LLMutexLock lock(&mSlaveListMutex); - RecordingBuffers& target_recording_buffers = mActiveRecordings.front()->mPartialRecording; + RecordingBuffers& target_recording_buffers = mActiveRecordings.back()->mPartialRecording; for (slave_thread_recorder_list_t::iterator it = mSlaveThreadRecorders.begin(), end_it = mSlaveThreadRecorders.end(); it != end_it; ++it) diff --git a/indra/llcommon/lltracethreadrecorder.h b/indra/llcommon/lltracethreadrecorder.h index c44bcbd12d..17a2d4a9a9 100644 --- a/indra/llcommon/lltracethreadrecorder.h +++ b/indra/llcommon/lltracethreadrecorder.h @@ -39,15 +39,15 @@ namespace LLTrace { protected: struct ActiveRecording; - typedef std::list active_recording_list_t; + typedef std::vector active_recording_list_t; public: ThreadRecorder(); virtual ~ThreadRecorder(); void activate(Recording* recording); - active_recording_list_t::iterator update(Recording* recording); void deactivate(Recording* recording); + active_recording_list_t::reverse_iterator bringUpToDate(Recording* recording); virtual void pushToMaster() = 0; @@ -58,10 +58,10 @@ namespace LLTrace { ActiveRecording(Recording* target); - Recording* mTargetRecording; + Recording* mTargetRecording; RecordingBuffers mPartialRecording; - void moveBaselineToTarget(); + void movePartialToTarget(); }; Recording mThreadRecording; @@ -98,7 +98,7 @@ namespace LLTrace class LL_COMMON_API SlaveThreadRecorder : public ThreadRecorder { public: - SlaveThreadRecorder(); + SlaveThreadRecorder(MasterThreadRecorder& master); ~SlaveThreadRecorder(); // call this periodically to gather stats data for master thread to consume @@ -117,7 +117,8 @@ namespace LLTrace private: LLMutex mRecordingMutex; }; - SharedData mSharedData; + SharedData mSharedData; + MasterThreadRecorder& mMasterRecorder; }; } diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp index 972b436bdc..22ca90df7a 100644 --- a/indra/llui/llstatbar.cpp +++ b/indra/llui/llstatbar.cpp @@ -47,10 +47,6 @@ LLStatBar::LLStatBar(const Params& p) mMinBar(p.bar_min), mMaxBar(p.bar_max), mCurMaxBar(p.bar_max), - mCountFloatp(LLTrace::CountStatHandle<>::getInstance(p.stat)), - mCountIntp(LLTrace::CountStatHandle::getInstance(p.stat)), - mMeasurementFloatp(LLTrace::MeasurementStatHandle<>::getInstance(p.stat)), - mMeasurementIntp(LLTrace::MeasurementStatHandle::getInstance(p.stat)), mTickSpacing(p.tick_spacing), mPrecision(p.precision), mUpdatesPerSec(p.update_rate), @@ -63,7 +59,9 @@ LLStatBar::LLStatBar(const Params& p) mDisplayMean(p.show_mean), mOrientation(p.orientation), mScaleRange(p.scale_range) -{} +{ + setStat(p.stat); +} BOOL LLStatBar::handleMouseDown(S32 x, S32 y, MASK mask) { @@ -143,23 +141,41 @@ void LLStatBar::draw() mean = frame_recording.getPeriodMean(*mCountIntp, mNumFrames); } } - else if (mMeasurementFloatp) + else if (mEventFloatp) { - LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording(); + LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording(); - current = last_frame_recording.getLastValue(*mMeasurementFloatp); - min = frame_recording.getPeriodMin(*mMeasurementFloatp, mNumFrames); - max = frame_recording.getPeriodMax(*mMeasurementFloatp, mNumFrames); - mean = frame_recording.getPeriodMean(*mMeasurementFloatp, mNumFrames); + current = last_frame_recording.getMean(*mEventFloatp); + min = frame_recording.getPeriodMin(*mEventFloatp, mNumFrames); + max = frame_recording.getPeriodMax(*mEventFloatp, mNumFrames); + mean = frame_recording.getPeriodMean(*mEventFloatp, mNumFrames); } - else if (mMeasurementIntp) + else if (mEventIntp) { - LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording(); + LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording(); + + current = last_frame_recording.getLastValue(*mEventIntp); + min = frame_recording.getPeriodMin(*mEventIntp, mNumFrames); + max = frame_recording.getPeriodMax(*mEventIntp, mNumFrames); + mean = frame_recording.getPeriodMean(*mEventIntp, mNumFrames); + } + else if (mSampleFloatp) + { + LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording(); + + current = last_frame_recording.getLastValue(*mSampleFloatp); + min = frame_recording.getPeriodMin(*mSampleFloatp, mNumFrames); + max = frame_recording.getPeriodMax(*mSampleFloatp, mNumFrames); + mean = frame_recording.getPeriodMean(*mSampleFloatp, mNumFrames); + } + else if (mSampleIntp) + { + LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording(); - current = last_frame_recording.getLastValue(*mMeasurementIntp); - min = frame_recording.getPeriodMin(*mMeasurementIntp, mNumFrames); - max = frame_recording.getPeriodMax(*mMeasurementIntp, mNumFrames); - mean = frame_recording.getPeriodMean(*mMeasurementIntp, mNumFrames); + current = last_frame_recording.getLastValue(*mSampleIntp); + min = frame_recording.getPeriodMin(*mSampleIntp, mNumFrames); + max = frame_recording.getPeriodMax(*mSampleIntp, mNumFrames); + mean = frame_recording.getPeriodMean(*mSampleIntp, mNumFrames); } current *= mUnitScale; @@ -247,7 +263,7 @@ void LLStatBar::draw() } value_format = llformat( "%%.%df", mPrecision); - if (mDisplayBar && (mCountFloatp || mCountIntp || mMeasurementFloatp || mMeasurementIntp)) + if (mDisplayBar && (mCountFloatp || mCountIntp || mEventFloatp || mEventIntp || mSampleFloatp || mSampleIntp)) { std::string tick_label; @@ -334,7 +350,7 @@ void LLStatBar::draw() ? (bar_right - bar_left) : (bar_top - bar_bottom); - if (mDisplayHistory && (mCountFloatp || mCountIntp || mMeasurementFloatp || mMeasurementIntp)) + if (mDisplayHistory && (mCountFloatp || mCountIntp || mEventFloatp || mEventIntp || mSampleFloatp || mSampleIntp)) { const S32 num_values = frame_recording.getNumPeriods() - 1; F32 begin = 0; @@ -362,19 +378,33 @@ void LLStatBar::draw() end = ((recording.getPerSec(*mCountIntp) - mMinBar) * value_scale) + 1; num_samples = recording.getSampleCount(*mCountIntp); } - else if (mMeasurementFloatp) + else if (mEventFloatp) { //rate isn't defined for measurement stats, so use mean - begin = ((recording.getMean(*mMeasurementFloatp) - mMinBar) * value_scale); - end = ((recording.getMean(*mMeasurementFloatp) - mMinBar) * value_scale) + 1; - num_samples = recording.getSampleCount(*mMeasurementFloatp); + begin = ((recording.getMean(*mEventFloatp) - mMinBar) * value_scale); + end = ((recording.getMean(*mEventFloatp) - mMinBar) * value_scale) + 1; + num_samples = recording.getSampleCount(*mEventFloatp); } - else if (mMeasurementIntp) + else if (mEventIntp) { //rate isn't defined for measurement stats, so use mean - begin = ((recording.getMean(*mMeasurementIntp) - mMinBar) * value_scale); - end = ((recording.getMean(*mMeasurementIntp) - mMinBar) * value_scale) + 1; - num_samples = recording.getSampleCount(*mMeasurementIntp); + begin = ((recording.getMean(*mEventIntp) - mMinBar) * value_scale); + end = ((recording.getMean(*mEventIntp) - mMinBar) * value_scale) + 1; + num_samples = recording.getSampleCount(*mEventIntp); + } + else if (mSampleFloatp) + { + //rate isn't defined for sample stats, so use mean + begin = ((recording.getMean(*mEventFloatp) - mMinBar) * value_scale); + end = ((recording.getMean(*mEventFloatp) - mMinBar) * value_scale) + 1; + num_samples = recording.getSampleCount(*mEventFloatp); + } + else if (mSampleIntp) + { + //rate isn't defined for sample stats, so use mean + begin = ((recording.getMean(*mEventFloatp) - mMinBar) * value_scale); + end = ((recording.getMean(*mEventFloatp) - mMinBar) * value_scale) + 1; + num_samples = recording.getSampleCount(*mEventFloatp); } } else @@ -391,17 +421,29 @@ void LLStatBar::draw() end = ((recording.getSum(*mCountIntp) - mMinBar) * value_scale) + 1; num_samples = recording.getSampleCount(*mCountIntp); } - else if (mMeasurementFloatp) + else if (mEventFloatp) + { + begin = ((recording.getMean(*mEventFloatp) - mMinBar) * value_scale); + end = ((recording.getMean(*mEventFloatp) - mMinBar) * value_scale) + 1; + num_samples = recording.getSampleCount(*mEventFloatp); + } + else if (mEventIntp) + { + begin = ((recording.getMean(*mEventIntp) - mMinBar) * value_scale); + end = ((recording.getMean(*mEventIntp) - mMinBar) * value_scale) + 1; + num_samples = recording.getSampleCount(*mEventIntp); + } + else if (mSampleFloatp) { - begin = ((recording.getMean(*mMeasurementFloatp) - mMinBar) * value_scale); - end = ((recording.getMean(*mMeasurementFloatp) - mMinBar) * value_scale) + 1; - num_samples = recording.getSampleCount(*mMeasurementFloatp); + begin = ((recording.getMean(*mEventFloatp) - mMinBar) * value_scale); + end = ((recording.getMean(*mEventFloatp) - mMinBar) * value_scale) + 1; + num_samples = recording.getSampleCount(*mEventFloatp); } - else if (mMeasurementIntp) + else if (mSampleIntp) { - begin = ((recording.getMean(*mMeasurementIntp) - mMinBar) * value_scale); - end = ((recording.getMean(*mMeasurementIntp) - mMinBar) * value_scale) + 1; - num_samples = recording.getSampleCount(*mMeasurementIntp); + begin = ((recording.getMean(*mEventFloatp) - mMinBar) * value_scale); + end = ((recording.getMean(*mEventFloatp) - mMinBar) * value_scale) + 1; + num_samples = recording.getSampleCount(*mEventFloatp); } } @@ -461,8 +503,10 @@ void LLStatBar::setStat(const std::string& stat_name) { mCountFloatp = LLTrace::CountStatHandle<>::getInstance(stat_name); mCountIntp = LLTrace::CountStatHandle::getInstance(stat_name); - mMeasurementFloatp = LLTrace::MeasurementStatHandle<>::getInstance(stat_name); - mMeasurementIntp = LLTrace::MeasurementStatHandle::getInstance(stat_name); + mEventFloatp = LLTrace::EventStatHandle<>::getInstance(stat_name); + mEventIntp = LLTrace::EventStatHandle::getInstance(stat_name); + mSampleFloatp = LLTrace::SampleStatHandle<>::getInstance(stat_name); + mSampleIntp = LLTrace::SampleStatHandle::getInstance(stat_name); } diff --git a/indra/llui/llstatbar.h b/indra/llui/llstatbar.h index db667aa07d..a0ed9699aa 100644 --- a/indra/llui/llstatbar.h +++ b/indra/llui/llstatbar.h @@ -111,10 +111,12 @@ private: bool mScaleRange; EOrientation mOrientation; - LLTrace::TraceType >* mCountFloatp; - LLTrace::TraceType >* mCountIntp; - LLTrace::TraceType >* mMeasurementFloatp; - LLTrace::TraceType >* mMeasurementIntp; + LLTrace::TraceType >* mCountFloatp; + LLTrace::TraceType >* mCountIntp; + LLTrace::TraceType >* mEventFloatp; + LLTrace::TraceType >* mEventIntp; + LLTrace::TraceType >* mSampleFloatp; + LLTrace::TraceType >* mSampleIntp; LLFrameTimer mUpdateTimer; LLUIString mLabel; diff --git a/indra/llui/llstatgraph.h b/indra/llui/llstatgraph.h index c9e33ed902..08681b3704 100644 --- a/indra/llui/llstatgraph.h +++ b/indra/llui/llstatgraph.h @@ -57,10 +57,12 @@ public: struct StatParams : public LLInitParam::ChoiceBlock { - Alternative >* > count_stat_float; - Alternative >* > count_stat_int; - Alternative >* > measurement_stat_float; - Alternative >* > measurement_stat_int; + Alternative >* > count_stat_float; + Alternative >* > count_stat_int; + Alternative >* > event_stat_float; + Alternative >* > event_stat_int; + Alternative >* > sample_stat_float; + Alternative >* > sample_stat_int; }; struct Params : public LLInitParam::Block diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 3a3fe2b656..edf874d744 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1244,7 +1244,7 @@ bool LLAppViewer::mainLoop() LLTrace::get_frame_recording().nextPeriod(); LLTrace::TimeBlock::logStats(); - LLTrace::getMasterThreadRecorder().pullFromSlaveThreads(); + LLTrace::getUIThreadRecorder().pullFromSlaveThreads(); //clear call stack records llclearcallstacks; diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp index dbdf3e5e9f..b71ab4c53b 100644 --- a/indra/newview/llfloaterjoystick.cpp +++ b/indra/newview/llfloaterjoystick.cpp @@ -42,13 +42,13 @@ #include "llviewerjoystick.h" #include "llcheckboxctrl.h" -static LLTrace::MeasurementStatHandle<> sJoystickAxis1("Joystick axis 1"), - sJoystickAxis2("Joystick axis 2"), - sJoystickAxis3("Joystick axis 3"), - sJoystickAxis4("Joystick axis 4"), - sJoystickAxis5("Joystick axis 5"), - sJoystickAxis6("Joystick axis 6"); -static LLTrace::MeasurementStatHandle<>* sJoystickAxes[6] = +static LLTrace::SampleStatHandle<> sJoystickAxis1("Joystick axis 1"), + sJoystickAxis2("Joystick axis 2"), + sJoystickAxis3("Joystick axis 3"), + sJoystickAxis4("Joystick axis 4"), + sJoystickAxis5("Joystick axis 5"), + sJoystickAxis6("Joystick axis 6"); +static LLTrace::SampleStatHandle<>* sJoystickAxes[6] = { &sJoystickAxis1, &sJoystickAxis2, diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp index 94c2e40bb1..15f2f6d762 100644 --- a/indra/newview/llscenemonitor.cpp +++ b/indra/newview/llscenemonitor.cpp @@ -462,7 +462,7 @@ void LLSceneMonitor::calcDiffAggregate() } } -static LLTrace::MeasurementStatHandle<> sFramePixelDiff("FramePixelDifference"); +static LLTrace::EventStatHandle<> sFramePixelDiff("FramePixelDifference"); void LLSceneMonitor::fetchQueryResult() { LLFastTimer _(FTM_SCENE_LOAD_IMAGE_DIFF); @@ -481,16 +481,18 @@ void LLSceneMonitor::fetchQueryResult() mDiffResult = count * 0.5f / (mDiff->getWidth() * mDiff->getHeight() * mDiffPixelRatio * mDiffPixelRatio); //0.5 -> (front face + back face) LL_DEBUGS("SceneMonitor") << "Frame difference: " << std::setprecision(4) << mDiffResult << LL_ENDL; - sample(sFramePixelDiff, mDiffResult); + record(sFramePixelDiff, mDiffResult); static LLCachedControl diff_threshold(gSavedSettings,"SceneLoadingPixelDiffThreshold"); if(mDiffResult > diff_threshold()) { mRecording->extend(); + llassert(mRecording->getAcceptedRecording().getLastRecording().getSum(LLStatViewer::FPS)); } else { mRecording->getPotentialRecording().nextPeriod(); + llassert(mRecording->getPotentialRecording().getLastRecording().getSum(LLStatViewer::FPS)); } } } @@ -503,7 +505,6 @@ void LLSceneMonitor::dumpToFile(std::string file_name) std::ofstream os(file_name.c_str()); - //total scene loading time os << std::setprecision(4); LLTrace::PeriodicRecording& scene_load_recording = mRecording->getAcceptedRecording(); @@ -565,7 +566,7 @@ void LLSceneMonitor::dumpToFile(std::string file_name) } } - for (LLTrace::MeasurementStatHandle::instance_iter it = LLTrace::MeasurementStatHandle::beginInstances(), end_it = LLTrace::MeasurementStatHandle::endInstances(); + for (LLTrace::EventStatHandle::instance_iter it = LLTrace::EventStatHandle::beginInstances(), end_it = LLTrace::EventStatHandle::endInstances(); it != end_it; ++it) { @@ -588,7 +589,53 @@ void LLSceneMonitor::dumpToFile(std::string file_name) } } - for (LLTrace::MeasurementStatHandle::instance_iter it = LLTrace::MeasurementStatHandle::beginInstances(), end_it = LLTrace::MeasurementStatHandle::endInstances(); + for (LLTrace::EventStatHandle::instance_iter it = LLTrace::EventStatHandle::beginInstances(), end_it = LLTrace::EventStatHandle::endInstances(); + it != end_it; + ++it) + { + std::ostringstream row; + row << it->getName(); + + S32 samples = 0; + + for (S32 i = frame_count - 1; i >= 0; --i) + { + samples += scene_load_recording.getPrevRecording(i).getSampleCount(*it); + row << ", " << scene_load_recording.getPrevRecording(i).getMean(*it); + } + + row << std::endl; + + if (samples > 0) + { + os << row.str(); + } + } + + for (LLTrace::SampleStatHandle::instance_iter it = LLTrace::SampleStatHandle::beginInstances(), end_it = LLTrace::SampleStatHandle::endInstances(); + it != end_it; + ++it) + { + std::ostringstream row; + row << it->getName(); + + S32 samples = 0; + + for (S32 i = frame_count - 1; i >= 0; --i) + { + samples += scene_load_recording.getPrevRecording(i).getSampleCount(*it); + row << ", " << scene_load_recording.getPrevRecording(i).getMean(*it); + } + + row << std::endl; + + if (samples > 0) + { + os << row.str(); + } + } + + for (LLTrace::SampleStatHandle::instance_iter it = LLTrace::SampleStatHandle::beginInstances(), end_it = LLTrace::SampleStatHandle::endInstances(); it != end_it; ++it) { diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index f748344cc8..f060e8933b 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -2071,7 +2071,7 @@ bool idle_startup() if (wearables_time > max_wearables_time()) { LLNotificationsUtil::add("ClothingLoading"); - add(LLStatViewer::LOADING_WEARABLES_LONG_DELAY, 1); + record(LLStatViewer::LOADING_WEARABLES_LONG_DELAY, wearables_time); LLStartUp::setStartupState( STATE_CLEANUP ); return TRUE; } diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index b945ec2318..f3406d9f8d 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -212,7 +212,7 @@ BOOL LLStatusBar::postBuild() pgp.rect(r); pgp.follows.flags(FOLLOWS_BOTTOM | FOLLOWS_RIGHT); pgp.mouse_opaque(false); - pgp.stat.measurement_stat_float(&LLStatViewer::PACKETS_LOST_PERCENT); + pgp.stat.sample_stat_float(&LLStatViewer::PACKETS_LOST_PERCENT); pgp.units("%"); pgp.min(0.f); pgp.max(5.f); diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 8bf7bcc398..910cb24bb2 100755 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -65,8 +65,8 @@ #include "bufferstream.h" bool LLTextureFetchDebugger::sDebuggerEnabled = false ; -LLTrace::MeasurementStatHandle<> LLTextureFetch::sCacheHitRate("texture_cache_hits"); -LLTrace::MeasurementStatHandle<> LLTextureFetch::sCacheReadLatency("texture_cache_read_latency"); +LLTrace::SampleStatHandle<> LLTextureFetch::sCacheHitRate("texture_cache_hits"); +LLTrace::SampleStatHandle<> LLTextureFetch::sCacheReadLatency("texture_cache_read_latency"); ////////////////////////////////////////////////////////////////////////////// @@ -1833,7 +1833,7 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe if (log_to_viewer_log || log_to_sim) { U64 timeNow = LLTimer::getTotalTime(); - mFetcher->mTextureInfo.setRequestStartTime(mID, mMetricsStartTime); + mFetcher->mTextureInfo.setRequestStartTime(mID, mMetricsStartTime.value()); mFetcher->mTextureInfo.setRequestType(mID, LLTextureInfoDetails::REQUEST_TYPE_HTTP); mFetcher->mTextureInfo.setRequestSize(mID, mRequestedSize); mFetcher->mTextureInfo.setRequestOffset(mID, mRequestedOffset); @@ -2278,7 +2278,7 @@ bool LLTextureFetchWorker::writeToCacheComplete() // Threads: Ttf void LLTextureFetchWorker::recordTextureStart(bool is_http) { - if (! mMetricsStartTime) + if (! mMetricsStartTime.value()) { mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp(); } @@ -2291,7 +2291,7 @@ void LLTextureFetchWorker::recordTextureStart(bool is_http) // Threads: Ttf void LLTextureFetchWorker::recordTextureDone(bool is_http) { - if (mMetricsStartTime) + if (mMetricsStartTime.value()) { LLViewerAssetStatsFF::record_response(LLViewerAssetType::AT_TEXTURE, is_http, diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 4dcb9dd4b8..573b32c4bd 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -308,8 +308,8 @@ private: LLMutex mQueueMutex; //to protect mRequestMap and mCommands only LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue. - static LLTrace::MeasurementStatHandle<> sCacheHitRate; - static LLTrace::MeasurementStatHandle<> sCacheReadLatency; + static LLTrace::SampleStatHandle<> sCacheHitRate; + static LLTrace::SampleStatHandle<> sCacheReadLatency; LLTextureCache* mTextureCache; LLImageDecodeThread* mImageDecodeThread; diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp index 8623af52ff..0bbf2cbbea 100644 --- a/indra/newview/llviewerassetstats.cpp +++ b/indra/newview/llviewerassetstats.cpp @@ -233,7 +233,7 @@ namespace LLViewerAssetStatsFF &sDequeuedAssetRequestsOther }; - static LLTrace::MeasurementStatHandle sResponseAssetRequestsTempTextureHTTP ("assetresponsetimestemptexturehttp", + static LLTrace::EventStatHandle sResponseAssetRequestsTempTextureHTTP ("assetresponsetimestemptexturehttp", "Time spent responding to temporary texture asset http requests"), sResponseAssetRequestsTempTextureUDP ("assetresponsetimestemptextureudp", "Time spent responding to temporary texture asset udp requests"), @@ -250,7 +250,7 @@ namespace LLViewerAssetStatsFF sResponsedAssetRequestsOther ("assetresponsetimesother", "Time spent responding to other asset requests"); - static LLTrace::MeasurementStatHandle* sResponse[EVACCount] = { + static LLTrace::EventStatHandle* sResponse[EVACCount] = { &sResponseAssetRequestsTempTextureHTTP, &sResponseAssetRequestsTempTextureUDP, &sResponseAssetRequestsNonTempTextureHTTP, @@ -283,7 +283,6 @@ LLViewerAssetStats::LLViewerAssetStats(const LLViewerAssetStats & src) mPhaseStats(src.mPhaseStats), mAvatarRezStates(src.mAvatarRezStates) { - src.mCurRecording->update(); mRegionRecordings = src.mRegionRecordings; mCurRecording = &mRegionRecordings[mRegionHandle]; @@ -485,7 +484,7 @@ void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output) .resp_mean(rec.getMean(*sResponse[EVACOtherGet]).value()); } - S32 fps = (S32)rec.getSum(LLStatViewer::FPS_SAMPLE); + S32 fps = (S32)rec.getLastValue(LLStatViewer::FPS_SAMPLE); if (!compact_output || fps != 0) { r.fps.count(fps); @@ -561,7 +560,7 @@ void record_response(LLViewerAssetType::EType at, bool with_http, bool is_temp, { const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); - sample(*sResponse[int(eac)], LLTrace::Microseconds(duration)); + record(*sResponse[int(eac)], LLTrace::Microseconds(duration)); } void record_avatar_stats() diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h index 56eaa13df9..af99710aca 100644 --- a/indra/newview/llviewerassetstats.h +++ b/indra/newview/llviewerassetstats.h @@ -83,7 +83,7 @@ public: * for compatibility with the pre-existing timestamp on the texture * fetcher class, LLTextureFetch. */ - typedef U64 duration_t; + typedef LLUnit duration_t; /** * Type for the region identifier used in stats. Currently uses diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp index 6f41abbd8a..5c2dd20ec3 100644 --- a/indra/newview/llviewerassetstorage.cpp +++ b/indra/newview/llviewerassetstorage.cpp @@ -69,7 +69,7 @@ public: protected: void recordMetrics() { - if (mMetricsStartTime) + if (mMetricsStartTime.value()) { // Okay, it appears this request was used for useful things. Record // the expected dequeue and duration of request processing. diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 50b14183c7..d912918129 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -2222,7 +2222,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, // If we're snapping the position by more than 0.5m, update LLViewerStats::mAgentPositionSnaps if ( asAvatar() && asAvatar()->isSelf() && (mag_sqr > 0.25f) ) { - sample(LLStatViewer::AGENT_POSITION_SNAP, LLTrace::Meters(diff.length())); + record(LLStatViewer::AGENT_POSITION_SNAP, LLTrace::Meters(diff.length())); } } diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 6ffd3d8fa4..c6ac7af93c 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -95,7 +95,7 @@ extern LLPipeline gPipeline; U32 LLViewerObjectList::sSimulatorMachineIndex = 1; // Not zero deliberately, to speed up index check. std::map LLViewerObjectList::sIPAndPortToIndex; std::map LLViewerObjectList::sIndexAndLocalIDToUUID; -LLTrace::MeasurementStatHandle<> LLViewerObjectList::sCacheHitRate("object_cache_hits"); +LLTrace::SampleStatHandle<> LLViewerObjectList::sCacheHitRate("object_cache_hits"); LLViewerObjectList::LLViewerObjectList() { diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 65447156e7..464554245e 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -198,7 +198,7 @@ protected: std::vector mOrphanChildren; // UUID's of orphaned objects S32 mNumOrphans; - static LLTrace::MeasurementStatHandle<> sCacheHitRate; + static LLTrace::SampleStatHandle<> sCacheHitRate; typedef std::vector > vobj_list_t; diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index e8196e9655..635611c02e 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -74,7 +74,6 @@ LLTrace::CountStatHandle<> FPS("framesrendered"), IM_COUNT("imcount", "IMs sent"), OBJECT_CREATE("objectcreate"), OBJECT_REZ("objectrez", "Object rez count"), - LOADING_WEARABLES_LONG_DELAY("loadingwearableslongdelay", "Wearables took too long to load"), LOGIN_TIMEOUTS("logintimeouts", "Number of login attempts that timed out"), LSL_SAVES("lslsaves", "Number of times user has saved a script"), ANIMATION_UPLOADS("animationuploads", "Animations uploaded"), @@ -98,13 +97,7 @@ LLTrace::CountStatHandle KBIT("kbitstat"), ACTUAL_IN_KBIT("actualinkbitstat"), ACTUAL_OUT_KBIT("actualoutkbitstat"); -LLTrace::CountStatHandle AVATAR_EDIT_TIME("avataredittime", "Seconds in Edit Appearence"), - TOOLBOX_TIME("toolboxtime", "Seconds using Toolbox"), - MOUSELOOK_TIME("mouselooktime", "Seconds in Mouselook"), - FPS_10_TIME("fps10time", "Seconds below 10 FPS"), - FPS_8_TIME("fps8time", "Seconds below 8 FPS"), - FPS_2_TIME("fps2time", "Seconds below 2 FPS"), - SIM_20_FPS_TIME("sim20fpstime", "Seconds with sim FPS below 20"), +LLTrace::CountStatHandle SIM_20_FPS_TIME("sim20fpstime", "Seconds with sim FPS below 20"), SIM_PHYSICS_20_FPS_TIME("simphysics20fpstime", "Seconds with physics FPS below 20"), LOSS_5_PERCENT_TIME("loss5percenttime", "Seconds with packet loss > 5%"); @@ -129,36 +122,34 @@ SimMeasurement<> SIM_TIME_DILATION("simtimedilation", "", LL_SIM_STAT_TIME_DIL SIM_PHYSICS_PINNED_TASKS("physicspinnedtasks", "", LL_SIM_STAT_PHYSICS_PINNED_TASKS), SIM_PHYSICS_LOD_TASKS("physicslodtasks", "", LL_SIM_STAT_PHYSICS_LOD_TASKS); -LLTrace::MeasurementStatHandle<> FPS_SAMPLE("fpssample"), - NUM_IMAGES("numimagesstat"), - NUM_RAW_IMAGES("numrawimagesstat"), - NUM_OBJECTS("numobjectsstat"), - NUM_ACTIVE_OBJECTS("numactiveobjectsstat"), - NUM_SIZE_CULLED("numsizeculledstat"), - NUM_VIS_CULLED("numvisculledstat"), - ENABLE_VBO("enablevbo", "Vertex Buffers Enabled"), - LIGHTING_DETAIL("lightingdetail", "Lighting Detail"), - VISIBLE_AVATARS("visibleavatars", "Visible Avatars"), - SHADER_OBJECTS("shaderobjects", "Object Shaders"), - DRAW_DISTANCE("drawdistance", "Draw Distance"), - CHAT_BUBBLES("chatbubbles", "Chat Bubbles Enabled"), - PENDING_VFS_OPERATIONS("vfspendingoperations"), - PACKETS_LOST_PERCENT("packetslostpercentstat"), - WINDOW_WIDTH("windowwidth", "Window width"), - WINDOW_HEIGHT("windowheight", "Window height"); +LLTrace::SampleStatHandle<> FPS_SAMPLE("fpssample"), + NUM_IMAGES("numimagesstat"), + NUM_RAW_IMAGES("numrawimagesstat"), + NUM_OBJECTS("numobjectsstat"), + NUM_ACTIVE_OBJECTS("numactiveobjectsstat"), + NUM_SIZE_CULLED("numsizeculledstat"), + NUM_VIS_CULLED("numvisculledstat"), + ENABLE_VBO("enablevbo", "Vertex Buffers Enabled"), + LIGHTING_DETAIL("lightingdetail", "Lighting Detail"), + VISIBLE_AVATARS("visibleavatars", "Visible Avatars"), + SHADER_OBJECTS("shaderobjects", "Object Shaders"), + DRAW_DISTANCE("drawdistance", "Draw Distance"), + PENDING_VFS_OPERATIONS("vfspendingoperations"), + PACKETS_LOST_PERCENT("packetslostpercentstat"), + WINDOW_WIDTH("windowwidth", "Window width"), + WINDOW_HEIGHT("windowheight", "Window height"); -LLTrace::MeasurementStatHandle AGENT_POSITION_SNAP("agentpositionsnap", "agent position corrections"); +static LLTrace::SampleStatHandle CHAT_BUBBLES("chatbubbles", "Chat Bubbles Enabled"); - -LLTrace::MeasurementStatHandle GL_TEX_MEM("gltexmemstat"), - GL_BOUND_MEM("glboundmemstat"), - RAW_MEM("rawmemstat"), - FORMATTED_MEM("formattedmemstat"), - DELTA_BANDWIDTH("deltabandwidth", "Increase/Decrease in bandwidth based on packet loss"), - MAX_BANDWIDTH("maxbandwidth", "Max bandwidth setting"); +LLTrace::SampleStatHandle GL_TEX_MEM("gltexmemstat"), + GL_BOUND_MEM("glboundmemstat"), + RAW_MEM("rawmemstat"), + FORMATTED_MEM("formattedmemstat"), + DELTA_BANDWIDTH("deltabandwidth", "Increase/Decrease in bandwidth based on packet loss"), + MAX_BANDWIDTH("maxbandwidth", "Max bandwidth setting"); -SimMeasurement SIM_FRAME_TIME("simframemsec", "", LL_SIM_STAT_FRAMEMS), +SimMeasurement SIM_FRAME_TIME("simframemsec", "", LL_SIM_STAT_FRAMEMS), SIM_NET_TIME("simnetmsec", "", LL_SIM_STAT_NETMS), SIM_OTHER_TIME("simsimothermsec", "", LL_SIM_STAT_SIMOTHERMS), SIM_PHYSICS_TIME("simsimphysicsmsec", "", LL_SIM_STAT_SIMPHYSICSMS), @@ -173,21 +164,32 @@ SimMeasurement SIM_FRAME_TIME("simframemsec", "", LL_SIM_ SIM_SLEEP_TIME("simsleepmsec", "", LL_SIM_STAT_SIMSLEEPTIME), SIM_PUMP_IO_TIME("simpumpiomsec", "", LL_SIM_STAT_IOPUMPTIME); -SimMeasurement SIM_UNACKED_BYTES("simtotalunackedbytes", "", LL_SIM_STAT_TOTAL_UNACKED_BYTES), +SimMeasurement SIM_UNACKED_BYTES("simtotalunackedbytes", "", LL_SIM_STAT_TOTAL_UNACKED_BYTES), SIM_PHYSICS_MEM("physicsmemoryallocated", "", LL_SIM_STAT_SIMPHYSICSMEMORY); +LLTrace::SampleStatHandle FRAMETIME_JITTER("frametimejitter", "Average delta between successive frame times"), + FRAMETIME_SLEW("frametimeslew", "Average delta between frame time and mean"), + SIM_PING("simpingstat"); + +LLTrace::EventStatHandle AGENT_POSITION_SNAP("agentpositionsnap", "agent position corrections"); + +LLTrace::EventStatHandle<> LOADING_WEARABLES_LONG_DELAY("loadingwearableslongdelay", "Wearables took too long to load"); + +LLTrace::EventStatHandle REGION_CROSSING_TIME("regioncrossingtime", "CROSSING_AVG"), + FRAME_STACKTIME("framestacktime", "FRAME_SECS"), + UPDATE_STACKTIME("updatestacktime", "UPDATE_SECS"), + NETWORK_STACKTIME("networkstacktime", "NETWORK_SECS"), + IMAGE_STACKTIME("imagestacktime", "IMAGE_SECS"), + REBUILD_STACKTIME("rebuildstacktime", "REBUILD_SECS"), + RENDER_STACKTIME("renderstacktime", "RENDER_SECS"); + +LLTrace::EventStatHandle AVATAR_EDIT_TIME("avataredittime", "Seconds in Edit Appearance"), + TOOLBOX_TIME("toolboxtime", "Seconds using Toolbox"), + MOUSELOOK_TIME("mouselooktime", "Seconds in Mouselook"), + FPS_10_TIME("fps10time", "Seconds below 10 FPS"), + FPS_8_TIME("fps8time", "Seconds below 8 FPS"), + FPS_2_TIME("fps2time", "Seconds below 2 FPS"); -LLTrace::MeasurementStatHandle FRAMETIME_JITTER("frametimejitter", "Average delta between successive frame times"), - FRAMETIME_SLEW("frametimeslew", "Average delta between frame time and mean"), - LOGIN_SECONDS("loginseconds", "Time between LoginRequest and LoginReply"), - REGION_CROSSING_TIME("regioncrossingtime", "CROSSING_AVG"), - FRAME_STACKTIME("framestacktime", "FRAME_SECS"), - UPDATE_STACKTIME("updatestacktime", "UPDATE_SECS"), - NETWORK_STACKTIME("networkstacktime", "NETWORK_SECS"), - IMAGE_STACKTIME("imagestacktime", "IMAGE_SECS"), - REBUILD_STACKTIME("rebuildstacktime", "REBUILD_SECS"), - RENDER_STACKTIME("renderstacktime", "RENDER_SECS"), - SIM_PING("simpingstat"); } @@ -230,15 +232,15 @@ void LLViewerStats::updateFrameStats(const F64 time_diff) if (time_diff >= 0.5) { - add(LLStatViewer::FPS_2_TIME, time_diff_seconds); + record(LLStatViewer::FPS_2_TIME, time_diff_seconds); } if (time_diff >= 0.125) { - add(LLStatViewer::FPS_8_TIME, time_diff_seconds); + record(LLStatViewer::FPS_8_TIME, time_diff_seconds); } if (time_diff >= 0.1) { - add(LLStatViewer::FPS_10_TIME, time_diff_seconds); + record(LLStatViewer::FPS_10_TIME, time_diff_seconds); } if (gFrameCount && mLastTimeDiff > 0.0) @@ -311,35 +313,36 @@ void update_statistics() { if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK) { - add(LLStatViewer::MOUSELOOK_TIME, gFrameIntervalSeconds); + record(LLStatViewer::MOUSELOOK_TIME, gFrameIntervalSeconds); } else if (gAgentCamera.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR) { - add(LLStatViewer::AVATAR_EDIT_TIME, gFrameIntervalSeconds); + record(LLStatViewer::AVATAR_EDIT_TIME, gFrameIntervalSeconds); } else if (LLFloaterReg::instanceVisible("build")) { - add(LLStatViewer::TOOLBOX_TIME, gFrameIntervalSeconds); + record(LLStatViewer::TOOLBOX_TIME, gFrameIntervalSeconds); } } LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording(); - sample(LLStatViewer::ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable")); + sample(LLStatViewer::ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable")); sample(LLStatViewer::LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail()); - sample(LLStatViewer::DRAW_DISTANCE, (F64)gSavedSettings.getF32("RenderFarClip")); - sample(LLStatViewer::CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles")); + sample(LLStatViewer::DRAW_DISTANCE, (F64)gSavedSettings.getF32("RenderFarClip")); + sample(LLStatViewer::CHAT_BUBBLES, gSavedSettings.getBOOL("UseChatBubbles")); typedef LLInstanceTracker, std::string> trace_type_t; - sample(LLStatViewer::FRAME_STACKTIME, last_frame_recording.getSum(*trace_type_t::getInstance("Frame")).as()); LLUnit idle_secs = last_frame_recording.getSum(*trace_type_t::getInstance("Idle")); LLUnit network_secs = last_frame_recording.getSum(*trace_type_t::getInstance("Network")); - sample(LLStatViewer::UPDATE_STACKTIME, idle_secs - network_secs); - sample(LLStatViewer::NETWORK_STACKTIME, network_secs); - sample(LLStatViewer::IMAGE_STACKTIME, last_frame_recording.getSum(*trace_type_t::getInstance("Update Images")).as()); - sample(LLStatViewer::REBUILD_STACKTIME, last_frame_recording.getSum(*trace_type_t::getInstance("Sort Draw State")).as()); - sample(LLStatViewer::RENDER_STACKTIME, last_frame_recording.getSum(*trace_type_t::getInstance("Render Geometry")).as()); + + record(LLStatViewer::FRAME_STACKTIME, last_frame_recording.getSum(*trace_type_t::getInstance("Frame"))); + record(LLStatViewer::UPDATE_STACKTIME, idle_secs - network_secs); + record(LLStatViewer::NETWORK_STACKTIME, network_secs); + record(LLStatViewer::IMAGE_STACKTIME, last_frame_recording.getSum(*trace_type_t::getInstance("Update Images"))); + record(LLStatViewer::REBUILD_STACKTIME, last_frame_recording.getSum(*trace_type_t::getInstance("Sort Draw State"))); + record(LLStatViewer::RENDER_STACKTIME, last_frame_recording.getSum(*trace_type_t::getInstance("Render Geometry"))); LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost()); if (cdp) diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index e94ba23163..c0ac6d220f 100644 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -46,10 +46,10 @@ struct SimMeasurementSampler : public LLInstanceTracker -struct SimMeasurement : public LLTrace::MeasurementStatHandle, public SimMeasurementSampler +struct SimMeasurement : public LLTrace::SampleStatHandle, public SimMeasurementSampler { SimMeasurement(const char* name, const char* description, ESimStatID stat_id) - : LLTrace::MeasurementStatHandle(name, description), + : LLTrace::SampleStatHandle(name, description), SimMeasurementSampler(stat_id) {} @@ -66,7 +66,8 @@ void sample(SimMeasurement& measurement, VALUE_T value) { LLTrace::sample(measurement, value); } -extern LLTrace::CountStatHandle<> FPS, + +extern LLTrace::CountStatHandle<> FPS, PACKETS_IN, PACKETS_LOST, PACKETS_OUT, @@ -76,7 +77,6 @@ extern LLTrace::CountStatHandle<> FPS, IM_COUNT, OBJECT_CREATE, OBJECT_REZ, - LOADING_WEARABLES_LONG_DELAY, LOGIN_TIMEOUTS, LSL_SAVES, ANIMATION_UPLOADS, @@ -102,15 +102,9 @@ extern LLTrace::CountStatHandle KBIT, ACTUAL_IN_KBIT, ACTUAL_OUT_KBIT; -extern LLTrace::CountStatHandle AVATAR_EDIT_TIME, - TOOLBOX_TIME, - MOUSELOOK_TIME, - FPS_10_TIME, - FPS_8_TIME, - FPS_2_TIME, - SIM_20_FPS_TIME, - SIM_PHYSICS_20_FPS_TIME, - LOSS_5_PERCENT_TIME; +extern LLTrace::CountStatHandle SIM_20_FPS_TIME, + SIM_PHYSICS_20_FPS_TIME, + LOSS_5_PERCENT_TIME; extern SimMeasurement<> SIM_TIME_DILATION, SIM_FPS, @@ -133,32 +127,29 @@ extern SimMeasurement<> SIM_TIME_DILATION, SIM_PHYSICS_PINNED_TASKS, SIM_PHYSICS_LOD_TASKS; -extern LLTrace::MeasurementStatHandle<> FPS_SAMPLE, - NUM_IMAGES, - NUM_RAW_IMAGES, - NUM_OBJECTS, - NUM_ACTIVE_OBJECTS, - NUM_SIZE_CULLED, - NUM_VIS_CULLED, - ENABLE_VBO, - LIGHTING_DETAIL, - VISIBLE_AVATARS, - SHADER_OBJECTS, - DRAW_DISTANCE, - CHAT_BUBBLES, - PENDING_VFS_OPERATIONS, - PACKETS_LOST_PERCENT, - WINDOW_WIDTH, - WINDOW_HEIGHT; - -extern LLTrace::MeasurementStatHandle AGENT_POSITION_SNAP; - -extern LLTrace::MeasurementStatHandle DELTA_BANDWIDTH, - MAX_BANDWIDTH, - GL_TEX_MEM, - GL_BOUND_MEM, - RAW_MEM, - FORMATTED_MEM; +extern LLTrace::SampleStatHandle<> FPS_SAMPLE, + NUM_IMAGES, + NUM_RAW_IMAGES, + NUM_OBJECTS, + NUM_ACTIVE_OBJECTS, + NUM_SIZE_CULLED, + NUM_VIS_CULLED, + ENABLE_VBO, + LIGHTING_DETAIL, + VISIBLE_AVATARS, + SHADER_OBJECTS, + DRAW_DISTANCE, + PENDING_VFS_OPERATIONS, + PACKETS_LOST_PERCENT, + WINDOW_WIDTH, + WINDOW_HEIGHT; + +extern LLTrace::SampleStatHandle DELTA_BANDWIDTH, + MAX_BANDWIDTH, + GL_TEX_MEM, + GL_BOUND_MEM, + RAW_MEM, + FORMATTED_MEM; extern SimMeasurement SIM_FRAME_TIME, SIM_NET_TIME, @@ -179,17 +170,29 @@ extern SimMeasurement SIM_UNACKED_BYTES, SIM_PHYSICS_MEM; -extern LLTrace::MeasurementStatHandle FRAMETIME_JITTER, - FRAMETIME_SLEW, - LOGIN_SECONDS, - REGION_CROSSING_TIME, - FRAME_STACKTIME, - UPDATE_STACKTIME, - NETWORK_STACKTIME, - IMAGE_STACKTIME, - REBUILD_STACKTIME, - RENDER_STACKTIME, - SIM_PING; +extern LLTrace::SampleStatHandle FRAMETIME_JITTER, + FRAMETIME_SLEW, + SIM_PING; + +extern LLTrace::EventStatHandle AGENT_POSITION_SNAP; + +extern LLTrace::EventStatHandle<> LOADING_WEARABLES_LONG_DELAY; + +extern LLTrace::EventStatHandle REGION_CROSSING_TIME, + FRAME_STACKTIME, + UPDATE_STACKTIME, + NETWORK_STACKTIME, + IMAGE_STACKTIME, + REBUILD_STACKTIME, + RENDER_STACKTIME; + +extern LLTrace::EventStatHandle AVATAR_EDIT_TIME, + TOOLBOX_TIME, + MOUSELOOK_TIME, + FPS_10_TIME, + FPS_8_TIME, + FPS_2_TIME; + } class LLViewerStats : public LLSingleton diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 08d296b88e..5299e7d2c1 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -249,7 +249,7 @@ std::string LLViewerWindow::sSnapshotDir; std::string LLViewerWindow::sMovieBaseName; -LLTrace::MeasurementStatHandle<> LLViewerWindow::sMouseVelocityStat("Mouse Velocity"); +LLTrace::SampleStatHandle<> LLViewerWindow::sMouseVelocityStat("Mouse Velocity"); class RecordToChatConsole : public LLError::Recorder, public LLSingleton @@ -456,6 +456,8 @@ public: if (gSavedSettings.getBOOL("DebugShowRenderInfo")) { + LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording(); + if (gPipeline.getUseVertexShaders() == 0) { addText(xpos, ypos, "Shaders Disabled"); @@ -561,7 +563,7 @@ public: addText(xpos, ypos, llformat("%d Unique Textures", LLImageGL::sUniqueCount)); ypos += y_inc; - addText(xpos, ypos, llformat("%d Render Calls", gPipeline.mBatchCount)); + addText(xpos, ypos, llformat("%d Render Calls", last_frame_recording.getSampleCount(LLPipeline::sStatBatchSize))); ypos += y_inc; addText(xpos, ypos, llformat("%d/%d Objects Active", gObjectList.getNumActiveObjects(), gObjectList.getNumObjects())); @@ -576,15 +578,10 @@ public: gPipeline.mTextureMatrixOps = 0; gPipeline.mMatrixOpCount = 0; - if (gPipeline.mBatchCount > 0) - { - addText(xpos, ypos, llformat("Batch min/max/mean: %d/%d/%d", gPipeline.mMinBatchSize, gPipeline.mMaxBatchSize, - gPipeline.mTrianglesDrawn/gPipeline.mBatchCount)); - - gPipeline.mMinBatchSize = gPipeline.mMaxBatchSize; - gPipeline.mMaxBatchSize = 0; - gPipeline.mBatchCount = 0; - } + if (last_frame_recording.getSampleCount(LLPipeline::sStatBatchSize) > 0) + { + addText(xpos, ypos, llformat("Batch min/max/mean: %d/%d/%d", last_frame_recording.getMin(LLPipeline::sStatBatchSize), last_frame_recording.getMax(LLPipeline::sStatBatchSize), last_frame_recording.getMean(LLPipeline::sStatBatchSize))); + } ypos += y_inc; addText(xpos, ypos, llformat("UI Verts/Calls: %d/%d", LLRender::sUIVerts, LLRender::sUICalls)); diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 004a59fda5..9fbb06a41e 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -250,7 +250,7 @@ public: S32 getCurrentMouseDX() const { return mCurrentMouseDelta.mX; } S32 getCurrentMouseDY() const { return mCurrentMouseDelta.mY; } LLCoordGL getCurrentMouseDelta() const { return mCurrentMouseDelta; } - static LLTrace::MeasurementStatHandle<>* getMouseVelocityStat() { return &sMouseVelocityStat; } + static LLTrace::SampleStatHandle<>* getMouseVelocityStat() { return &sMouseVelocityStat; } BOOL getLeftMouseDown() const { return mLeftMouseDown; } BOOL getMiddleMouseDown() const { return mMiddleMouseDown; } BOOL getRightMouseDown() const { return mRightMouseDown; } @@ -482,7 +482,7 @@ private: // Object temporarily hovered over while dragging LLPointer mDragHoveredObject; - static LLTrace::MeasurementStatHandle<> sMouseVelocityStat; + static LLTrace::SampleStatHandle<> sMouseVelocityStat; }; // diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 69f998f0f3..b6f48b4a66 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -914,7 +914,7 @@ void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp) { ++mRegionCrossingCount; LLTrace::Seconds delta = mRegionCrossingTimer.getElapsedTimeF32(); - sample(LLStatViewer::REGION_CROSSING_TIME, delta); + record(LLStatViewer::REGION_CROSSING_TIME, delta); // Diagnostics llinfos << "Region crossing took " << (F32)(delta * 1000.0).value() << " ms " << llendl; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 3f6269e768..6a0ef13894 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -198,6 +198,7 @@ BOOL LLPipeline::CameraOffset; F32 LLPipeline::CameraMaxCoF; F32 LLPipeline::CameraDoFResScale; F32 LLPipeline::RenderAutoHideSurfaceAreaLimit; +LLTrace::EventStatHandle LLPipeline::sStatBatchSize("renderbatchsize"); const F32 BACKLIGHT_DAY_MAGNITUDE_AVATAR = 0.2f; const F32 BACKLIGHT_NIGHT_MAGNITUDE_AVATAR = 0.1f; @@ -403,17 +404,9 @@ bool addDeferredAttachments(LLRenderTarget& target) LLPipeline::LLPipeline() : mBackfaceCull(FALSE), - mBatchCount(0), mMatrixOpCount(0), mTextureMatrixOps(0), - mMaxBatchSize(0), - mMinBatchSize(0), - mMeanBatchSize(0), - mTrianglesDrawn(0), mNumVisibleNodes(0), - mVerticesRelit(0), - mLightingChanges(0), - mGeometryChanges(0), mNumVisibleFaces(0), mInitialized(FALSE), @@ -1809,17 +1802,7 @@ void LLPipeline::resetFrameStats() { assertInitialized(); - add(LLStatViewer::TRIANGLES_DRAWN, mTrianglesDrawn); - - if (mBatchCount > 0) - { - mMeanBatchSize = gPipeline.mTrianglesDrawn/gPipeline.mBatchCount; - } - mTrianglesDrawn = 0; sCompiles = 0; - mVerticesRelit = 0; - mLightingChanges = 0; - mGeometryChanges = 0; mNumVisibleFaces = 0; if (mOldRenderDebugMask != mRenderDebugMask) @@ -1827,7 +1810,6 @@ void LLPipeline::resetFrameStats() gObjectList.clearDebugText(); mOldRenderDebugMask = mRenderDebugMask; } - } //external functions for asynchronous updating @@ -2585,7 +2567,6 @@ BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority) if (update_complete && assertInitialized()) { drawablep->setState(LLDrawable::BUILT); - mGeometryChanges++; } return update_complete; } @@ -3347,7 +3328,6 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) } } - mNumVisibleFaces += drawablep->getNumFaces(); } @@ -4516,10 +4496,8 @@ void LLPipeline::addTrianglesDrawn(S32 index_count, U32 render_type) count = index_count/3; } - mTrianglesDrawn += count; - mBatchCount++; - mMaxBatchSize = llmax(mMaxBatchSize, count); - mMinBatchSize = llmin(mMinBatchSize, count); + record(sStatBatchSize, count); + add(LLStatViewer::TRIANGLES_DRAWN, count); if (LLPipeline::sRenderFrameTest) { diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 720ddf79f5..ec976d3ecc 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -492,23 +492,14 @@ public: LLQuaternion mFlyCamRotation; BOOL mBackfaceCull; - S32 mBatchCount; S32 mMatrixOpCount; S32 mTextureMatrixOps; - S32 mMaxBatchSize; - S32 mMinBatchSize; - S32 mMeanBatchSize; - S32 mTrianglesDrawn; S32 mNumVisibleNodes; - S32 mVerticesRelit; S32 mDebugTextureUploadCost; S32 mDebugSculptUploadCost; S32 mDebugMeshUploadCost; - S32 mLightingChanges; - S32 mGeometryChanges; - S32 mNumVisibleFaces; static S32 sCompiles; @@ -542,6 +533,8 @@ public: static S32 sVisibleLightCount; static F32 sMinRenderSize; + static LLTrace::EventStatHandle sStatBatchSize; + //screen texture U32 mScreenWidth; U32 mScreenHeight; -- cgit v1.3 From 9fd3af3c389ed491b515cbb5136b344b069913e4 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 13 Jun 2013 15:29:15 -0700 Subject: SH-3931 WIP Interesting: Add graphs to visualize scene load metrics changed Units macros and argument order to make it more clear optimized units for integer types fixed merging of periodicrecordings...should eliminate duplicate entries in sceneloadmonitor history --- indra/llcharacter/llkeyframewalkmotion.cpp | 2 +- indra/llcommon/llcriticaldamp.cpp | 2 +- indra/llcommon/llcriticaldamp.h | 4 +- indra/llcommon/lldate.cpp | 2 +- indra/llcommon/lldate.h | 2 +- indra/llcommon/llfasttimer.cpp | 14 +- indra/llcommon/llfasttimer.h | 2 +- indra/llcommon/llprocessor.cpp | 2 +- indra/llcommon/llprocessor.h | 2 +- indra/llcommon/lltimer.cpp | 14 +- indra/llcommon/lltimer.h | 16 +- indra/llcommon/lltrace.h | 76 +++--- indra/llcommon/lltracerecording.cpp | 189 ++++++++------- indra/llcommon/lltracerecording.h | 56 ++--- indra/llcommon/llunit.h | 372 ++++++++++++++++++----------- indra/llcommon/tests/llunits_test.cpp | 104 ++++---- indra/llrender/llimagegl.cpp | 6 +- indra/llrender/llimagegl.h | 6 +- indra/llui/llstatbar.cpp | 4 +- indra/newview/llappviewer.cpp | 2 +- indra/newview/llappviewer.h | 2 +- indra/newview/llfasttimerview.cpp | 303 ++++++++++++----------- indra/newview/llfasttimerview.h | 77 +++--- indra/newview/llscenemonitor.cpp | 4 +- indra/newview/lltexturefetch.h | 2 +- indra/newview/lltextureview.cpp | 12 +- indra/newview/llviewerassetstats.cpp | 4 +- indra/newview/llviewerassetstats.h | 2 +- indra/newview/llviewermessage.cpp | 18 +- indra/newview/llviewerstats.cpp | 10 +- indra/newview/llviewerstats.h | 6 +- indra/newview/llviewertexture.cpp | 16 +- indra/newview/llviewertexture.h | 14 +- indra/newview/llviewerwindow.cpp | 2 +- indra/newview/pipeline.cpp | 2 +- 35 files changed, 735 insertions(+), 616 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/llcharacter/llkeyframewalkmotion.cpp b/indra/llcharacter/llkeyframewalkmotion.cpp index e188b06c03..c6ca0b542e 100755 --- a/indra/llcharacter/llkeyframewalkmotion.cpp +++ b/indra/llcharacter/llkeyframewalkmotion.cpp @@ -383,7 +383,7 @@ BOOL LLFlyAdjustMotion::onUpdate(F32 time, U8* joint_mask) F32 target_roll = llclamp(ang_vel.mV[VZ], -4.f, 4.f) * roll_factor; // roll is critically damped interpolation between current roll and angular velocity-derived target roll - mRoll = LLSmoothInterpolation::lerp(mRoll, target_roll, LLUnit(100)); + mRoll = LLSmoothInterpolation::lerp(mRoll, target_roll, LLUnit(100)); LLQuaternion roll(mRoll, LLVector3(0.f, 0.f, 1.f)); mPelvisState->setRotation(roll); diff --git a/indra/llcommon/llcriticaldamp.cpp b/indra/llcommon/llcriticaldamp.cpp index 2f013fe255..575fc4149e 100755 --- a/indra/llcommon/llcriticaldamp.cpp +++ b/indra/llcommon/llcriticaldamp.cpp @@ -81,7 +81,7 @@ void LLSmoothInterpolation::updateInterpolants() //----------------------------------------------------------------------------- // getInterpolant() //----------------------------------------------------------------------------- -F32 LLSmoothInterpolation::getInterpolant(LLUnit time_constant, bool use_cache) +F32 LLSmoothInterpolation::getInterpolant(LLUnit time_constant, bool use_cache) { if (time_constant == 0.f) { diff --git a/indra/llcommon/llcriticaldamp.h b/indra/llcommon/llcriticaldamp.h index ab5d4ba6e2..e174643cd0 100755 --- a/indra/llcommon/llcriticaldamp.h +++ b/indra/llcommon/llcriticaldamp.h @@ -42,10 +42,10 @@ public: static void updateInterpolants(); // ACCESSORS - static F32 getInterpolant(LLUnit time_constant, bool use_cache = true); + static F32 getInterpolant(LLUnit time_constant, bool use_cache = true); template - static T lerp(T a, T b, LLUnit time_constant, bool use_cache = true) + static T lerp(T a, T b, LLUnit time_constant, bool use_cache = true) { F32 interpolant = getInterpolant(time_constant, use_cache); return ((a * (1.f - interpolant)) diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp index 2efe39e158..7892269e35 100755 --- a/indra/llcommon/lldate.cpp +++ b/indra/llcommon/lldate.cpp @@ -55,7 +55,7 @@ LLDate::LLDate(const LLDate& date) : mSecondsSinceEpoch(date.mSecondsSinceEpoch) {} -LLDate::LLDate(LLUnit seconds_since_epoch) : +LLDate::LLDate(LLUnit seconds_since_epoch) : mSecondsSinceEpoch(seconds_since_epoch.value()) {} diff --git a/indra/llcommon/lldate.h b/indra/llcommon/lldate.h index b62a846147..1067ac5280 100755 --- a/indra/llcommon/lldate.h +++ b/indra/llcommon/lldate.h @@ -59,7 +59,7 @@ public: * * @param seconds_since_epoch The number of seconds since UTC epoch. */ - LLDate(LLUnit seconds_since_epoch); + LLDate(LLUnit seconds_since_epoch); /** * @brief Construct a date from a string representation diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index dfc72bd2ce..809a0327ca 100755 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -146,8 +146,8 @@ U64 TimeBlock::countsPerSecond() { #if LL_FASTTIMER_USE_RDTSC || !LL_WINDOWS //getCPUFrequency returns MHz and sCPUClockFrequency wants to be in Hz - static LLUnit sCPUClockFrequency = LLProcessorInfo().getCPUFrequency(); - + static LLUnit sCPUClockFrequency = LLProcessorInfo().getCPUFrequency(); + return sCPUClockFrequency.value(); #else // If we're not using RDTSC, each fasttimer tick is just a performance counter tick. // Not redefining the clock frequency itself (in llprocessor.cpp/calculate_cpu_frequency()) @@ -159,8 +159,8 @@ U64 TimeBlock::countsPerSecond() QueryPerformanceFrequency((LARGE_INTEGER*)&sCPUClockFrequency); firstcall = false; } -#endif return sCPUClockFrequency.value(); +#endif } #endif @@ -318,11 +318,11 @@ void TimeBlock::logStats() LL_DEBUGS("FastTimers") << "LLProcessorInfo().getCPUFrequency() " << LLProcessorInfo().getCPUFrequency() << LL_ENDL; LL_DEBUGS("FastTimers") << "getCPUClockCount32() " << getCPUClockCount32() << LL_ENDL; LL_DEBUGS("FastTimers") << "getCPUClockCount64() " << getCPUClockCount64() << LL_ENDL; - LL_DEBUGS("FastTimers") << "elapsed sec " << ((F64)getCPUClockCount64()) / (LLUnit(LLProcessorInfo().getCPUFrequency())) << LL_ENDL; + LL_DEBUGS("FastTimers") << "elapsed sec " << ((F64)getCPUClockCount64()) / (LLUnit(LLProcessorInfo().getCPUFrequency())) << LL_ENDL; } call_count++; - LLUnit total_time(0); + LLUnit total_time(0); LLSD sd; { @@ -365,7 +365,7 @@ void TimeBlock::dumpCurTimes() ++it) { TimeBlock* timerp = (*it); - LLUnit total_time_ms = last_frame_recording.getSum(*timerp); + LLUnit total_time_ms = last_frame_recording.getSum(*timerp); U32 num_calls = last_frame_recording.getSum(timerp->callCount()); // Don't bother with really brief times, keep output concise @@ -449,7 +449,7 @@ void TimeBlockAccumulator::reset( const TimeBlockAccumulator* other ) } } -LLUnit BlockTimer::getElapsedTime() +LLUnit BlockTimer::getElapsedTime() { U64 total_time = TimeBlock::getCPUClockCount64() - mStartTime; diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index 20514d1638..fdc6997d45 100755 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -71,7 +71,7 @@ public: BlockTimer(TimeBlock& timer); ~BlockTimer(); - LLUnit getElapsedTime(); + LLUnit getElapsedTime(); private: diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index 5ddfa6fcef..b80e813d84 100755 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -875,7 +875,7 @@ LLProcessorInfo::LLProcessorInfo() : mImpl(NULL) LLProcessorInfo::~LLProcessorInfo() {} -LLUnitImplicit LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); } +LLUnitImplicit LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); } bool LLProcessorInfo::hasSSE() const { return mImpl->hasSSE(); } bool LLProcessorInfo::hasSSE2() const { return mImpl->hasSSE2(); } bool LLProcessorInfo::hasAltivec() const { return mImpl->hasAltivec(); } diff --git a/indra/llcommon/llprocessor.h b/indra/llcommon/llprocessor.h index fbd427f484..7f220467b0 100755 --- a/indra/llcommon/llprocessor.h +++ b/indra/llcommon/llprocessor.h @@ -37,7 +37,7 @@ public: LLProcessorInfo(); ~LLProcessorInfo(); - LLUnitImplicit getCPUFrequency() const; + LLUnitImplicit getCPUFrequency() const; bool hasSSE() const; bool hasSSE2() const; bool hasAltivec() const; diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index 838155d54d..693809b622 100755 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp @@ -285,14 +285,14 @@ LLTimer::~LLTimer() } // static -LLUnitImplicit LLTimer::getTotalTime() +LLUnitImplicit LLTimer::getTotalTime() { // simply call into the implementation function. return totalTime(); } // static -LLUnitImplicit LLTimer::getTotalSeconds() +LLUnitImplicit LLTimer::getTotalSeconds() { return U64_to_F64(getTotalTime()) * USEC_TO_SEC_F64; } @@ -341,23 +341,23 @@ U64 getElapsedTimeAndUpdate(U64& lastClockCount) } -LLUnitImplicit LLTimer::getElapsedTimeF64() const +LLUnitImplicit LLTimer::getElapsedTimeF64() const { U64 last = mLastClockCount; return (F64)getElapsedTimeAndUpdate(last) * gClockFrequencyInv; } -LLUnitImplicit LLTimer::getElapsedTimeF32() const +LLUnitImplicit LLTimer::getElapsedTimeF32() const { return (F32)getElapsedTimeF64(); } -LLUnitImplicit LLTimer::getElapsedTimeAndResetF64() +LLUnitImplicit LLTimer::getElapsedTimeAndResetF64() { return (F64)getElapsedTimeAndUpdate(mLastClockCount) * gClockFrequencyInv; } -LLUnitImplicit LLTimer::getElapsedTimeAndResetF32() +LLUnitImplicit LLTimer::getElapsedTimeAndResetF32() { return (F32)getElapsedTimeAndResetF64(); } @@ -370,7 +370,7 @@ void LLTimer::setTimerExpirySec(F32 expiration) + (U64)((F32)(expiration * gClockFrequency)); } -LLUnitImplicit LLTimer::getRemainingTimeF32() const +LLUnitImplicit LLTimer::getRemainingTimeF32() const { U64 cur_ticks = get_clock_count(); if (cur_ticks > mExpirationTicks) diff --git a/indra/llcommon/lltimer.h b/indra/llcommon/lltimer.h index 0ba87d1e15..9e464c4b1a 100755 --- a/indra/llcommon/lltimer.h +++ b/indra/llcommon/lltimer.h @@ -67,16 +67,16 @@ public: // Return a high precision number of seconds since the start of // this application instance. - static LLUnitImplicit getElapsedSeconds() + static LLUnitImplicit getElapsedSeconds() { return sTimer->getElapsedTimeF64(); } // Return a high precision usec since epoch - static LLUnitImplicit getTotalTime(); + static LLUnitImplicit getTotalTime(); // Return a high precision seconds since epoch - static LLUnitImplicit getTotalSeconds(); + static LLUnitImplicit getTotalSeconds(); // MANIPULATORS @@ -87,16 +87,16 @@ public: void setTimerExpirySec(F32 expiration); BOOL checkExpirationAndReset(F32 expiration); BOOL hasExpired() const; - LLUnitImplicit getElapsedTimeAndResetF32(); // Returns elapsed time in seconds with reset - LLUnitImplicit getElapsedTimeAndResetF64(); + LLUnitImplicit getElapsedTimeAndResetF32(); // Returns elapsed time in seconds with reset + LLUnitImplicit getElapsedTimeAndResetF64(); - LLUnitImplicit getRemainingTimeF32() const; + LLUnitImplicit getRemainingTimeF32() const; static BOOL knownBadTimer(); // ACCESSORS - LLUnitImplicit getElapsedTimeF32() const; // Returns elapsed time in seconds - LLUnitImplicit getElapsedTimeF64() const; // Returns elapsed time in seconds + LLUnitImplicit getElapsedTimeF32() const; // Returns elapsed time in seconds + LLUnitImplicit getElapsedTimeF64() const; // Returns elapsed time in seconds bool getStarted() const { return mStarted; } diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index cfe1273b4b..1bf853c5c0 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -44,27 +44,27 @@ namespace LLTrace { class Recording; -typedef LLUnit Bytes; -typedef LLUnit Kibibytes; -typedef LLUnit Mibibytes; -typedef LLUnit Gibibytes; -typedef LLUnit Bits; -typedef LLUnit Kibibits; -typedef LLUnit Mibibits; -typedef LLUnit Gibibits; - -typedef LLUnit Seconds; -typedef LLUnit Milliseconds; -typedef LLUnit Minutes; -typedef LLUnit Hours; -typedef LLUnit Milliseconds; -typedef LLUnit Microseconds; -typedef LLUnit Nanoseconds; - -typedef LLUnit Meters; -typedef LLUnit Kilometers; -typedef LLUnit Centimeters; -typedef LLUnit Millimeters; +typedef LLUnit Bytes; +typedef LLUnit Kibibytes; +typedef LLUnit Mibibytes; +typedef LLUnit Gibibytes; +typedef LLUnit Bits; +typedef LLUnit Kibibits; +typedef LLUnit Mibibits; +typedef LLUnit Gibibits; + +typedef LLUnit Seconds; +typedef LLUnit Milliseconds; +typedef LLUnit Minutes; +typedef LLUnit Hours; +typedef LLUnit Milliseconds; +typedef LLUnit Microseconds; +typedef LLUnit Nanoseconds; + +typedef LLUnit Meters; +typedef LLUnit Kilometers; +typedef LLUnit Centimeters; +typedef LLUnit Millimeters; void init(); void cleanup(); @@ -216,6 +216,11 @@ public: } size_t size() const + { + return getNumIndices(); + } + + static size_t getNumIndices() { return sNextStorageSlot; } @@ -263,6 +268,7 @@ public: } size_t getIndex() const { return mAccumulatorIndex; } + static size_t getNumIndices() { return AccumulatorBuffer::getNumIndices(); } virtual const char* getUnitLabel() { return ""; } @@ -408,8 +414,8 @@ public: void sample(F64 value) { - LLUnitImplicit time_stamp = LLTimer::getTotalSeconds(); - LLUnitImplicit delta_time = time_stamp - mLastSampleTimeStamp; + LLUnitImplicit time_stamp = LLTimer::getTotalSeconds(); + LLUnitImplicit delta_time = time_stamp - mLastSampleTimeStamp; mLastSampleTimeStamp = time_stamp; if (mHasValue) @@ -498,8 +504,8 @@ public: void flush() { - LLUnitImplicit time_stamp = LLTimer::getTotalSeconds(); - LLUnitImplicit delta_time = time_stamp - mLastSampleTimeStamp; + LLUnitImplicit time_stamp = LLTimer::getTotalSeconds(); + LLUnitImplicit delta_time = time_stamp - mLastSampleTimeStamp; if (mHasValue) { @@ -528,7 +534,7 @@ private: F64 mMean, mVarianceSum; - LLUnitImplicit mLastSampleTimeStamp, + LLUnitImplicit mLastSampleTimeStamp, mTotalSamplingTime; U32 mNumSamples; @@ -578,8 +584,8 @@ private: class TimeBlockAccumulator { public: - typedef LLUnit value_t; - typedef LLUnit mean_t; + typedef LLUnit value_t; + typedef LLUnit mean_t; typedef TimeBlockAccumulator self_t; // fake classes that allows us to view different facets of underlying statistic @@ -591,8 +597,8 @@ public: struct SelfTimeFacet { - typedef LLUnit value_t; - typedef LLUnit mean_t; + typedef LLUnit value_t; + typedef LLUnit mean_t; }; TimeBlockAccumulator(); @@ -672,7 +678,7 @@ template void record(EventStatHandle& measurement, VALUE_T value) { T converted_value(value); - measurement.getPrimaryAccumulator()->record(LLUnits::rawValue(converted_value)); + measurement.getPrimaryAccumulator()->record(LLUnits::storageValue(converted_value)); } template @@ -694,7 +700,7 @@ template void sample(SampleStatHandle& measurement, VALUE_T value) { T converted_value(value); - measurement.getPrimaryAccumulator()->sample(LLUnits::rawValue(converted_value)); + measurement.getPrimaryAccumulator()->sample(LLUnits::storageValue(converted_value)); } template @@ -716,7 +722,7 @@ template void add(CountStatHandle& count, VALUE_T value) { T converted_value(value); - count.getPrimaryAccumulator()->add(LLUnits::rawValue(converted_value)); + count.getPrimaryAccumulator()->add(LLUnits::storageValue(converted_value)); } @@ -739,8 +745,8 @@ struct MemStatAccumulator struct ChildMemFacet { - typedef LLUnit value_t; - typedef LLUnit mean_t; + typedef LLUnit value_t; + typedef LLUnit mean_t; }; MemStatAccumulator() diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index d32504b014..ff90da3822 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -186,26 +186,18 @@ void Recording::handleSplitTo(Recording& other) void Recording::appendRecording( const Recording& other ) { - EPlayState play_state = getPlayState(); - { - pause(); - mBuffers.write()->append(*other.mBuffers); - mElapsedSeconds += other.mElapsedSeconds; - } - setPlayState(play_state); + update(); + mBuffers.write()->append(*other.mBuffers); + mElapsedSeconds += other.mElapsedSeconds; } void Recording::mergeRecording( const Recording& other) { - EPlayState play_state = getPlayState(); - { - pause(); - mBuffers.write()->merge(*other.mBuffers); - } - setPlayState(play_state); + update(); + mBuffers.write()->merge(*other.mBuffers); } -LLUnit Recording::getSum(const TraceType& stat) +LLUnit Recording::getSum(const TraceType& stat) { const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()]; update(); @@ -213,7 +205,7 @@ LLUnit Recording::getSum(const TraceType Recording::getSum(const TraceType& stat) +LLUnit Recording::getSum(const TraceType& stat) { const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()]; update(); @@ -227,85 +219,85 @@ U32 Recording::getSum(const TraceType& sta return mBuffers->mStackTimers[stat.getIndex()].mCalls; } -LLUnit Recording::getPerSec(const TraceType& stat) +LLUnit Recording::getPerSec(const TraceType& stat) { const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()]; update(); return (F64)(accumulator.mTotalTimeCounter - accumulator.mStartTotalTimeCounter) - / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds); + / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds.value()); } -LLUnit Recording::getPerSec(const TraceType& stat) +LLUnit Recording::getPerSec(const TraceType& stat) { const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()]; update(); return (F64)(accumulator.mSelfTimeCounter) - / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds); + / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds.value()); } F32 Recording::getPerSec(const TraceType& stat) { update(); - return (F32)mBuffers->mStackTimers[stat.getIndex()].mCalls / mElapsedSeconds; + return (F32)mBuffers->mStackTimers[stat.getIndex()].mCalls / mElapsedSeconds.value(); } -LLUnit Recording::getMin(const TraceType& stat) +LLUnit Recording::getMin(const TraceType& stat) { update(); return mBuffers->mMemStats[stat.getIndex()].mSize.getMin(); } -LLUnit Recording::getMean(const TraceType& stat) +LLUnit Recording::getMean(const TraceType& stat) { update(); return mBuffers->mMemStats[stat.getIndex()].mSize.getMean(); } -LLUnit Recording::getMax(const TraceType& stat) +LLUnit Recording::getMax(const TraceType& stat) { update(); return mBuffers->mMemStats[stat.getIndex()].mSize.getMax(); } -LLUnit Recording::getStandardDeviation(const TraceType& stat) +LLUnit Recording::getStandardDeviation(const TraceType& stat) { update(); return mBuffers->mMemStats[stat.getIndex()].mSize.getStandardDeviation(); } -LLUnit Recording::getLastValue(const TraceType& stat) +LLUnit Recording::getLastValue(const TraceType& stat) { update(); return mBuffers->mMemStats[stat.getIndex()].mSize.getLastValue(); } -LLUnit Recording::getMin(const TraceType& stat) +LLUnit Recording::getMin(const TraceType& stat) { update(); return mBuffers->mMemStats[stat.getIndex()].mChildSize.getMin(); } -LLUnit Recording::getMean(const TraceType& stat) +LLUnit Recording::getMean(const TraceType& stat) { update(); return mBuffers->mMemStats[stat.getIndex()].mChildSize.getMean(); } -LLUnit Recording::getMax(const TraceType& stat) +LLUnit Recording::getMax(const TraceType& stat) { update(); return mBuffers->mMemStats[stat.getIndex()].mChildSize.getMax(); } -LLUnit Recording::getStandardDeviation(const TraceType& stat) +LLUnit Recording::getStandardDeviation(const TraceType& stat) { update(); return mBuffers->mMemStats[stat.getIndex()].mChildSize.getStandardDeviation(); } -LLUnit Recording::getLastValue(const TraceType& stat) +LLUnit Recording::getLastValue(const TraceType& stat) { update(); return mBuffers->mMemStats[stat.getIndex()].mChildSize.getLastValue(); @@ -341,7 +333,7 @@ F64 Recording::getPerSec( const TraceType& stat ) update(); F64 sum = mBuffers->mCounts[stat.getIndex()].getSum(); return (sum != 0.0) - ? (sum / mElapsedSeconds) + ? (sum / mElapsedSeconds.value()) : 0.0; } @@ -430,6 +422,7 @@ U32 Recording::getSampleCount( const TraceType& stat ) PeriodicRecording::PeriodicRecording( U32 num_periods, EPlayState state) : mAutoResize(num_periods == 0), mCurPeriod(0), + mNumPeriods(0), mRecordingPeriods(num_periods ? num_periods : 1) { setPlayState(state); @@ -443,9 +436,20 @@ void PeriodicRecording::nextPeriod() } Recording& old_recording = getCurRecording(); - mCurPeriod = (mCurPeriod + 1) % mRecordingPeriods.size(); old_recording.splitTo(getCurRecording()); + + mNumPeriods = llmin(mRecordingPeriods.size(), mNumPeriods + 1); +} + +void PeriodicRecording::appendRecording(Recording& recording) +{ + // if I have a recording of any length, then close it off and start a fresh one + if (getCurRecording().getDuration().value()) + { + nextPeriod(); + } + getCurRecording().appendRecording(recording); } @@ -453,77 +457,77 @@ void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other ) { if (other.mRecordingPeriods.empty()) return; - EPlayState play_state = getPlayState(); - pause(); - - EPlayState other_play_state = other.getPlayState(); - other.pause(); - - U32 other_recording_count = other.mRecordingPeriods.size(); - - Recording& other_oldest_recording = other.mRecordingPeriods[(other.mCurPeriod + 1) % other.mRecordingPeriods.size()]; + getCurRecording().update(); + other.getCurRecording().update(); // if I have a recording of any length, then close it off and start a fresh one if (getCurRecording().getDuration().value()) { nextPeriod(); } - getCurRecording().appendRecording(other_oldest_recording); - if (other_recording_count > 1) + if (mAutoResize) { - if (mAutoResize) + S32 other_index = (other.mCurPeriod + 1) % other.mRecordingPeriods.size(); + S32 end_index = (other.mCurPeriod) % other.mRecordingPeriods.size(); + + do { - for (S32 other_index = (other.mCurPeriod + 2) % other_recording_count, - end_index = (other.mCurPeriod + 1) % other_recording_count; - other_index != end_index; - other_index = (other_index + 1) % other_recording_count) + if (other.mRecordingPeriods[other_index].getDuration().value()) { - llassert(other.mRecordingPeriods[other_index].getDuration() != 0.f - && (mRecordingPeriods.empty() - || other.mRecordingPeriods[other_index].getDuration() != mRecordingPeriods.back().getDuration())); mRecordingPeriods.push_back(other.mRecordingPeriods[other_index]); } - - mCurPeriod = mRecordingPeriods.size() - 1; + other_index = (other_index + 1) % other.mRecordingPeriods.size(); } - else + while(other_index != end_index); + + mCurPeriod = mRecordingPeriods.size() - 1; + mNumPeriods = mRecordingPeriods.size(); + } + else + { + //FIXME: get proper number of recordings from other...might not have used all its slots + size_t num_to_copy = llmin( mRecordingPeriods.size(), other.getNumRecordedPeriods()); + std::vector::iterator src_it = other.mRecordingPeriods.begin() + + ( (other.mCurPeriod + 1 // oldest period + + (other.mRecordingPeriods.size() - num_to_copy)) // minus room for copy + % other.mRecordingPeriods.size()); + std::vector::iterator dest_it = mRecordingPeriods.begin() + mCurPeriod; + + for(size_t i = 0; i < num_to_copy; i++) { - size_t num_to_copy = llmin( mRecordingPeriods.size(), other.mRecordingPeriods.size() - 1); - std::vector::iterator src_it = other.mRecordingPeriods.begin() - + ( (other.mCurPeriod + 1 // oldest period - + (other.mRecordingPeriods.size() - num_to_copy)) // minus room for copy - % other.mRecordingPeriods.size()); - std::vector::iterator dest_it = mRecordingPeriods.begin() + ((mCurPeriod + 1) % mRecordingPeriods.size()); - - for(S32 i = 0; i < num_to_copy; i++) - { - *dest_it = *src_it; + *dest_it = *src_it; - if (++src_it == other.mRecordingPeriods.end()) - { - src_it = other.mRecordingPeriods.begin(); - } + if (++src_it == other.mRecordingPeriods.end()) + { + src_it = other.mRecordingPeriods.begin(); + } - if (++dest_it == mRecordingPeriods.end()) - { - dest_it = mRecordingPeriods.begin(); - } + if (++dest_it == mRecordingPeriods.end()) + { + dest_it = mRecordingPeriods.begin(); } - - mCurPeriod = (mCurPeriod + num_to_copy) % mRecordingPeriods.size(); } + + // want argument to % to be positive, otherwise result could be negative and thus out of bounds + llassert(num_to_copy >= 1); + // advance to last recording period copied, so we can check if the last period had actually carried any data, in which case we'll advance below + // using nextPeriod() which retains continuity (mLastValue, etc) + mCurPeriod = (mCurPeriod + num_to_copy - 1) % mRecordingPeriods.size(); + mNumPeriods = llmin(mRecordingPeriods.size(), mNumPeriods + num_to_copy); } - nextPeriod(); - - setPlayState(play_state); - other.setPlayState(other_play_state); + if (getCurRecording().getDuration().value()) + { + //call this to chain last period copied to new active period + nextPeriod(); + } + getCurRecording().setPlayState(getPlayState()); } -LLUnit PeriodicRecording::getDuration() const +LLUnit PeriodicRecording::getDuration() const { - LLUnit duration; + LLUnit duration; size_t num_periods = mRecordingPeriods.size(); for (size_t i = 1; i <= num_periods; i++) { @@ -615,7 +619,7 @@ void PeriodicRecording::handleSplitTo(PeriodicRecording& other) F64 PeriodicRecording::getPeriodMean( const TraceType& stat, size_t num_periods /*= U32_MAX*/ ) { size_t total_periods = mRecordingPeriods.size(); - num_periods = llmin(num_periods, total_periods); + num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods); F64 mean = 0; if (num_periods <= 0) { return mean; } @@ -643,7 +647,7 @@ F64 PeriodicRecording::getPeriodMean( const TraceType& stat, s F64 PeriodicRecording::getPeriodMin( const TraceType& stat, size_t num_periods /*= U32_MAX*/ ) { size_t total_periods = mRecordingPeriods.size(); - num_periods = llmin(num_periods, total_periods); + num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods); F64 min_val = std::numeric_limits::max(); for (S32 i = 1; i <= num_periods; i++) @@ -657,7 +661,7 @@ F64 PeriodicRecording::getPeriodMin( const TraceType& stat, si F64 PeriodicRecording::getPeriodMax( const TraceType& stat, size_t num_periods /*= U32_MAX*/ ) { size_t total_periods = mRecordingPeriods.size(); - num_periods = llmin(num_periods, total_periods); + num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods); F64 max_val = std::numeric_limits::min(); for (S32 i = 1; i <= num_periods; i++) @@ -671,7 +675,7 @@ F64 PeriodicRecording::getPeriodMax( const TraceType& stat, si F64 PeriodicRecording::getPeriodMin( const TraceType& stat, size_t num_periods /*= U32_MAX*/ ) { size_t total_periods = mRecordingPeriods.size(); - num_periods = llmin(num_periods, total_periods); + num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods); F64 min_val = std::numeric_limits::max(); for (S32 i = 1; i <= num_periods; i++) @@ -685,7 +689,7 @@ F64 PeriodicRecording::getPeriodMin( const TraceType& stat, s F64 PeriodicRecording::getPeriodMax(const TraceType& stat, size_t num_periods /*= U32_MAX*/) { size_t total_periods = mRecordingPeriods.size(); - num_periods = llmin(num_periods, total_periods); + num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods); F64 max_val = std::numeric_limits::min(); for (S32 i = 1; i <= num_periods; i++) @@ -700,9 +704,9 @@ F64 PeriodicRecording::getPeriodMax(const TraceType& stat, si F64 PeriodicRecording::getPeriodMean( const TraceType& stat, size_t num_periods /*= U32_MAX*/ ) { size_t total_periods = mRecordingPeriods.size(); - num_periods = llmin(num_periods, total_periods); + num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods); - LLUnit total_duration = 0.f; + LLUnit total_duration = 0.f; F64 mean = 0; if (num_periods <= 0) { return mean; } @@ -712,7 +716,7 @@ F64 PeriodicRecording::getPeriodMean( const TraceType& stat, S32 index = (mCurPeriod + total_periods - i) % total_periods; if (mRecordingPeriods[index].getDuration() > 0.f) { - LLUnit recording_duration = mRecordingPeriods[index].getDuration(); + LLUnit recording_duration = mRecordingPeriods[index].getDuration(); mean += mRecordingPeriods[index].getMean(stat) * recording_duration.value(); total_duration += recording_duration; } @@ -734,13 +738,11 @@ F64 PeriodicRecording::getPeriodMean( const TraceType& stat, void ExtendableRecording::extend() { // stop recording to get latest data - mPotentialRecording.stop(); + mPotentialRecording.update(); // push the data back to accepted recording mAcceptedRecording.appendRecording(mPotentialRecording); // flush data, so we can start from scratch mPotentialRecording.reset(); - // go back to play state we were in initially - mPotentialRecording.setPlayState(getPlayState()); } void ExtendableRecording::handleStart() @@ -777,15 +779,10 @@ ExtendablePeriodicRecording::ExtendablePeriodicRecording() void ExtendablePeriodicRecording::extend() { - llassert(mPotentialRecording.getPlayState() == getPlayState()); - // stop recording to get latest data - mPotentialRecording.pause(); // push the data back to accepted recording mAcceptedRecording.appendPeriodicRecording(mPotentialRecording); // flush data, so we can start from scratch mPotentialRecording.reset(); - // go back to play state we were in initially - mPotentialRecording.setPlayState(getPlayState()); } diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index 4651bfcb61..e3cef77b06 100644 --- a/indra/llcommon/lltracerecording.h +++ b/indra/llcommon/lltracerecording.h @@ -148,26 +148,26 @@ namespace LLTrace void makeUnique() { mBuffers.makeUnique(); } // Timer accessors - LLUnit getSum(const TraceType& stat); - LLUnit getSum(const TraceType& stat); + LLUnit getSum(const TraceType& stat); + LLUnit getSum(const TraceType& stat); U32 getSum(const TraceType& stat); - LLUnit getPerSec(const TraceType& stat); - LLUnit getPerSec(const TraceType& stat); + LLUnit getPerSec(const TraceType& stat); + LLUnit getPerSec(const TraceType& stat); F32 getPerSec(const TraceType& stat); // Memory accessors - LLUnit getMin(const TraceType& stat); - LLUnit getMean(const TraceType& stat); - LLUnit getMax(const TraceType& stat); - LLUnit getStandardDeviation(const TraceType& stat); - LLUnit getLastValue(const TraceType& stat); - - LLUnit getMin(const TraceType& stat); - LLUnit getMean(const TraceType& stat); - LLUnit getMax(const TraceType& stat); - LLUnit getStandardDeviation(const TraceType& stat); - LLUnit getLastValue(const TraceType& stat); + LLUnit getMin(const TraceType& stat); + LLUnit getMean(const TraceType& stat); + LLUnit getMax(const TraceType& stat); + LLUnit getStandardDeviation(const TraceType& stat); + LLUnit getLastValue(const TraceType& stat); + + LLUnit getMin(const TraceType& stat); + LLUnit getMean(const TraceType& stat); + LLUnit getMax(const TraceType& stat); + LLUnit getStandardDeviation(const TraceType& stat); + LLUnit getLastValue(const TraceType& stat); U32 getSum(const TraceType& stat); U32 getSum(const TraceType& stat); @@ -273,7 +273,7 @@ namespace LLTrace U32 getSampleCount(const TraceType& stat); - LLUnit getDuration() const { return LLUnit(mElapsedSeconds); } + LLUnit getDuration() const { return mElapsedSeconds; } protected: friend class ThreadRecorder; @@ -288,7 +288,7 @@ namespace LLTrace class ThreadRecorder* getThreadRecorder(); LLTimer mSamplingTimer; - F64 mElapsedSeconds; + LLUnit mElapsedSeconds; LLCopyOnWritePointer mBuffers; }; @@ -299,11 +299,12 @@ namespace LLTrace PeriodicRecording(U32 num_periods, EPlayState state = STOPPED); void nextPeriod(); - U32 getNumPeriods() { return mRecordingPeriods.size(); } + size_t getNumRecordedPeriods() { return mNumPeriods; } - LLUnit getDuration() const; + LLUnit getDuration() const; void appendPeriodicRecording(PeriodicRecording& other); + void appendRecording(Recording& recording); Recording& getLastRecording(); const Recording& getLastRecording() const; Recording& getCurRecording(); @@ -317,7 +318,7 @@ namespace LLTrace typename T::value_t getPeriodMin(const TraceType& stat, size_t num_periods = U32_MAX) { size_t total_periods = mRecordingPeriods.size(); - num_periods = llmin(num_periods, total_periods); + num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods); typename T::value_t min_val = std::numeric_limits::max(); for (S32 i = 1; i <= num_periods; i++) @@ -346,7 +347,7 @@ namespace LLTrace F64 getPeriodMinPerSec(const TraceType& stat, size_t num_periods = U32_MAX) { size_t total_periods = mRecordingPeriods.size(); - num_periods = llmin(num_periods, total_periods); + num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods); F64 min_val = std::numeric_limits::max(); for (S32 i = 1; i <= num_periods; i++) @@ -362,7 +363,7 @@ namespace LLTrace typename T::value_t getPeriodMax(const TraceType& stat, size_t num_periods = U32_MAX) { size_t total_periods = mRecordingPeriods.size(); - num_periods = llmin(num_periods, total_periods); + num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods); typename T::value_t max_val = std::numeric_limits::min(); for (S32 i = 1; i <= num_periods; i++) @@ -391,7 +392,7 @@ namespace LLTrace F64 getPeriodMaxPerSec(const TraceType& stat, size_t num_periods = U32_MAX) { size_t total_periods = mRecordingPeriods.size(); - num_periods = llmin(num_periods, total_periods); + num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods); F64 max_val = std::numeric_limits::min(); for (S32 i = 1; i <= num_periods; i++) @@ -407,7 +408,7 @@ namespace LLTrace typename T::mean_t getPeriodMean(const TraceType& stat, size_t num_periods = U32_MAX) { size_t total_periods = mRecordingPeriods.size(); - num_periods = llmin(num_periods, total_periods); + num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods); typename T::mean_t mean = 0; if (num_periods <= 0) { return mean; } @@ -442,7 +443,7 @@ namespace LLTrace typename T::mean_t getPeriodMeanPerSec(const TraceType& stat, size_t num_periods = U32_MAX) { size_t total_periods = mRecordingPeriods.size(); - num_periods = llmin(num_periods, total_periods); + num_periods = llmin(num_periods, isStarted() ? total_periods - 1 : total_periods); typename T::mean_t mean = 0; if (num_periods <= 0) { return mean; } @@ -468,8 +469,9 @@ namespace LLTrace private: std::vector mRecordingPeriods; - const bool mAutoResize; - S32 mCurPeriod; + const bool mAutoResize; + size_t mCurPeriod; + size_t mNumPeriods; }; PeriodicRecording& get_frame_recording(); diff --git a/indra/llcommon/llunit.h b/indra/llcommon/llunit.h index f48cbe0e11..5b961c81f0 100644 --- a/indra/llcommon/llunit.h +++ b/indra/llcommon/llunit.h @@ -35,31 +35,31 @@ namespace LLUnits { template -struct ConversionFactor +struct Convert { - static F64 get() + static VALUE_TYPE get(VALUE_TYPE val) { // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template llstatic_assert_template(DERIVED_UNITS_TAG, false, "Cannot convert between types."); - return 0; + return val; } }; template -struct ConversionFactor +struct Convert { - static F64 get() + static VALUE_TYPE get(VALUE_TYPE val) { - return 1; + return val; } }; } -template +template struct LLUnit { - typedef LLUnit self_t; + typedef LLUnit self_t; typedef STORAGE_TYPE storage_t; // value initialization @@ -68,11 +68,16 @@ struct LLUnit {} // unit initialization and conversion - template - LLUnit(LLUnit other) + template + LLUnit(LLUnit other) : mValue(convert(other)) {} + bool operator == (const self_t& other) + { + return mValue = other.mValue; + } + // value assignment self_t& operator = (storage_t value) { @@ -81,8 +86,8 @@ struct LLUnit } // unit assignment - template - self_t& operator = (LLUnit other) + template + self_t& operator = (LLUnit other) { mValue = convert(other); return *this; @@ -93,9 +98,9 @@ struct LLUnit return mValue; } - template LLUnit as() + template LLUnit as() { - return LLUnit(*this); + return LLUnit(*this); } @@ -104,8 +109,8 @@ struct LLUnit mValue += value; } - template - void operator += (LLUnit other) + template + void operator += (LLUnit other) { mValue += convert(other); } @@ -115,8 +120,8 @@ struct LLUnit mValue -= value; } - template - void operator -= (LLUnit other) + template + void operator -= (LLUnit other) { mValue -= convert(other); } @@ -127,7 +132,7 @@ struct LLUnit } template - void operator *= (LLUnit multiplicand) + void operator *= (LLUnit multiplicand) { // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template llstatic_assert_template(OTHER_UNIT, false, "Multiplication of unit types not supported."); @@ -139,37 +144,43 @@ struct LLUnit } template - void operator /= (LLUnit divisor) + void operator /= (LLUnit divisor) { // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template llstatic_assert_template(OTHER_UNIT, false, "Illegal in-place division of unit types."); } - template - static storage_t convert(LLUnit v) + template + static storage_t convert(LLUnit v) { - return (storage_t)(v.value() - * LLUnits::ConversionFactor::get() - * LLUnits::ConversionFactor::get()); + return (storage_t)LLUnits::Convert::get((STORAGE_TYPE) + LLUnits::Convert::get(v.value())); } + template + static storage_t convert(LLUnit v) + { + return (storage_t)(v.value()); + } + + protected: storage_t mValue; }; -template -struct LLUnitImplicit : public LLUnit +template +struct LLUnitImplicit : public LLUnit { - typedef LLUnitImplicit self_t; - typedef typename LLUnit::storage_t storage_t; - typedef LLUnit base_t; + typedef LLUnitImplicit self_t; + typedef typename LLUnit::storage_t storage_t; + typedef LLUnit base_t; LLUnitImplicit(storage_t value = storage_t()) : base_t(value) {} - template - LLUnitImplicit(LLUnit other) + template + LLUnitImplicit(LLUnit other) : base_t(convert(other)) {} @@ -184,50 +195,50 @@ struct LLUnitImplicit : public LLUnit // // operator + // -template -LLUnit operator + (LLUnit first, LLUnit second) +template +LLUnit operator + (LLUnit first, LLUnit second) { - LLUnit result(first); + LLUnit result(first); result += second; return result; } -template -LLUnit operator + (LLUnit first, SCALAR_TYPE second) +template +LLUnit operator + (LLUnit first, SCALAR_TYPE second) { - LLUnit result(first); + LLUnit result(first); result += second; return result; } -template -LLUnit operator + (SCALAR_TYPE first, LLUnit second) +template +LLUnit operator + (SCALAR_TYPE first, LLUnit second) { - LLUnit result(first); + LLUnit result(first); result += second; return result; } -template -LLUnitImplicit operator + (LLUnitImplicit first, LLUnit second) +template +LLUnitImplicit operator + (LLUnitImplicit first, LLUnit second) { - LLUnitImplicit result(first); + LLUnitImplicit result(first); result += second; return result; } -template -LLUnitImplicit operator + (LLUnitImplicit first, SCALAR_TYPE second) +template +LLUnitImplicit operator + (LLUnitImplicit first, SCALAR_TYPE second) { - LLUnitImplicit result(first); + LLUnitImplicit result(first); result += second; return result; } -template -LLUnitImplicit operator + (LLUnitImplicit first, LLUnitImplicit second) +template +LLUnitImplicit operator + (LLUnitImplicit first, LLUnitImplicit second) { - LLUnitImplicit result(first); + LLUnitImplicit result(first); result += second; return result; } @@ -235,50 +246,50 @@ LLUnitImplicit operator + (LLUnitImplicit -LLUnit operator - (LLUnit first, LLUnit second) +template +LLUnit operator - (LLUnit first, LLUnit second) { - LLUnit result(first); + LLUnit result(first); result -= second; return result; } -template -LLUnit operator - (LLUnit first, SCALAR_TYPE second) +template +LLUnit operator - (LLUnit first, SCALAR_TYPE second) { - LLUnit result(first); + LLUnit result(first); result -= second; return result; } -template -LLUnit operator - (SCALAR_TYPE first, LLUnit second) +template +LLUnit operator - (SCALAR_TYPE first, LLUnit second) { - LLUnit result(first); + LLUnit result(first); result -= second; return result; } -template -LLUnitImplicit operator - (LLUnitImplicit first, LLUnitImplicit second) +template +LLUnitImplicit operator - (LLUnitImplicit first, LLUnitImplicit second) { - LLUnitImplicit result(first); + LLUnitImplicit result(first); result -= second; return result; } -template -LLUnitImplicit operator - (LLUnitImplicit first, SCALAR_TYPE second) +template +LLUnitImplicit operator - (LLUnitImplicit first, SCALAR_TYPE second) { - LLUnitImplicit result(first); + LLUnitImplicit result(first); result -= second; return result; } -template -LLUnitImplicit operator - (SCALAR_TYPE first, LLUnitImplicit second) +template +LLUnitImplicit operator - (SCALAR_TYPE first, LLUnitImplicit second) { - LLUnitImplicit result(first); + LLUnitImplicit result(first); result -= second; return result; } @@ -286,102 +297,100 @@ LLUnitImplicit operator - (SCALAR_TYPE first, LLUnitImp // // operator * // -template -LLUnit operator * (SCALAR_TYPE first, LLUnit second) +template +LLUnit operator * (SCALAR_TYPE first, LLUnit second) { - return LLUnit((STORAGE_TYPE)(first * second.value())); + return LLUnit((STORAGE_TYPE)(first * second.value())); } -template -LLUnit operator * (LLUnit first, SCALAR_TYPE second) +template +LLUnit operator * (LLUnit first, SCALAR_TYPE second) { - return LLUnit((STORAGE_TYPE)(first.value() * second)); + return LLUnit((STORAGE_TYPE)(first.value() * second)); } -template -LLUnit operator * (LLUnit, LLUnit) +template +LLUnit operator * (LLUnit, LLUnit) { // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template llstatic_assert_template(STORAGE_TYPE1, false, "Multiplication of unit types results in new unit type - not supported."); - return LLUnit(); + return LLUnit(); } -template -LLUnitImplicit operator * (SCALAR_TYPE first, LLUnitImplicit second) +template +LLUnitImplicit operator * (SCALAR_TYPE first, LLUnitImplicit second) { - return LLUnitImplicit(first * second.value()); + return LLUnitImplicit(first * second.value()); } -template -LLUnitImplicit operator * (LLUnitImplicit first, SCALAR_TYPE second) +template +LLUnitImplicit operator * (LLUnitImplicit first, SCALAR_TYPE second) { - return LLUnitImplicit(first.value() * second); + return LLUnitImplicit(first.value() * second); } -template -LLUnitImplicit operator * (LLUnitImplicit, LLUnitImplicit) +template +LLUnitImplicit operator * (LLUnitImplicit, LLUnitImplicit) { // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template llstatic_assert_template(STORAGE_TYPE1, false, "Multiplication of unit types results in new unit type - not supported."); - return LLUnitImplicit(); + return LLUnitImplicit(); } // // operator / // -template -SCALAR_TYPE operator / (SCALAR_TYPE first, LLUnit second) +template +SCALAR_TYPE operator / (SCALAR_TYPE first, LLUnit second) { return SCALAR_TYPE(first / second.value()); } -template -LLUnit operator / (LLUnit first, SCALAR_TYPE second) +template +LLUnit operator / (LLUnit first, SCALAR_TYPE second) { - return LLUnit((STORAGE_TYPE)(first.value() / second)); + return LLUnit((STORAGE_TYPE)(first.value() / second)); } -template -STORAGE_TYPE1 operator / (LLUnit first, LLUnit second) +template +STORAGE_TYPE1 operator / (LLUnit first, LLUnit second) { - // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template - return STORAGE_TYPE1(first.value() / second.value()); + return STORAGE_TYPE1(first.value() / first.convert(second)); } -template -LLUnitImplicit operator / (LLUnitImplicit first, SCALAR_TYPE second) +template +LLUnitImplicit operator / (LLUnitImplicit first, SCALAR_TYPE second) { - return LLUnitImplicit((STORAGE_TYPE)(first.value() / second)); + return LLUnitImplicit((STORAGE_TYPE)(first.value() / second)); } -template -STORAGE_TYPE1 operator / (LLUnitImplicit first, LLUnitImplicit second) +template +STORAGE_TYPE1 operator / (LLUnitImplicit first, LLUnitImplicit second) { - // spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template - return STORAGE_TYPE1(first.value() / second.value()); + return STORAGE_TYPE1(first.value() / first.convert(second)); } #define COMPARISON_OPERATORS(op) \ -template \ -bool operator op (SCALAR_TYPE first, LLUnit second) \ +template \ +bool operator op (SCALAR_TYPE first, LLUnit second) \ { \ return first op second.value(); \ } \ \ -template \ -bool operator op (LLUnit first, SCALAR_TYPE second) \ +template \ +bool operator op (LLUnit first, SCALAR_TYPE second) \ { \ return first.value() op second; \ } \ \ -template \ -bool operator op (LLUnitImplicit first, LLUnitImplicit second) \ +template \ +bool operator op (LLUnitImplicit first, LLUnitImplicit second) \ { \ return first.value() op first.convert(second); \ } \ \ -template \ - bool operator op (LLUnit first, LLUnit second) \ +template \ + bool operator op (LLUnit first, LLUnit second) \ { \ return first.value() op first.convert(second); \ } @@ -401,7 +410,7 @@ struct LLGetUnitLabel }; template -struct LLGetUnitLabel > +struct LLGetUnitLabel > { static const char* getUnitLabel() { return T::getUnitLabel(); } }; @@ -411,70 +420,147 @@ struct LLGetUnitLabel > // namespace LLUnits { + +template +struct LinearOps +{ + typedef LinearOps self_t; + LinearOps(VALUE_TYPE val) : mValue (val) {} + + operator VALUE_TYPE() const { return mValue; } + VALUE_TYPE mValue; + + template + self_t operator * (T other) + { + return mValue * other; + } + + template + self_t operator / (T other) + { + return mValue / other; + } + + template + self_t operator + (T other) + { + return mValue + other; + } + + template + self_t operator - (T other) + { + return mValue - other; + } +}; + +template +struct InverseLinearOps +{ + typedef InverseLinearOps self_t; + + InverseLinearOps(VALUE_TYPE val) : mValue (val) {} + operator VALUE_TYPE() const { return mValue; } + VALUE_TYPE mValue; + + template + self_t operator * (T other) + { + return mValue / other; + } + + template + self_t operator / (T other) + { + return mValue * other; + } + + template + self_t operator + (T other) + { + return mValue - other; + } + + template + self_t operator - (T other) + { + return mValue + other; + } +}; + + template -T rawValue(T val) { return val; } +T storageValue(T val) { return val; } template -STORAGE_TYPE rawValue(LLUnit val) { return val.value(); } +STORAGE_TYPE storageValue(LLUnit val) { return val.value(); } template -STORAGE_TYPE rawValue(LLUnitImplicit val) { return val.value(); } +STORAGE_TYPE storageValue(LLUnitImplicit val) { return val.value(); } -#define LL_DECLARE_DERIVED_UNIT(conversion_factor, base_unit_name, unit_name, unit_label) \ +#define LL_DECLARE_BASE_UNIT(base_unit_name, unit_label) \ +struct base_unit_name { typedef base_unit_name base_unit_t; static const char* getUnitLabel() { return unit_label; }} + +#define LL_DECLARE_DERIVED_UNIT(unit_name, unit_label, base_unit_name, conversion_operation) \ struct unit_name \ { \ typedef base_unit_name base_unit_t; \ static const char* getUnitLabel() { return unit_label; } \ }; \ template \ -struct ConversionFactor \ +struct Convert \ { \ - static F64 get() \ + static STORAGE_TYPE get(STORAGE_TYPE val) \ { \ - return (F64)conversion_factor; \ + return (LinearOps(val) conversion_operation).mValue; \ } \ }; \ \ template \ -struct ConversionFactor \ +struct Convert \ { \ - static F64 get() \ + static STORAGE_TYPE get(STORAGE_TYPE val) \ { \ - return (F64)(1.0 / (conversion_factor)); \ + return (InverseLinearOps(val) conversion_operation).mValue; \ } \ } -#define LL_DECLARE_BASE_UNIT(base_unit_name, unit_label) \ -struct base_unit_name { typedef base_unit_name base_unit_t; static const char* getUnitLabel() { return unit_label; }} - LL_DECLARE_BASE_UNIT(Bytes, "B"); -LL_DECLARE_DERIVED_UNIT(1024, Bytes, Kibibytes, "KiB"); -LL_DECLARE_DERIVED_UNIT(1024 * 1024, Bytes, Mibibytes, "MiB"); -LL_DECLARE_DERIVED_UNIT(1024 * 1024 * 1024, Bytes, Gibibytes, "GiB"); -LL_DECLARE_DERIVED_UNIT(1.0 / 8.0, Bytes, Bits, "b"); -LL_DECLARE_DERIVED_UNIT(1024 / 8, Bytes, Kibibits, "Kib"); -LL_DECLARE_DERIVED_UNIT(1024 / 8, Bytes, Mibibits, "Mib"); -LL_DECLARE_DERIVED_UNIT(1024 * 1024 * 1024 / 8, Bytes, Gibibits, "Gib"); +LL_DECLARE_DERIVED_UNIT(Kilobytes, "KB", Bytes, * 1000); +LL_DECLARE_DERIVED_UNIT(Megabytes, "MB", Bytes, * 1000 * 1000); +LL_DECLARE_DERIVED_UNIT(Gigabytes, "GB", Bytes, * 1000 * 1000 * 1000); +LL_DECLARE_DERIVED_UNIT(Kibibytes, "KiB", Bytes, * 1024); +LL_DECLARE_DERIVED_UNIT(Mibibytes, "MiB", Bytes, * 1024 * 1024); +LL_DECLARE_DERIVED_UNIT(Gibibytes, "GiB", Bytes, * 1024 * 1024 * 1024); + +LL_DECLARE_DERIVED_UNIT(Bits, "b", Bytes, / 8); +LL_DECLARE_DERIVED_UNIT(Kilobits, "Kb", Bytes, * (1000 / 8)); +LL_DECLARE_DERIVED_UNIT(Megabits, "Mb", Bytes, * (1000 / 8)); +LL_DECLARE_DERIVED_UNIT(Gigabits, "Gb", Bytes, * (1000 * 1000 * 1000 / 8)); +LL_DECLARE_DERIVED_UNIT(Kibibits, "Kib", Bytes, * (1024 / 8)); +LL_DECLARE_DERIVED_UNIT(Mibibits, "Mib", Bytes, * (1024 / 8)); +LL_DECLARE_DERIVED_UNIT(Gibibits, "Gib", Bytes, * (1024 * 1024 * 1024 / 8)); LL_DECLARE_BASE_UNIT(Seconds, "s"); -LL_DECLARE_DERIVED_UNIT(60, Seconds, Minutes, "min"); -LL_DECLARE_DERIVED_UNIT(60 * 60, Seconds, Hours, "h"); -LL_DECLARE_DERIVED_UNIT(1.0 / 1000.0, Seconds, Milliseconds, "ms"); -LL_DECLARE_DERIVED_UNIT(1.0 / 1000000.0, Seconds, Microseconds, "\x09\x3cs"); -LL_DECLARE_DERIVED_UNIT(1.0 / 1000000000.0, Seconds, Nanoseconds, "ns"); +LL_DECLARE_DERIVED_UNIT(Minutes, "min", Seconds, * 60); +LL_DECLARE_DERIVED_UNIT(Hours, "h", Seconds, * 60 * 60); +LL_DECLARE_DERIVED_UNIT(Milliseconds, "ms", Seconds, / 1000); +LL_DECLARE_DERIVED_UNIT(Microseconds, "\x09\x3cs", Seconds, / 1000000); +LL_DECLARE_DERIVED_UNIT(Nanoseconds, "ns", Seconds, / 1000000000); LL_DECLARE_BASE_UNIT(Meters, "m"); -LL_DECLARE_DERIVED_UNIT(1000, Meters, Kilometers, "km"); -LL_DECLARE_DERIVED_UNIT(1.0 / 100.0, Meters, Centimeters, "cm"); -LL_DECLARE_DERIVED_UNIT(1.0 / 1000.0, Meters, Millimeters, "mm"); +LL_DECLARE_DERIVED_UNIT(Kilometers, "km", Meters, * 1000); +LL_DECLARE_DERIVED_UNIT(Centimeters, "cm", Meters, * 100); +LL_DECLARE_DERIVED_UNIT(Millimeters, "mm", Meters, * 1000); LL_DECLARE_BASE_UNIT(Hertz, "Hz"); -LL_DECLARE_DERIVED_UNIT(1000, Hertz, Kilohertz, "KHz"); -LL_DECLARE_DERIVED_UNIT(1000 * 1000, Hertz, Megahertz, "MHz"); -LL_DECLARE_DERIVED_UNIT(1000 * 1000 * 1000, Hertz, Gigahertz, "GHz"); +LL_DECLARE_DERIVED_UNIT(Kilohertz, "KHz", Hertz, * 1000); +LL_DECLARE_DERIVED_UNIT(Megahertz, "MHz", Hertz, * 1000 * 1000); +LL_DECLARE_DERIVED_UNIT(Gigahertz, "GHz", Hertz, * 1000 * 1000 * 1000); LL_DECLARE_BASE_UNIT(Radians, "rad"); -LL_DECLARE_DERIVED_UNIT(0.01745329251994, Radians, Degrees, "deg"); +LL_DECLARE_DERIVED_UNIT(Degrees, "deg", Radians, * 0.01745329251994); } // namespace LLUnits diff --git a/indra/llcommon/tests/llunits_test.cpp b/indra/llcommon/tests/llunits_test.cpp index 33e30f9688..747e8d1827 100644 --- a/indra/llcommon/tests/llunits_test.cpp +++ b/indra/llcommon/tests/llunits_test.cpp @@ -34,8 +34,8 @@ namespace LLUnits { // using powers of 2 to allow strict floating point equality LL_DECLARE_BASE_UNIT(Quatloos, "Quat"); - LL_DECLARE_DERIVED_UNIT(4, Quatloos, Latinum, "Lat"); - LL_DECLARE_DERIVED_UNIT((1.0 / 4.0), Quatloos, Solari, "Sol"); + LL_DECLARE_DERIVED_UNIT(Latinum, "Lat", Quatloos, * 4); + LL_DECLARE_DERIVED_UNIT(Solari, "Sol", Quatloos, / 4); } namespace tut @@ -53,105 +53,107 @@ namespace tut template<> template<> void units_object_t::test<1>() { - LLUnit float_quatloos; - ensure(float_quatloos.value() == 0.f); + LLUnit float_quatloos; + ensure(float_quatloos == 0.f); - LLUnit int_quatloos; - ensure(int_quatloos.value() == 0); + LLUnit int_quatloos; + ensure(int_quatloos == 0); int_quatloos = 42; - ensure(int_quatloos.value() == 42); + ensure(int_quatloos == 42); float_quatloos = int_quatloos; - ensure(float_quatloos.value() == 42.f); + ensure(float_quatloos == 42.f); int_quatloos = float_quatloos; - ensure(int_quatloos.value() == 42); + ensure(int_quatloos == 42); float_quatloos = 42.1f; - ensure(float_quatloos.value() == 42.1f); + ensure(float_quatloos == 42.1f); int_quatloos = float_quatloos; - ensure(int_quatloos.value() == 42); - LLUnit unsigned_int_quatloos(float_quatloos); - ensure(unsigned_int_quatloos.value() == 42); + ensure(int_quatloos == 42); + LLUnit unsigned_int_quatloos(float_quatloos); + ensure(unsigned_int_quatloos == 42); } // conversions to/from base unit template<> template<> void units_object_t::test<2>() { - LLUnit quatloos(1.f); - ensure(quatloos.value() == 1.f); - LLUnit latinum_bars(quatloos); - ensure(latinum_bars.value() == 1.f / 4.f); + LLUnit quatloos(1.f); + ensure(quatloos == 1.f); + LLUnit latinum_bars(quatloos); + ensure(latinum_bars == 1.f / 4.f); latinum_bars = 256; quatloos = latinum_bars; - ensure(quatloos.value() == 1024); + ensure(quatloos == 1024); - LLUnit solari(quatloos); - ensure(solari.value() == 4096); + LLUnit solari(quatloos); + ensure(solari == 4096); } // conversions across non-base units template<> template<> void units_object_t::test<3>() { - LLUnit solari = 4.f; - LLUnit latinum_bars = solari; - ensure(latinum_bars.value() == 0.25f); + LLUnit solari = 4.f; + LLUnit latinum_bars = solari; + ensure(latinum_bars == 0.25f); } // math operations template<> template<> void units_object_t::test<4>() { - LLUnit quatloos = 1.f; + LLUnit quatloos = 1.f; quatloos *= 4.f; - ensure(quatloos.value() == 4); + ensure(quatloos == 4); quatloos = quatloos * 2; - ensure(quatloos.value() == 8); + ensure(quatloos == 8); quatloos = 2.f * quatloos; - ensure(quatloos.value() == 16); + ensure(quatloos == 16); quatloos += 4.f; - ensure(quatloos.value() == 20); + ensure(quatloos == 20); quatloos += 4; - ensure(quatloos.value() == 24); + ensure(quatloos == 24); quatloos = quatloos + 4; - ensure(quatloos.value() == 28); + ensure(quatloos == 28); quatloos = 4 + quatloos; - ensure(quatloos.value() == 32); + ensure(quatloos == 32); quatloos += quatloos * 3; - ensure(quatloos.value() == 128); + ensure(quatloos == 128); quatloos -= quatloos / 4 * 3; - ensure(quatloos.value() == 32); + ensure(quatloos == 32); quatloos = quatloos - 8; - ensure(quatloos.value() == 24); + ensure(quatloos == 24); quatloos -= 4; - ensure(quatloos.value() == 20); + ensure(quatloos == 20); quatloos -= 4.f; - ensure(quatloos.value() == 16); + ensure(quatloos == 16); quatloos *= 2.f; - ensure(quatloos.value() == 32); + ensure(quatloos == 32); quatloos = quatloos * 2.f; - ensure(quatloos.value() == 64); + ensure(quatloos == 64); quatloos = 0.5f * quatloos; - ensure(quatloos.value() == 32); + ensure(quatloos == 32); quatloos /= 2.f; - ensure(quatloos.value() == 16); + ensure(quatloos == 16); quatloos = quatloos / 4; - ensure(quatloos.value() == 4); + ensure(quatloos == 4); - F32 ratio = quatloos / LLUnit(4.f); + F32 ratio = quatloos / LLUnit(4.f); + ensure(ratio == 1); + ratio = quatloos / LLUnit(16.f); ensure(ratio == 1); - quatloos += LLUnit(4.f); - ensure(quatloos.value() == 5); - quatloos -= LLUnit(1.f); - ensure(quatloos.value() == 1); + quatloos += LLUnit(4.f); + ensure(quatloos == 5); + quatloos -= LLUnit(1.f); + ensure(quatloos == 1); } // implicit units @@ -159,16 +161,16 @@ namespace tut void units_object_t::test<5>() { // 0-initialized - LLUnit quatloos(0); + LLUnit quatloos(0); // initialize implicit unit from explicit - LLUnitImplicit quatloos_implicit = quatloos + 1; - ensure(quatloos_implicit.value() == 1); + LLUnitImplicit quatloos_implicit = quatloos + 1; + ensure(quatloos_implicit == 1); // assign implicit to explicit, or perform math operations quatloos = quatloos_implicit; - ensure(quatloos.value() == 1); + ensure(quatloos == 1); quatloos += quatloos_implicit; - ensure(quatloos.value() == 2); + ensure(quatloos == 2); // math operations on implicits quatloos_implicit = 1; diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 2c3fcfcec1..cb99a651c6 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -51,9 +51,9 @@ U32 wpo2(U32 i); U32 LLImageGL::sUniqueCount = 0; U32 LLImageGL::sBindCount = 0; -LLUnit LLImageGL::sGlobalTextureMemory = 0; -LLUnit LLImageGL::sBoundTextureMemory = 0; -LLUnit LLImageGL::sCurBoundTextureMemory = 0; +LLUnit LLImageGL::sGlobalTextureMemory = 0; +LLUnit LLImageGL::sBoundTextureMemory = 0; +LLUnit LLImageGL::sCurBoundTextureMemory = 0; S32 LLImageGL::sCount = 0; LLImageGL::dead_texturelist_t LLImageGL::sDeadTextureList[LLTexUnit::TT_NONE]; U32 LLImageGL::sCurTexName = 1; diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 2b568e5e0f..227ccc90bd 100755 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -246,9 +246,9 @@ public: static F32 sLastFrameTime; // Global memory statistics - static LLUnit sGlobalTextureMemory; // Tracks main memory texmem - static LLUnit sBoundTextureMemory; // Tracks bound texmem for last completed frame - static LLUnit sCurBoundTextureMemory; // Tracks bound texmem for current frame + static LLUnit sGlobalTextureMemory; // Tracks main memory texmem + static LLUnit sBoundTextureMemory; // Tracks bound texmem for last completed frame + static LLUnit sCurBoundTextureMemory; // Tracks bound texmem for current frame static U32 sBindCount; // Tracks number of texture binds for current frame static U32 sUniqueCount; // Tracks number of unique texture binds for current frame static BOOL sGlobalUseAnisotropic; diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp index 6966df8213..d3cc2733e6 100755 --- a/indra/llui/llstatbar.cpp +++ b/indra/llui/llstatbar.cpp @@ -284,7 +284,7 @@ void LLStatBar::draw() // draw background bar. gl_rect_2d(bar_left, bar_top, bar_right, bar_bottom, LLColor4(0.f, 0.f, 0.f, 0.25f)); - if (frame_recording.getNumPeriods() == 0) + if (frame_recording.getNumRecordedPeriods() == 0) { // No data, don't draw anything... return; @@ -315,7 +315,7 @@ void LLStatBar::draw() if (mDisplayHistory && (mCountFloatp || mEventFloatp || mSampleFloatp)) { - const S32 num_values = frame_recording.getNumPeriods() - 1; + const S32 num_values = frame_recording.getNumRecordedPeriods() - 1; F32 begin = 0; F32 end = 0; S32 i; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 42bf9b657b..ef24ba21ee 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -296,7 +296,7 @@ LLPumpIO* gServicePump = NULL; U64 gFrameTime = 0; F32 gFrameTimeSeconds = 0.f; -LLUnit gFrameIntervalSeconds = 0.f; +LLUnit gFrameIntervalSeconds = 0.f; F32 gFPSClamped = 10.f; // Pretend we start at target rate. F32 gFrameDTClamped = 0.f; // Time between adjacent checks to network for packets U64 gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 2e75de445f..ad662d8ea1 100755 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -337,7 +337,7 @@ extern LLPumpIO* gServicePump; extern U64 gFrameTime; // The timestamp of the most-recently-processed frame extern F32 gFrameTimeSeconds; // Loses msec precision after ~4.5 hours... -extern LLUnit gFrameIntervalSeconds; // Elapsed time between current and previous gFrameTimeSeconds +extern LLUnit gFrameIntervalSeconds; // Elapsed time between current and previous gFrameTimeSeconds extern F32 gFPSClamped; // Frames per second, smoothed, weighted toward last frame extern F32 gFrameDTClamped; extern U64 gStartTime; diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 40526d3357..8e061ec87c 100755 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -101,21 +101,15 @@ LLFastTimerView::LLFastTimerView(const LLSD& key) mScrollIndex(0), mHoverID(NULL), mHoverBarIndex(-1), - mPrintStats(-1), - mRecording(&get_frame_recording()), - mPauseHistory(false) + mStatsIndex(-1), + mPauseHistory(false), + mRecording(512) { - mTimerBars = new std::vector[MAX_VISIBLE_HISTORY + 1]; + mTimerBarRows.resize(MAX_VISIBLE_HISTORY); } LLFastTimerView::~LLFastTimerView() { - if (mRecording != &get_frame_recording()) - { - delete mRecording; - } - mRecording = NULL; - delete [] mTimerBars; } void LLFastTimerView::onPause() @@ -130,16 +124,11 @@ void LLFastTimerView::setPauseState(bool pause_state) // reset scroll to bottom when unpausing if (!pause_state) { - if (mRecording != &get_frame_recording()) - { - delete mRecording; - } - mRecording = &get_frame_recording(); + getChild("pause_btn")->setLabel(getString("pause")); } else { - mRecording = new PeriodicRecording(get_frame_recording()); mScrollIndex = 0; getChild("pause_btn")->setLabel(getString("run")); @@ -175,7 +164,7 @@ BOOL LLFastTimerView::handleRightMouseDown(S32 x, S32 y, MASK mask) { S32 bar_idx = MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight()); bar_idx = llclamp(bar_idx, 0, MAX_VISIBLE_HISTORY); - mPrintStats = mScrollIndex + bar_idx; + mStatsIndex = mScrollIndex + bar_idx; return TRUE; } return LLFloater::handleRightMouseDown(x, y, mask); @@ -262,8 +251,8 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) if (hasMouseCapture()) { F32 lerp = llclamp(1.f - (F32) (x - mGraphRect.mLeft) / (F32) mGraphRect.getWidth(), 0.f, 1.f); - mScrollIndex = llround( lerp * (F32)(mRecording->getNumPeriods() - MAX_VISIBLE_HISTORY)); - mScrollIndex = llclamp( mScrollIndex, 0, (S32)mRecording->getNumPeriods()); + mScrollIndex = llround( lerp * (F32)(mRecording.getNumRecordedPeriods() - MAX_VISIBLE_HISTORY)); + mScrollIndex = llclamp( mScrollIndex, 0, (S32)mRecording.getNumRecordedPeriods()); return TRUE; } mHoverTimer = NULL; @@ -272,7 +261,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) if(mPauseHistory && mBarRect.pointInRect(x, y)) { mHoverBarIndex = llmin((mBarRect.mTop - y) / (mBarRect.getHeight() / (MAX_VISIBLE_HISTORY + 2)) - 1, - (S32)mRecording->getNumPeriods() - 1, + (S32)mRecording.getNumRecordedPeriods() - 1, MAX_VISIBLE_HISTORY); if (mHoverBarIndex == 0) { @@ -289,7 +278,8 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) ++it, ++i) { // is mouse over bar for this timer? - if (mTimerBars[mHoverBarIndex][i].mVisibleRect.pointInRect(x, y)) + TimerBarRow& row = mHoverBarIndex == 0 ? mAverageTimerRow : mTimerBarRows[mHoverBarIndex - 1]; + if (row.mBars[i].mVisibleRect.pointInRect(x, y - row.mBottom)) { mHoverID = (*it); if (mHoverTimer != *it) @@ -301,7 +291,8 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) mHoverTimer = (*it); } - mToolTipRect = mTimerBars[mHoverBarIndex][i].mVisibleRect; + mToolTipRect = row.mBars[i].mVisibleRect; + mToolTipRect.translate(0, row.mBottom); } if ((*it)->getCollapsed()) @@ -329,11 +320,11 @@ static std::string get_tooltip(TimeBlock& timer, S32 history_index, PeriodicReco if (history_index == 0) { // by default, show average number of call - tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)LLUnit(frame_recording.getPeriodMean(timer)).value(), (S32)frame_recording.getPeriodMean(timer.callCount())); + tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)LLUnit(frame_recording.getPeriodMean(timer)).value(), (S32)frame_recording.getPeriodMean(timer.callCount())); } else { - tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)LLUnit(frame_recording.getPrevRecording(history_index).getSum(timer)).value(), (S32)frame_recording.getPrevRecording(history_index).getSum(timer.callCount())); + tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)LLUnit(frame_recording.getPrevRecording(history_index).getSum(timer)).value(), (S32)frame_recording.getPrevRecording(history_index).getSum(timer.callCount())); } return tooltip; } @@ -348,7 +339,7 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask) LLRect screen_rect; localRectToScreen(mToolTipRect, &screen_rect); - std::string tooltip = get_tooltip(*mHoverTimer, mHoverBarIndex > 0 ? mScrollIndex + mHoverBarIndex : 0, *mRecording); + std::string tooltip = get_tooltip(*mHoverTimer, mHoverBarIndex > 0 ? mScrollIndex + mHoverBarIndex : 0, mRecording); LLToolTipMgr::instance().show(LLToolTip::Params() .message(tooltip) @@ -366,7 +357,7 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask) TimeBlock* idp = getLegendID(y); if (idp) { - LLToolTipMgr::instance().show(get_tooltip(*idp, 0, *mRecording)); + LLToolTipMgr::instance().show(get_tooltip(*idp, 0, mRecording)); return TRUE; } @@ -381,7 +372,7 @@ BOOL LLFastTimerView::handleScrollWheel(S32 x, S32 y, S32 clicks) setPauseState(true); mScrollIndex = llclamp( mScrollIndex + clicks, 0, - llmin((S32)mRecording->getNumPeriods(), (S32)mRecording->getNumPeriods() - MAX_VISIBLE_HISTORY)); + llmin((S32)mRecording.getNumRecordedPeriods(), (S32)mRecording.getNumRecordedPeriods() - MAX_VISIBLE_HISTORY)); return TRUE; } @@ -389,12 +380,19 @@ static TimeBlock FTM_RENDER_TIMER("Timers", true); static const S32 MARGIN = 10; static const S32 LEGEND_WIDTH = 220; -static std::map sTimerColors; +static std::vector sTimerColors; void LLFastTimerView::draw() { LLFastTimer t(FTM_RENDER_TIMER); + if (!mPauseHistory) + { + mRecording.appendRecording(LLTrace::get_frame_recording().getLastRecording()); + mTimerBarRows.pop_back(); + mTimerBarRows.push_front(TimerBarRow()); + } + generateUniqueColors(); // Draw the window background @@ -417,11 +415,20 @@ void LLFastTimerView::draw() printLineStats(); LLView::draw(); - mAllTimeMax = llmax(mAllTimeMax, mRecording->getLastRecording().getSum(FTM_FRAME)); + mAllTimeMax = llmax(mAllTimeMax, mRecording.getLastRecording().getSum(FTM_FRAME)); mHoverID = NULL; mHoverBarIndex = -1; } +void LLFastTimerView::onOpen(const LLSD& key) +{ + if (mRecording.getNumRecordedPeriods() == 0) + { + mRecording.appendPeriodicRecording(LLTrace::get_frame_recording()); + } +} + + void saveChart(const std::string& label, const char* suffix, LLImageRaw* scratch) { //read result back into raw image @@ -828,7 +835,7 @@ void LLFastTimerView::doAnalysisDefault(std::string baseline, std::string target LLSD current = analyzePerformanceLogDefault(target_is); target_is.close(); - //output comparision + //output comparison std::ofstream os(output.c_str()); LLSD::Real session_time = current["SessionTime"].asReal(); @@ -936,7 +943,7 @@ void LLFastTimerView::onClickCloseBtn() void LLFastTimerView::printLineStats() { // Output stats for clicked bar to log - if (mPrintStats >= 0) + if (mStatsIndex >= 0) { std::string legend_stat; bool first = true; @@ -974,16 +981,16 @@ void LLFastTimerView::printLineStats() } first = false; - LLUnit ticks; - if (mPrintStats > 0) + LLUnit ticks; + if (mStatsIndex == 0) { - ticks = mRecording->getPrevRecording(mPrintStats).getSum(*idp); + ticks = mRecording.getPeriodMean(*idp); } else { - ticks = mRecording->getPeriodMean(*idp); + ticks = mRecording.getPrevRecording(mStatsIndex).getSum(*idp); } - LLUnit ms = ticks; + LLUnit ms = ticks; timer_stat += llformat("%.1f",ms.value()); @@ -993,7 +1000,7 @@ void LLFastTimerView::printLineStats() } } llinfos << timer_stat << llendl; - mPrintStats = -1; + mStatsIndex = -1; } } @@ -1009,7 +1016,7 @@ void LLFastTimerView::drawLineGraph() LLLocalClipRect clip(mGraphRect); //normalize based on last frame's maximum - static LLUnit max_time = 0.000001; + static LLUnit max_time = 0.000001; static U32 max_calls = 0; static F32 alpha_interp = 0.f; @@ -1020,7 +1027,7 @@ void LLFastTimerView::drawLineGraph() else if (mDisplayHz) axis_label = llformat("%d Hz", (int)(1.f / max_time.value())); else - axis_label = llformat("%4.2f ms", LLUnit(max_time).value()); + axis_label = llformat("%4.2f ms", LLUnit(max_time).value()); x = mGraphRect.mRight - LLFontGL::getFontMonospace()->getWidth(axis_label)-5; y = mGraphRect.mTop - LLFontGL::getFontMonospace()->getLineHeight(); @@ -1030,10 +1037,10 @@ void LLFastTimerView::drawLineGraph() //highlight visible range { - S32 first_frame = mRecording->getNumPeriods() - mScrollIndex; + S32 first_frame = mRecording.getNumRecordedPeriods() - mScrollIndex; S32 last_frame = first_frame - MAX_VISIBLE_HISTORY; - F32 frame_delta = ((F32) (mGraphRect.getWidth()))/(mRecording->getNumPeriods()-1); + F32 frame_delta = ((F32) (mGraphRect.getWidth()))/(mRecording.getNumRecordedPeriods()-1); F32 right = (F32) mGraphRect.mLeft + frame_delta*first_frame; F32 left = (F32) mGraphRect.mLeft + frame_delta*last_frame; @@ -1055,7 +1062,7 @@ void LLFastTimerView::drawLineGraph() } } - LLUnit cur_max = 0; + LLUnit cur_max = 0; U32 cur_max_calls = 0; for(timer_tree_iterator_t it = begin_timer_tree(FTM_FRAME); it != end_timer_tree(); @@ -1070,7 +1077,7 @@ void LLFastTimerView::drawLineGraph() glLineWidth(3); } - const F32 * col = sTimerColors[idp].mV;// ft_display_table[idx].color->mV; + const F32 * col = sTimerColors[idp->getIndex()].mV;// ft_display_table[idx].color->mV; F32 alpha = 1.f; @@ -1085,12 +1092,13 @@ void LLFastTimerView::drawLineGraph() gGL.color4f(col[0], col[1], col[2], alpha); gGL.begin(LLRender::TRIANGLE_STRIP); - for (U32 j = mRecording->getNumPeriods(); + for (U32 j = mRecording.getNumRecordedPeriods(); j > 0; j--) { - LLUnit time = llmax(mRecording->getPrevRecording(j).getSum(*idp), LLUnit(0.000001)); - U32 calls = mRecording->getPrevRecording(j).getSum(idp->callCount()); + LLTrace::Recording& recording = mRecording.getPrevRecording(j); + LLUnit time = llmax(recording.getSum(*idp), LLUnit(0.000001)); + U32 calls = recording.getSum(idp->callCount()); if (alpha == 1.f) { @@ -1098,7 +1106,7 @@ void LLFastTimerView::drawLineGraph() cur_max = llmax(cur_max, time); cur_max_calls = llmax(cur_max_calls, calls); } - F32 x = mGraphRect.mRight - j * (F32)(mGraphRect.getWidth())/(mRecording->getNumPeriods()-1); + F32 x = mGraphRect.mRight - j * (F32)(mGraphRect.getWidth())/(mRecording.getNumRecordedPeriods()-1); F32 y = mDisplayHz ? mGraphRect.mBottom + (1.f / time.value()) * ((F32) mGraphRect.getHeight() / (1.f / max_time.value())) : mGraphRect.mBottom + time / max_time * (F32)mGraphRect.getHeight(); @@ -1124,7 +1132,7 @@ void LLFastTimerView::drawLineGraph() max_time = lerp(max_time.value(), cur_max.value(), LLSmoothInterpolation::getInterpolant(0.1f)); if (max_time - cur_max <= 1 || cur_max - max_time <= 1) { - max_time = llmax(LLUnit(1), LLUnit(cur_max)); + max_time = llmax(LLUnit(1), LLUnit(cur_max)); } max_calls = llround(lerp((F32)max_calls, (F32) cur_max_calls, LLSmoothInterpolation::getInterpolant(0.1f))); @@ -1183,20 +1191,20 @@ void LLFastTimerView::drawLegend( S32 y ) scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 2.f); } bar_rect.stretch(scale_offset); - gl_rect_2d(bar_rect, sTimerColors[idp]); + gl_rect_2d(bar_rect, sTimerColors[idp->getIndex()]); - LLUnit ms = 0; + LLUnit ms = 0; S32 calls = 0; if (mHoverBarIndex > 0 && mHoverID) { S32 hidx = mScrollIndex + mHoverBarIndex; - ms = mRecording->getPrevRecording(hidx).getSum(*idp); - calls = mRecording->getPrevRecording(hidx).getSum(idp->callCount()); + ms = mRecording.getPrevRecording(hidx).getSum(*idp); + calls = mRecording.getPrevRecording(hidx).getSum(idp->callCount()); } else { - ms = LLUnit(mRecording->getPeriodMean(*idp)); - calls = (S32)mRecording->getPeriodMean(idp->callCount()); + ms = LLUnit(mRecording.getPeriodMean(*idp)); + calls = (S32)mRecording.getPeriodMean(idp->callCount()); } std::string timer_label; @@ -1254,7 +1262,8 @@ void LLFastTimerView::generateUniqueColors() { // generate unique colors { - sTimerColors[&FTM_FRAME] = LLColor4::grey; + sTimerColors.reserve(LLTrace::TimeBlock::getNumIndices()); + sTimerColors[FTM_FRAME.getIndex()] = LLColor4::grey; F32 hue = 0.f; @@ -1274,7 +1283,7 @@ void LLFastTimerView::generateUniqueColors() LLColor4 child_color; child_color.setHSL(hue, saturation, lightness); - sTimerColors[idp] = child_color; + sTimerColors[idp->getIndex()] = child_color; } } } @@ -1315,7 +1324,7 @@ void LLFastTimerView::drawTicks() { // Draw MS ticks { - LLUnit ms = mTotalTimeDisplay; + LLUnit ms = mTotalTimeDisplay; std::string tick_label; S32 x; S32 barw = mBarRect.getWidth(); @@ -1382,127 +1391,127 @@ void LLFastTimerView::updateTotalTime() switch(mDisplayMode) { case 0: - mTotalTimeDisplay = mRecording->getPeriodMean(FTM_FRAME)*2; + mTotalTimeDisplay = mRecording.getPeriodMean(FTM_FRAME)*2; break; case 1: mTotalTimeDisplay = mAllTimeMax; break; case 2: // Calculate the max total ticks for the current history - mTotalTimeDisplay = mRecording->getPeriodMax(FTM_FRAME); + mTotalTimeDisplay = mRecording.getPeriodMax(FTM_FRAME); break; default: - mTotalTimeDisplay = LLUnit(100); + mTotalTimeDisplay = LLUnit(100); break; } - mTotalTimeDisplay = LLUnit(llceil(mTotalTimeDisplay.as().value() / 20.f) * 20.f); + mTotalTimeDisplay = LLUnit(llceil(mTotalTimeDisplay.as().value() / 20.f) * 20.f); } void LLFastTimerView::drawBars() { - updateTotalTime(); - if (mTotalTimeDisplay <= 0.0) return; - LLLocalClipRect clip(mBarRect); S32 bar_height = mBarRect.getHeight() / (MAX_VISIBLE_HISTORY + 2); - S32 vpad = llmax(1, bar_height / 4); // spacing between bars + const S32 vpad = llmax(1, bar_height / 4); // spacing between bars bar_height -= vpad; + updateTotalTime(); + if (mTotalTimeDisplay <= 0.0) return; + drawTicks(); - S32 y = mBarRect.mTop - ((S32)LLFontGL::getFontMonospace()->getLineHeight() + 4); - drawBorders(y, mBarRect.mLeft, bar_height, vpad); + const S32 bars_top = mBarRect.mTop - ((S32)LLFontGL::getFontMonospace()->getLineHeight() + 4); + drawBorders(bars_top, mBarRect.mLeft, bar_height, vpad); // Draw bars for each history entry - // Special: -1 = show running average + // Special: 0 = show running average LLPointer bar_image = LLUI::getUIImage("Rounded_Square"); + + const S32 image_width = bar_image->getTextureWidth(); + const S32 image_height = bar_image->getTextureHeight(); + gGL.getTexUnit(0)->bind(bar_image->getImage()); - const S32 histmax = llmin((S32)mRecording->getNumPeriods(), MAX_VISIBLE_HISTORY) + 1; + { + const S32 histmax = llmin((S32)mRecording.getNumRecordedPeriods(), MAX_VISIBLE_HISTORY); - for (S32 bar_index = 0; bar_index < histmax && y > LINE_GRAPH_HEIGHT; bar_index++) - { - S32 history_index = (bar_index > 0) - ? bar_index + mScrollIndex - : -1; - mTimerBars[bar_index].clear(); - mTimerBars[bar_index].reserve(LLInstanceTracker::instanceCount()); - - updateTimerBarWidths(&FTM_FRAME, mTimerBars[bar_index], history_index, true); - LLRect frame_bar_rect(mBarRect.mLeft, y, mBarRect.mLeft + mTimerBars[bar_index][0].mWidth, y-bar_height); - mTimerBars[bar_index][0].mVisibleRect = frame_bar_rect; - updateTimerBarFractions(&FTM_FRAME, 0, mTimerBars[bar_index]); - drawBar(&FTM_FRAME, frame_bar_rect, mTimerBars[bar_index], 0, bar_image); - - y -= (bar_height + vpad); - if (bar_index == 0) - y -= bar_height; - } + llassert(mTimerBarRows.size() >= histmax); + + // update widths + updateTimerBarWidths(&FTM_FRAME, mAverageTimerRow, -1); + mAverageTimerRow.mBars[0].mVisibleRect = LLRect(mBarRect.mLeft, 0, mBarRect.mLeft + mAverageTimerRow.mBars[0].mWidth, -bar_height); + updateTimerBarFractions(&FTM_FRAME, mAverageTimerRow); + + for (S32 history_index = 0; history_index < histmax; history_index++) + { + TimerBarRow& row = mTimerBarRows[history_index]; + if (row.mBars.empty()) + { + row.mBars.reserve(LLInstanceTracker::instanceCount()); + updateTimerBarWidths(&FTM_FRAME, row, history_index); + row.mBars[0].mVisibleRect = LLRect(mBarRect.mLeft, 0, mBarRect.mLeft + row.mBars[0].mWidth, -1); + updateTimerBarFractions(&FTM_FRAME, row); + } + } + + // draw bars + LLRect frame_bar_rect( mBarRect.mLeft, + bars_top, + mBarRect.mLeft + mAverageTimerRow.mBars[0].mWidth, + bars_top - bar_height); + mAverageTimerRow.mBottom = frame_bar_rect.mBottom; + drawBar(&FTM_FRAME, frame_bar_rect, mAverageTimerRow, image_width, image_height, false); + frame_bar_rect.translate(0, -(bar_height + vpad + bar_height)); + + for(S32 bar_index = mScrollIndex; bar_index < llmin(histmax, mScrollIndex + MAX_VISIBLE_HISTORY); ++bar_index) + { + TimerBarRow& row = mTimerBarRows[bar_index]; + row.mBottom = frame_bar_rect.mBottom; + drawBar(&FTM_FRAME, frame_bar_rect, row, image_width, image_height, false); + + frame_bar_rect.translate(0, -(bar_height + vpad)); + } + + } gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } static LLFastTimer::DeclareTimer FTM_UPDATE_TIMER_BAR_WIDTHS("Update timer bar widths"); -S32 LLFastTimerView::updateTimerBarWidths(LLTrace::TimeBlock* time_block, std::vector& bars, S32 history_index, bool visible) +S32 LLFastTimerView::updateTimerBarWidths(LLTrace::TimeBlock* time_block, TimerBarRow& row, S32 history_index, bool visible) { + std::vector& bars = row.mBars; LLFastTimer _(FTM_UPDATE_TIMER_BAR_WIDTHS); - F32 self_time_frame_fraction = history_index == -1 - ? (mRecording->getPeriodMean(time_block->selfTime()) / mTotalTimeDisplay) - : (mRecording->getPrevRecording(history_index).getSum(time_block->selfTime()) / mTotalTimeDisplay); + const F32 self_time_frame_fraction = history_index == -1 + ? (mRecording.getPeriodMean(time_block->selfTime()) / mTotalTimeDisplay) + : (mRecording.getPrevRecording(history_index).getSum(time_block->selfTime()) / mTotalTimeDisplay); - S32 self_time_width = llround(self_time_frame_fraction * (F32)mBarRect.getWidth()); + const S32 self_time_width = llround(self_time_frame_fraction * (F32)mBarRect.getWidth()); S32 full_width = self_time_width; - bool children_visible = visible; - // reserve a spot for this bar to be rendered before its children // even though we don't know its size yet - S32 bar_rect_index = bars.size(); - if (visible) - { - bars.push_back(TimerBar()); - } + bars.push_back(TimerBar()); + TimerBar& timer_bar = bars.back(); - if (time_block->getCollapsed()) - { - children_visible = false; - } + const bool children_visible = visible && !time_block->getCollapsed(); for (TimeBlock::child_iter it = time_block->beginChildren(), end_it = time_block->endChildren(); it != end_it; ++it) { - full_width += updateTimerBarWidths(*it, bars, history_index, children_visible); + full_width += updateTimerBarWidths(*it, row, history_index, children_visible); } - if (visible) - { - TimerBar& timer_bar = bars[bar_rect_index]; - - timer_bar.mWidth = full_width; - timer_bar.mSelfWidth = self_time_width; - timer_bar.mColor = sTimerColors[time_block]; - - BOOL is_child_of_hover_item = (time_block == mHoverID); - TimeBlock* next_parent = time_block->getParent(); - while(!is_child_of_hover_item && next_parent) - { - is_child_of_hover_item = (mHoverID == next_parent); - if (next_parent->getParent() == next_parent) break; - next_parent = next_parent->getParent(); - } - - if (mHoverID != NULL - && time_block != mHoverID - && !is_child_of_hover_item) - { - timer_bar.mColor = lerp(timer_bar.mColor, LLColor4::grey, 0.8f); - } - } + timer_bar.mWidth = full_width; + timer_bar.mSelfWidth = self_time_width; + timer_bar.mTimeBlock = time_block; + timer_bar.mVisible = visible; + return full_width; } static LLFastTimer::DeclareTimer FTM_UPDATE_TIMER_BAR_FRACTIONS("Update timer bar fractions"); -S32 LLFastTimerView::updateTimerBarFractions(LLTrace::TimeBlock* time_block, S32 timer_bar_index, std::vector& bars) +S32 LLFastTimerView::updateTimerBarFractions(LLTrace::TimeBlock* time_block, TimerBarRow& row, S32 timer_bar_index) { + std::vector& bars = row.mBars; LLFastTimer _(FTM_UPDATE_TIMER_BAR_FRACTIONS); TimerBar& timer_bar = bars[timer_bar_index]; S32 child_time_width = timer_bar.mWidth - timer_bar.mSelfWidth; @@ -1518,11 +1527,6 @@ S32 LLFastTimerView::updateTimerBarFractions(LLTrace::TimeBlock* time_block, S32 } children_rect.mRight = children_rect.mLeft + timer_bar.mWidth - timer_bar.mSelfWidth; - if (children_rect.getHeight() > MIN_BAR_HEIGHT) - { - children_rect.mTop -= 1; - children_rect.mBottom += 1; - } timer_bar.mChildrenRect = children_rect; //now loop through children and figure out portion of bar image covered by each bar, now that we know the @@ -1548,7 +1552,7 @@ S32 LLFastTimerView::updateTimerBarFractions(LLTrace::TimeBlock* time_block, S32 children_rect.mLeft + llround(child_timer_bar.mEndFraction * children_rect.getWidth()), children_rect.mBottom); - timer_bar_index = updateTimerBarFractions(child_time_block, timer_bar_index, bars); + timer_bar_index = updateTimerBarFractions(child_time_block, row, timer_bar_index); bar_fraction_start = child_timer_bar.mEndFraction; } @@ -1556,25 +1560,29 @@ S32 LLFastTimerView::updateTimerBarFractions(LLTrace::TimeBlock* time_block, S32 return timer_bar_index; } -S32 LLFastTimerView::drawBar(LLTrace::TimeBlock* time_block, LLRect bar_rect, std::vector& bars, S32 bar_index, LLPointer& bar_image) +S32 LLFastTimerView::drawBar(LLTrace::TimeBlock* time_block, LLRect bar_rect, TimerBarRow& row, S32 image_width, S32 image_height, bool hovered, S32 bar_index) { - TimerBar& timer_bar = bars[bar_index]; + TimerBar& timer_bar = row.mBars[bar_index]; + + hovered |= mHoverID == time_block; // animate scale of bar when hovering over that particular timer if (bar_rect.getWidth() > 0) { LLRect render_rect(bar_rect); S32 scale_offset = 0; - if (time_block == mHoverID) + if (mHoverID == time_block) { scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 3.f); render_rect.mTop += scale_offset; render_rect.mBottom -= scale_offset; } - gGL.color4fv(timer_bar.mColor.mV); + LLColor4 color = sTimerColors[time_block->getIndex()]; + if (!hovered) color = lerp(color, LLColor4::grey, 0.8f); + gGL.color4fv(color.mV); gl_segmented_rect_2d_fragment_tex(render_rect, - bar_image->getTextureWidth(), bar_image->getTextureHeight(), + image_width, image_height, 16, timer_bar.mStartFraction, timer_bar.mEndFraction); } @@ -1584,7 +1592,20 @@ S32 LLFastTimerView::drawBar(LLTrace::TimeBlock* time_block, LLRect bar_rect, st for (TimeBlock::child_iter it = time_block->beginChildren(), end_it = time_block->endChildren(); it != end_it; ++it) { ++bar_index; - bar_index = drawBar(*it, timer_bar.mChildrenRect, bars, bar_index, bar_image); + LLRect children_rect = timer_bar.mChildrenRect; + children_rect.translate(0, row.mBottom); + if (bar_rect.getHeight() > MIN_BAR_HEIGHT) + { + // shrink as we go down a level + children_rect.mTop = bar_rect.mTop - 1; + children_rect.mBottom = bar_rect.mBottom + 1; + } + else + { + children_rect.mTop = bar_rect.mTop; + children_rect.mBottom = bar_rect.mBottom; + } + bar_index = drawBar(*it, children_rect, row, image_width, image_height, hovered, bar_index); } } diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h index 341adacd65..c20cadd6d7 100755 --- a/indra/newview/llfasttimerview.h +++ b/indra/newview/llfasttimerview.h @@ -31,6 +31,7 @@ #include "llfasttimer.h" #include "llunit.h" #include "lltracerecording.h" +#include class LLFastTimerView : public LLFloater { @@ -60,13 +61,11 @@ public: virtual BOOL handleToolTip(S32 x, S32 y, MASK mask); virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); virtual void draw(); - + virtual void onOpen(const LLSD& key); LLTrace::TimeBlock* getLegendID(S32 y); -protected: - virtual void onClickCloseBtn(); - private: + virtual void onClickCloseBtn(); void drawTicks(); void drawLineGraph(); void drawLegend(S32 y); @@ -87,47 +86,53 @@ private: mStartFraction(0.f), mEndFraction(1.f) {} - S32 mWidth; - S32 mSelfWidth; - LLRect mVisibleRect, - mChildrenRect; - LLColor4 mColor; - bool mVisible; - F32 mStartFraction, - mEndFraction; + S32 mWidth; + S32 mSelfWidth; + LLRect mVisibleRect, + mChildrenRect; + LLTrace::TimeBlock* mTimeBlock; + bool mVisible; + F32 mStartFraction, + mEndFraction; }; - S32 updateTimerBarWidths(LLTrace::TimeBlock* time_block, std::vector& bars, S32 history_index, bool visible); - S32 updateTimerBarFractions(LLTrace::TimeBlock* time_block, S32 timer_bar_index, std::vector& bars); - S32 drawBar(LLTrace::TimeBlock* time_block, LLRect bar_rect, std::vector& bars, S32 bar_index, LLPointer& bar_image); + + struct TimerBarRow + { + S32 mBottom; + std::vector mBars; + }; + + S32 updateTimerBarWidths(LLTrace::TimeBlock* time_block, TimerBarRow& row, S32 history_index, bool visible = true); + S32 updateTimerBarFractions(LLTrace::TimeBlock* time_block, TimerBarRow& row, S32 timer_bar_index = 0); + S32 drawBar(LLTrace::TimeBlock* time_block, LLRect bar_rect, TimerBarRow& row, S32 image_width, S32 image_height, bool hovered, S32 bar_index = 0); void setPauseState(bool pause_state); - std::vector* mTimerBars; - S32 mDisplayMode; + std::deque mTimerBarRows; + TimerBarRow mAverageTimerRow; - typedef enum child_alignment + enum ChildAlignment { ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT, ALIGN_COUNT - } ChildAlignment; - - ChildAlignment mDisplayCenter; - bool mDisplayCalls, - mDisplayHz; - LLUnit mAllTimeMax, - mTotalTimeDisplay; - LLRect mBarRect; - S32 mScrollIndex; - LLTrace::TimeBlock* mHoverID; - LLTrace::TimeBlock* mHoverTimer; - LLRect mToolTipRect; - S32 mHoverBarIndex; - LLFrameTimer mHighlightTimer; - S32 mPrintStats; - LLRect mGraphRect; - LLTrace::PeriodicRecording* mRecording; - bool mPauseHistory; + } mDisplayCenter; + bool mDisplayCalls, + mDisplayHz, + mPauseHistory; + LLUnit mAllTimeMax, + mTotalTimeDisplay; + S32 mScrollIndex, + mHoverBarIndex, + mStatsIndex; + S32 mDisplayMode; + LLTrace::TimeBlock* mHoverID; + LLTrace::TimeBlock* mHoverTimer; + LLRect mToolTipRect, + mGraphRect, + mBarRect; + LLFrameTimer mHighlightTimer; + LLTrace::PeriodicRecording mRecording; }; #endif diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp index dccf8a2a17..3d9e0ab4c3 100644 --- a/indra/newview/llscenemonitor.cpp +++ b/indra/newview/llscenemonitor.cpp @@ -503,9 +503,9 @@ void LLSceneMonitor::dumpToFile(std::string file_name) os << std::setprecision(3); PeriodicRecording& scene_load_recording = mSceneLoadRecording.getAcceptedRecording(); - const U32 frame_count = scene_load_recording.getNumPeriods(); + const U32 frame_count = scene_load_recording.getNumRecordedPeriods(); - LLUnit frame_time; + LLUnit frame_time; os << "Stat"; for (S32 frame = 0; frame < frame_count; frame++) diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 2530beb722..7fc58e230c 100755 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -330,7 +330,7 @@ private: LLTextureInfo mTextureInfo; // XXX possible delete - LLUnit mHTTPTextureBits; // Mfnq + LLUnit mHTTPTextureBits; // Mfnq // XXX possible delete //debug use diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index c9ec5d9bf6..766b66efa0 100755 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -507,17 +507,17 @@ private: void LLGLTexMemBar::draw() { - LLUnit bound_mem = LLViewerTexture::sBoundTextureMemory; - LLUnit max_bound_mem = LLViewerTexture::sMaxBoundTextureMem; - LLUnit total_mem = LLViewerTexture::sTotalTextureMemory; - LLUnit max_total_mem = LLViewerTexture::sMaxTotalTextureMem; + LLUnit bound_mem = LLViewerTexture::sBoundTextureMemory; + LLUnit max_bound_mem = LLViewerTexture::sMaxBoundTextureMem; + LLUnit total_mem = LLViewerTexture::sTotalTextureMemory; + LLUnit max_total_mem = LLViewerTexture::sMaxTotalTextureMem; F32 discard_bias = LLViewerTexture::sDesiredDiscardBias; F32 cache_usage = (F32)LLTrace::Mibibytes(LLAppViewer::getTextureCache()->getUsage()).value() ; F32 cache_max_usage = (F32)LLTrace::Mibibytes(LLAppViewer::getTextureCache()->getMaxUsage()).value() ; S32 line_height = LLFontGL::getFontMonospace()->getLineHeight(); S32 v_offset = 0;//(S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f); - LLUnit total_texture_downloaded = gTotalTextureData; - LLUnit total_object_downloaded = gTotalObjectData; + LLUnit total_texture_downloaded = gTotalTextureData; + LLUnit total_object_downloaded = gTotalObjectData; U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests() ; U32 total_active_cached_objects = LLWorld::getInstance()->getNumOfActiveCachedObjects(); U32 total_objects = gObjectList.getNumObjects(); diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp index 3a6ee636d4..dc4c9fe4ad 100755 --- a/indra/newview/llviewerassetstats.cpp +++ b/indra/newview/llviewerassetstats.cpp @@ -486,10 +486,10 @@ void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output) grid_from_region_handle(it->first, &grid_x, &grid_y); r.grid_x(grid_x); r.grid_y(grid_y); - r.duration(LLUnit(rec.getDuration()).value()); + r.duration(LLUnit(rec.getDuration()).value()); } - stats.duration(mCurRecording ? LLUnit(mCurRecording->getDuration()).value() : 0.0); + stats.duration(mCurRecording ? LLUnit(mCurRecording->getDuration()).value() : 0.0); } LLSD LLViewerAssetStats::asLLSD(bool compact_output) diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h index 1a8770f8a7..e03b7c53a6 100755 --- a/indra/newview/llviewerassetstats.h +++ b/indra/newview/llviewerassetstats.h @@ -83,7 +83,7 @@ public: * for compatibility with the pre-existing timestamp on the texture * fetcher class, LLTextureFetch. */ - typedef LLUnit duration_t; + typedef LLUnit duration_t; /** * Type for the region identifier used in stats. Currently uses diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index f2a3ffc3dc..0309acdad2 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -4480,18 +4480,18 @@ void send_agent_update(BOOL force_send, BOOL send_reliable) // *TODO: Remove this dependency, or figure out a better way to handle // this hack. -extern LLUnit gObjectData; +extern LLUnit gObjectData; void process_object_update(LLMessageSystem *mesgsys, void **user_data) { // Update the data counters if (mesgsys->getReceiveCompressedSize()) { - gObjectData += (LLUnit)mesgsys->getReceiveCompressedSize(); + gObjectData += (LLUnit)mesgsys->getReceiveCompressedSize(); } else { - gObjectData += (LLUnit)mesgsys->getReceiveSize(); + gObjectData += (LLUnit)mesgsys->getReceiveSize(); } // Update the object... @@ -4503,11 +4503,11 @@ void process_compressed_object_update(LLMessageSystem *mesgsys, void **user_data // Update the data counters if (mesgsys->getReceiveCompressedSize()) { - gObjectData += (LLUnit)mesgsys->getReceiveCompressedSize(); + gObjectData += (LLUnit)mesgsys->getReceiveCompressedSize(); } else { - gObjectData += (LLUnit)mesgsys->getReceiveSize(); + gObjectData += (LLUnit)mesgsys->getReceiveSize(); } // Update the object... @@ -4519,11 +4519,11 @@ void process_cached_object_update(LLMessageSystem *mesgsys, void **user_data) // Update the data counters if (mesgsys->getReceiveCompressedSize()) { - gObjectData += (LLUnit)mesgsys->getReceiveCompressedSize(); + gObjectData += (LLUnit)mesgsys->getReceiveCompressedSize(); } else { - gObjectData += (LLUnit)mesgsys->getReceiveSize(); + gObjectData += (LLUnit)mesgsys->getReceiveSize(); } // Update the object... @@ -4535,11 +4535,11 @@ void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_ { if (mesgsys->getReceiveCompressedSize()) { - gObjectData += (LLUnit)mesgsys->getReceiveCompressedSize(); + gObjectData += (LLUnit)mesgsys->getReceiveCompressedSize(); } else { - gObjectData += (LLUnit)mesgsys->getReceiveSize(); + gObjectData += (LLUnit)mesgsys->getReceiveSize(); } gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_TERSE_IMPROVED); diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index be477f7f9a..7ddee48b38 100755 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -290,13 +290,13 @@ F32 gAveLandCompression = 0.f, gWorstLandCompression = 0.f, gWorstWaterCompression = 0.f; -LLUnit gTotalWorldData = 0, +LLUnit gTotalWorldData = 0, gTotalObjectData = 0, gTotalTextureData = 0; U32 gSimPingCount = 0; -LLUnit gObjectData = 0; +LLUnit gObjectData = 0; F32 gAvgSimPing = 0.f; -LLUnit gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGORY] = {0}; +LLUnit gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGORY] = {0}; extern U32 gVisCompared; extern U32 gVisTested; @@ -334,8 +334,8 @@ void update_statistics() typedef LLInstanceTracker, std::string> trace_type_t; - LLUnit idle_secs = last_frame_recording.getSum(*trace_type_t::getInstance("Idle")); - LLUnit network_secs = last_frame_recording.getSum(*trace_type_t::getInstance("Network")); + LLUnit idle_secs = last_frame_recording.getSum(*trace_type_t::getInstance("Idle")); + LLUnit network_secs = last_frame_recording.getSum(*trace_type_t::getInstance("Network")); record(LLStatViewer::FRAME_STACKTIME, last_frame_recording.getSum(*trace_type_t::getInstance("Frame"))); record(LLStatViewer::UPDATE_STACKTIME, idle_secs - network_secs); diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index bfba7bca9a..4e48a61264 100755 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -331,7 +331,7 @@ void update_statistics(); void send_stats(); extern LLFrameTimer gTextureTimer; -extern LLUnit gTotalTextureData; -extern LLUnit gTotalObjectData; -extern LLUnit gTotalTextureBytesPerBoostLevel[] ; +extern LLUnit gTotalTextureData; +extern LLUnit gTotalObjectData; +extern LLUnit gTotalTextureBytesPerBoostLevel[] ; #endif // LL_LLVIEWERSTATS_H diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index e0a88bfad6..f468df0674 100755 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -66,8 +66,8 @@ /////////////////////////////////////////////////////////////////////////////// // extern -const LLUnit gMinVideoRam = 32; -const LLUnit gMaxVideoRam = 512; +const LLUnit gMinVideoRam = 32; +const LLUnit gMaxVideoRam = 512; // statics @@ -88,11 +88,11 @@ S32 LLViewerTexture::sAuxCount = 0; LLFrameTimer LLViewerTexture::sEvaluationTimer; F32 LLViewerTexture::sDesiredDiscardBias = 0.f; F32 LLViewerTexture::sDesiredDiscardScale = 1.1f; -LLUnit LLViewerTexture::sBoundTextureMemory = 0; -LLUnit LLViewerTexture::sTotalTextureMemory = 0; -LLUnit LLViewerTexture::sMaxBoundTextureMem = 0; -LLUnit LLViewerTexture::sMaxTotalTextureMem = 0; -LLUnit LLViewerTexture::sMaxDesiredTextureMem = 0 ; +LLUnit LLViewerTexture::sBoundTextureMemory = 0; +LLUnit LLViewerTexture::sTotalTextureMemory = 0; +LLUnit LLViewerTexture::sMaxBoundTextureMem = 0; +LLUnit LLViewerTexture::sMaxTotalTextureMem = 0; +LLUnit LLViewerTexture::sMaxDesiredTextureMem = 0 ; S8 LLViewerTexture::sCameraMovingDiscardBias = 0 ; F32 LLViewerTexture::sCameraMovingBias = 0.0f ; S32 LLViewerTexture::sMaxSculptRez = 128 ; //max sculpt image size @@ -542,7 +542,7 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity sTotalTextureMemory >= sMaxTotalTextureMem) { //when texture memory overflows, lower down the threshold to release the textures more aggressively. - sMaxDesiredTextureMem = llmin(sMaxDesiredTextureMem * 0.75f, LLUnit(gMaxVideoRam)); + sMaxDesiredTextureMem = llmin(sMaxDesiredTextureMem * 0.75f, LLUnit(gMaxVideoRam)); // If we are using more texture memory than we should, // scale up the desired discard level diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index e939731cf2..529b812f41 100755 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -39,8 +39,8 @@ #include #include -extern const LLUnit gMinVideoRam; -extern const LLUnit gMaxVideoRam; +extern const LLUnit gMinVideoRam; +extern const LLUnit gMaxVideoRam; class LLFace; class LLImageGL ; @@ -205,11 +205,11 @@ public: static LLFrameTimer sEvaluationTimer; static F32 sDesiredDiscardBias; static F32 sDesiredDiscardScale; - static LLUnit sBoundTextureMemory; - static LLUnit sTotalTextureMemory; - static LLUnit sMaxBoundTextureMem; - static LLUnit sMaxTotalTextureMem; - static LLUnit sMaxDesiredTextureMem ; + static LLUnit sBoundTextureMemory; + static LLUnit sTotalTextureMemory; + static LLUnit sMaxBoundTextureMem; + static LLUnit sMaxTotalTextureMem; + static LLUnit sMaxDesiredTextureMem ; static S8 sCameraMovingDiscardBias; static F32 sCameraMovingBias; static S32 sMaxSculptRez ; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 349849a267..97f7baa98d 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -738,7 +738,7 @@ public: { if(gTotalTextureBytesPerBoostLevel[i] > 0) { - addText(xpos, ypos, llformat("Boost_Level %d: %.3f MB", i, LLUnit(gTotalTextureBytesPerBoostLevel[i]).value())); + addText(xpos, ypos, llformat("Boost_Level %d: %.3f MB", i, LLUnit(gTotalTextureBytesPerBoostLevel[i]).value())); ypos += y_inc; } } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index dd5c153d55..7cf30e1661 100755 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2792,7 +2792,7 @@ void LLPipeline::updateGeom(F32 max_dtime) S32 count = 0; - max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, LLUnitImplicit(max_dtime)); + max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, LLUnitImplicit(max_dtime)); LLSpatialGroup* last_group = NULL; LLSpatialBridge* last_bridge = NULL; -- cgit v1.3