Skip to content

Commit 21bd9ab

Browse files
committed
perf: optimize model panel MDL interactions
cache the CStudioHdr, it's expensive to init and CBaseAnimating stores this so replicate that behavior
1 parent 4cc7391 commit 21bd9ab

File tree

6 files changed

+115
-81
lines changed

6 files changed

+115
-81
lines changed

src/game/client/game_controls/basemodel_panel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ class CBaseModelPanel : public CMDLPanel
181181
virtual void OnMouseWheeled( int delta );
182182

183183
studiohdr_t* GetStudioHdr( void ) { return m_RootMDL.m_MDL.GetStudioHdr(); }
184+
CStudioHdr* GetStudioHdrFull( void ) { return m_RootMDL.m_pStudioHdr; }
184185
void SetBody( unsigned int nBody ) { m_RootMDL.m_MDL.m_nBody = nBody; }
185186

186187
void RotateYaw( float flDelta );

src/game/client/tf/vgui/modelimagepanel.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,9 @@ void CModelImagePanel::Paint()
148148

149149
// copy the rendered weapon skin from the render target
150150
Assert( m_pCachedIcon == NULL );
151-
CStudioHdr studioHdr( g_pMDLCache->GetStudioHdr( m_RootMDL.m_MDL.GetMDL() ), g_pMDLCache );
151+
CStudioHdr* studioHdr = m_RootMDL.m_pStudioHdr;
152152
char buffer[_MAX_PATH];
153-
CUtlString strMDLName = V_GetFileName( studioHdr.pszName() );
153+
CUtlString strMDLName = V_GetFileName( studioHdr->pszName() );
154154
V_sprintf_safe( buffer, "proc/icon/mdl_%s_body%d_skin%d_w%d_h%d", strMDLName.StripExtension().Get(), m_RootMDL.m_MDL.m_nBody, m_RootMDL.m_MDL.m_nSkin, GetWide(), GetTall() );
155155
SafeAssign( &m_pCachedIcon, new CIconRenderReceiver() );
156156

src/game/client/tf/vgui/tf_playermodelpanel.cpp

Lines changed: 48 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -643,8 +643,8 @@ void CTFPlayerModelPanel::SwitchHeldItemTo( CEconItemView *pItem )
643643
{
644644
ClearScene();
645645

646-
CStudioHdr studioHdr( GetStudioHdr(), g_pMDLCache );
647-
int iSequence = LookupSequence( &studioHdr, pSequence );
646+
CStudioHdr *studioHdr = m_RootMDL.m_pStudioHdr;
647+
int iSequence = LookupSequence( studioHdr, pSequence );
648648
if ( iSequence >= 0 )
649649
{
650650
// does a weapon need to be equipped?
@@ -784,19 +784,19 @@ void CTFPlayerModelPanel::UpdateWeaponBodygroups( bool bModifyDeployedOnlyBodygr
784784
void CTFPlayerModelPanel::UpdateHiddenBodyGroups( CEconItemView* pItem )
785785
{
786786
MDLCACHE_CRITICAL_SECTION();
787-
CStudioHdr studioHdr( GetStudioHdr(), g_pMDLCache );
787+
CStudioHdr* studioHdr = m_RootMDL.m_pStudioHdr;
788788

789789
int iNumBodyGroups = pItem->GetStaticData()->GetNumModifiedBodyGroups( 0 );
790790
for ( int i=0; i<iNumBodyGroups; ++i )
791791
{
792792
int iState = 0;
793793
const char *pszBodyGroup = pItem->GetStaticData()->GetModifiedBodyGroup( 0, i, iState );
794-
int iBodyGroup = FindBodygroupByName( &studioHdr, pszBodyGroup );
794+
int iBodyGroup = FindBodygroupByName( studioHdr, pszBodyGroup );
795795

796796
if ( iBodyGroup == -1 )
797797
continue;
798798

799-
::SetBodygroup( &studioHdr, m_nBody, iBodyGroup, iState );
799+
::SetBodygroup( studioHdr, m_nBody, iBodyGroup, iState );
800800
SetBody( m_nBody );
801801
}
802802

@@ -807,12 +807,12 @@ void CTFPlayerModelPanel::UpdateHiddenBodyGroups( CEconItemView* pItem )
807807
{
808808
FOR_EACH_VEC( pStyle->GetAdditionalHideBodygroups(), i )
809809
{
810-
int iBodyGroup = FindBodygroupByName( &studioHdr, pStyle->GetAdditionalHideBodygroups()[i] );
810+
int iBodyGroup = FindBodygroupByName( studioHdr, pStyle->GetAdditionalHideBodygroups()[i] );
811811

812812
if ( iBodyGroup == -1 )
813813
continue;
814814

815-
::SetBodygroup( &studioHdr, m_nBody, iBodyGroup, 1 ); // force state to '1' here to mean hidden
815+
::SetBodygroup( studioHdr, m_nBody, iBodyGroup, 1 ); // force state to '1' here to mean hidden
816816
SetBody( m_nBody );
817817
}
818818
}
@@ -822,7 +822,7 @@ void CTFPlayerModelPanel::UpdateHiddenBodyGroups( CEconItemView* pItem )
822822
int iBodyStateOverride = pItem->GetStaticData()->GetWorldmodelBodygroupStateOverride( m_iTeam );
823823
if ( iBodyOverride > -1 && iBodyStateOverride > -1 )
824824
{
825-
::SetBodygroup( &studioHdr, m_nBody, iBodyOverride, iBodyStateOverride );
825+
::SetBodygroup( studioHdr, m_nBody, iBodyOverride, iBodyStateOverride );
826826
}
827827
}
828828

@@ -855,18 +855,18 @@ void CTFPlayerModelPanel::EquipAllWearables( CEconItemView *pHeldItem )
855855
{
856856
// First, reset all our bodygroups
857857
MDLCACHE_CRITICAL_SECTION();
858-
CStudioHdr studioHdr( GetStudioHdr(), g_pMDLCache );
858+
CStudioHdr* studioHdr = m_RootMDL.m_pStudioHdr;
859859

860860
const CEconItemSchema::BodygroupStateMap_t& mapBodygroupState = GetItemSchema()->GetDefaultBodygroupStateMap();
861861

862862
FOR_EACH_MAP_FAST( mapBodygroupState, i )
863863
{
864864
const char *pszBodygroupName = mapBodygroupState.Key(i);
865-
int iBodyGroup = FindBodygroupByName( &studioHdr, pszBodygroupName );
865+
int iBodyGroup = FindBodygroupByName( studioHdr, pszBodygroupName );
866866
if ( iBodyGroup > -1 )
867867
{
868868
int iState = mapBodygroupState[i];
869-
::SetBodygroup( &studioHdr, m_nBody, iBodyGroup, iState );
869+
::SetBodygroup( studioHdr, m_nBody, iBodyGroup, iState );
870870
}
871871
}
872872

@@ -1139,8 +1139,8 @@ void CTFPlayerModelPanel::OnModelLoadComplete( const model_t *pModel )
11391139
{
11401140
// Classes start at 1, bodygroups at 0, so we shift them all back 1.
11411141
MDLCACHE_CRITICAL_SECTION();
1142-
CStudioHdr sHDR( pMDL->GetStudioHdr(), g_pMDLCache );
1143-
::SetBodygroup( &sHDR, nBody, 1, m_iCurrentClassIndex-1 );
1142+
CStudioHdr* sHDR = m_RootMDL.m_pStudioHdr;
1143+
::SetBodygroup( sHDR, nBody, 1, m_iCurrentClassIndex-1 );
11441144
pMDL->m_nBody = nBody;
11451145
}
11461146
}
@@ -1341,6 +1341,8 @@ CEconItemView *CTFPlayerModelPanel::GetLoadoutItemFromMDLHandle( loadout_positio
13411341
// Check if we have a particle hat, if not ignore
13421342
CEconItemView *pEconItem = NULL;
13431343

1344+
const char* pModelName = vgui::MDLCache()->GetModelName(mdlHandle);
1345+
13441346
// Find this item
13451347
FOR_EACH_VEC( m_ItemsToCarry, i )
13461348
{
@@ -1354,15 +1356,12 @@ CEconItemView *CTFPlayerModelPanel::GetLoadoutItemFromMDLHandle( loadout_positio
13541356
const char * pDisplayModel = pItem->GetPlayerDisplayModel( m_iCurrentClassIndex, m_iTeam );
13551357
if ( pDisplayModel )
13561358
{
1357-
MDLHandle_t hMDLFindResult = vgui::MDLCache()->FindMDL( pDisplayModel );
1358-
// compare the model to make sure that this is the same item
1359-
if ( hMDLFindResult == mdlHandle )
1359+
// compare the model name to make sure that this is the same item
1360+
if ( !strcmp( pModelName, pDisplayModel ) )
13601361
{
13611362
pEconItem = pItem;
1362-
vgui::MDLCache()->Release(hMDLFindResult); // counterbalance addref from within FindMDL
13631363
break;
13641364
}
1365-
vgui::MDLCache()->Release(hMDLFindResult);
13661365
}
13671366
}
13681367
}
@@ -1466,9 +1465,9 @@ bool CTFPlayerModelPanel::RenderStatTrack( CStudioHdr *pStudioHdr, matrix3x4_t *
14661465
// it'll crash trying to pull data from the missing header.
14671466
if ( pStatTrackStudioHdr != NULL )
14681467
{
1469-
CStudioHdr mergeHdr( pStatTrackStudioHdr, g_pMDLCache );
1470-
m_StatTrackModel.m_MDL.SetupBonesWithBoneMerge( &mergeHdr, pMergeBoneToWorld, pStudioHdr, pWorldMatrix, m_StatTrackModel.m_MDLToWorld );
1471-
for ( int i=0; i<mergeHdr.numbones(); ++i )
1468+
CStudioHdr* mergeHdr = m_RootMDL.m_pStudioHdr;
1469+
m_StatTrackModel.m_MDL.SetupBonesWithBoneMerge( mergeHdr, pMergeBoneToWorld, pStudioHdr, pWorldMatrix, m_StatTrackModel.m_MDLToWorld );
1470+
for ( int i=0; i<mergeHdr->numbones(); ++i )
14721471
{
14731472
MatrixScaleBy( m_flStatTrackScale, pMergeBoneToWorld[i] );
14741473
}
@@ -1998,18 +1997,18 @@ void CTFPlayerModelPanel::ProcessSequence( CChoreoScene *scene, CChoreoEvent *ev
19981997
{
19991998
Assert( event->GetType() == CChoreoEvent::SEQUENCE );
20001999

2001-
CStudioHdr studioHdr( GetStudioHdr(), g_pMDLCache );
2000+
CStudioHdr* studioHdr = m_RootMDL.m_pStudioHdr;
20022001

20032002
if ( !event->GetActor() )
20042003
return;
20052004

2006-
int iSequence = LookupSequence( &studioHdr, event->GetParameters() );
2005+
int iSequence = LookupSequence( studioHdr, event->GetParameters() );
20072006
if (iSequence < 0)
20082007
return;
20092008

20102009
// making sure the mdl has correct playback rate
2011-
mstudioseqdesc_t &seqdesc = studioHdr.pSeqdesc( iSequence );
2012-
mstudioanimdesc_t &animdesc = studioHdr.pAnimdesc( studioHdr.iRelativeAnim( iSequence, seqdesc.anim(0,0) ) );
2010+
mstudioseqdesc_t &seqdesc = studioHdr->pSeqdesc( iSequence );
2011+
mstudioanimdesc_t &animdesc = studioHdr->pAnimdesc( studioHdr->iRelativeAnim( iSequence, seqdesc.anim(0,0) ) );
20132012
m_RootMDL.m_MDL.m_flPlaybackRate = animdesc.fps;
20142013

20152014
MDLSquenceLayer_t tmpSequenceLayers[1];
@@ -2076,18 +2075,18 @@ void CTFPlayerModelPanel::ProcessLoop( CChoreoScene *scene, CChoreoEvent *event
20762075
//-----------------------------------------------------------------------------
20772076
LocalFlexController_t CTFPlayerModelPanel::GetNumFlexControllers( void )
20782077
{
2079-
CStudioHdr studioHdr( GetStudioHdr(), g_pMDLCache );
2080-
return studioHdr.numflexcontrollers();
2078+
CStudioHdr* studioHdr = m_RootMDL.m_pStudioHdr;
2079+
return studioHdr->numflexcontrollers();
20812080
}
20822081

20832082
//-----------------------------------------------------------------------------
20842083
// Purpose:
20852084
//-----------------------------------------------------------------------------
20862085
const char *CTFPlayerModelPanel::GetFlexDescFacs( int iFlexDesc )
20872086
{
2088-
CStudioHdr studioHdr( GetStudioHdr(), g_pMDLCache );
2087+
CStudioHdr* studioHdr = m_RootMDL.m_pStudioHdr;
20892088

2090-
mstudioflexdesc_t *pflexdesc = studioHdr.pFlexdesc( iFlexDesc );
2089+
mstudioflexdesc_t *pflexdesc = studioHdr->pFlexdesc( iFlexDesc );
20912090

20922091
return pflexdesc->pszFACS( );
20932092
}
@@ -2097,9 +2096,9 @@ const char *CTFPlayerModelPanel::GetFlexDescFacs( int iFlexDesc )
20972096
//-----------------------------------------------------------------------------
20982097
const char *CTFPlayerModelPanel::GetFlexControllerName( LocalFlexController_t iFlexController )
20992098
{
2100-
CStudioHdr studioHdr( GetStudioHdr(), g_pMDLCache );
2099+
CStudioHdr* studioHdr = m_RootMDL.m_pStudioHdr;
21012100

2102-
mstudioflexcontroller_t *pflexcontroller = studioHdr.pFlexcontroller( iFlexController );
2101+
mstudioflexcontroller_t *pflexcontroller = studioHdr->pFlexcontroller( iFlexController );
21032102

21042103
return pflexcontroller->pszName( );
21052104
}
@@ -2109,9 +2108,9 @@ const char *CTFPlayerModelPanel::GetFlexControllerName( LocalFlexController_t iF
21092108
//-----------------------------------------------------------------------------
21102109
const char *CTFPlayerModelPanel::GetFlexControllerType( LocalFlexController_t iFlexController )
21112110
{
2112-
CStudioHdr studioHdr( GetStudioHdr(), g_pMDLCache );
2111+
CStudioHdr* studioHdr = m_RootMDL.m_pStudioHdr;
21132112

2114-
mstudioflexcontroller_t *pflexcontroller = studioHdr.pFlexcontroller( iFlexController );
2113+
mstudioflexcontroller_t *pflexcontroller = studioHdr->pFlexcontroller( iFlexController );
21152114

21162115
return pflexcontroller->pszType( );
21172116
}
@@ -2140,9 +2139,9 @@ void CTFPlayerModelPanel::SetFlexWeight( LocalFlexController_t index, float valu
21402139
{
21412140
if (index >= 0 && index < GetNumFlexControllers())
21422141
{
2143-
CStudioHdr studioHdr( GetStudioHdr(), g_pMDLCache );
2142+
CStudioHdr* studioHdr = m_RootMDL.m_pStudioHdr;
21442143

2145-
mstudioflexcontroller_t *pflexcontroller = studioHdr.pFlexcontroller( index );
2144+
mstudioflexcontroller_t *pflexcontroller = studioHdr->pFlexcontroller( index );
21462145

21472146
if (pflexcontroller->max != pflexcontroller->min)
21482147
{
@@ -2161,9 +2160,9 @@ float CTFPlayerModelPanel::GetFlexWeight( LocalFlexController_t index )
21612160
{
21622161
if (index >= 0 && index < GetNumFlexControllers())
21632162
{
2164-
CStudioHdr studioHdr( GetStudioHdr(), g_pMDLCache );
2163+
CStudioHdr* studioHdr = m_RootMDL.m_pStudioHdr;
21652164

2166-
mstudioflexcontroller_t *pflexcontroller = studioHdr.pFlexcontroller( index );
2165+
mstudioflexcontroller_t *pflexcontroller = studioHdr->pFlexcontroller( index );
21672166

21682167
if (pflexcontroller->max != pflexcontroller->min)
21692168
{
@@ -2184,13 +2183,13 @@ void CTFPlayerModelPanel::SetupFlexWeights( void )
21842183
return;
21852184

21862185
// initialize the models local to global flex controller mappings
2187-
CStudioHdr studioHdr( GetStudioHdr(), g_pMDLCache );
2188-
if (studioHdr.pFlexcontroller( LocalFlexController_t(0) )->localToGlobal == -1)
2186+
CStudioHdr* studioHdr = m_RootMDL.m_pStudioHdr;
2187+
if (studioHdr->pFlexcontroller( LocalFlexController_t(0) )->localToGlobal == -1)
21892188
{
2190-
for ( LocalFlexController_t i = LocalFlexController_t(0); i < studioHdr.numflexcontrollers(); i++)
2189+
for ( LocalFlexController_t i = LocalFlexController_t(0); i < studioHdr->numflexcontrollers(); i++)
21912190
{
2192-
int j = C_BaseFlex::AddGlobalFlexController( studioHdr.pFlexcontroller( i )->pszName() );
2193-
studioHdr.pFlexcontroller( i )->localToGlobal = j;
2191+
int j = C_BaseFlex::AddGlobalFlexController( studioHdr->pFlexcontroller( i )->pszName() );
2192+
studioHdr->pFlexcontroller( i )->localToGlobal = j;
21942193
}
21952194
}
21962195

@@ -2216,9 +2215,9 @@ void CTFPlayerModelPanel::SetupFlexWeights( void )
22162215
}
22172216

22182217
// get the networked flexweights and convert them from 0..1 to real dynamic range
2219-
for (i = LocalFlexController_t(0); i < studioHdr.numflexcontrollers(); i++)
2218+
for (i = LocalFlexController_t(0); i < studioHdr->numflexcontrollers(); i++)
22202219
{
2221-
mstudioflexcontroller_t *pflex = studioHdr.pFlexcontroller( i );
2220+
mstudioflexcontroller_t *pflex = studioHdr->pFlexcontroller( i );
22222221

22232222
m_RootMDL.m_MDL.m_pFlexControls[pflex->localToGlobal] = m_flexWeight[i];
22242223
// rescale
@@ -2415,8 +2414,7 @@ void CTFPlayerModelPanel::ProcessFlexAnimation( CChoreoScene *scene, CChoreoEven
24152414
{
24162415
Assert( event->GetType() == CChoreoEvent::FLEXANIMATION );
24172416

2418-
CStudioHdr studioHdr( GetStudioHdr(), g_pMDLCache );
2419-
CStudioHdr *hdr = &studioHdr;
2417+
CStudioHdr* hdr = m_RootMDL.m_pStudioHdr;
24202418
if ( !hdr )
24212419
return;
24222420

@@ -2630,8 +2628,7 @@ void CTFPlayerModelPanel::AddVisemesForSentence( Emphasized_Phoneme *classes, fl
26302628
//-----------------------------------------------------------------------------
26312629
void CTFPlayerModelPanel::AddViseme( Emphasized_Phoneme *classes, float emphasis_intensity, int phoneme, float scale, bool newexpression )
26322630
{
2633-
CStudioHdr studioHdr( GetStudioHdr(), g_pMDLCache );
2634-
CStudioHdr *hdr = &studioHdr;
2631+
CStudioHdr* hdr = m_RootMDL.m_pStudioHdr;
26352632
if ( !hdr )
26362633
return;
26372634

@@ -2803,11 +2800,11 @@ void CTFPlayerModelPanel::ComputeBlendedSetting( Emphasized_Phoneme *classes, fl
28032800
//-----------------------------------------------------------------------------
28042801
void CTFPlayerModelPanel::InitPhonemeMappings( void )
28052802
{
2806-
CStudioHdr studioHdr( GetStudioHdr(), g_pMDLCache );
2807-
if ( studioHdr.IsValid() )
2803+
CStudioHdr *studioHdr = m_RootMDL.m_pStudioHdr;
2804+
if ( studioHdr && studioHdr->IsValid() )
28082805
{
28092806
char szBasename[MAX_PATH];
2810-
Q_StripExtension( studioHdr.pszName(), szBasename, sizeof( szBasename ) );
2807+
Q_StripExtension( studioHdr->pszName(), szBasename, sizeof( szBasename ) );
28112808

28122809
char szExpressionName[MAX_PATH];
28132810
Q_snprintf( szExpressionName, sizeof( szExpressionName ), "%s/phonemes/phonemes", szBasename );

src/game/client/tf/workshop/item_import.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2599,14 +2599,14 @@ int CImportPreviewItemPanel::GetSequence( const char *pszGesture )
25992599
return -1;
26002600
}
26012601

2602-
CStudioHdr studioHdr( m_pPlayerModelPanel->GetStudioHdr(), g_pMDLCache );
2602+
CStudioHdr *studioHdr = m_pPlayerModelPanel->GetStudioHdrFull();
26032603

26042604
// Look for the bind pose by label since it's not an activity
26052605
if ( !pszGesture && V_strcasecmp( m_sCurrentPose.Get(), "ref" ) == 0 )
26062606
{
2607-
for ( int iSeq = 0; iSeq < studioHdr.GetNumSeq(); ++iSeq )
2607+
for ( int iSeq = 0; iSeq < studioHdr->GetNumSeq(); ++iSeq )
26082608
{
2609-
mstudioseqdesc_t &seqDesc = studioHdr.pSeqdesc( iSeq );
2609+
mstudioseqdesc_t &seqDesc = studioHdr->pSeqdesc( iSeq );
26102610
if ( V_strcasecmp( seqDesc.pszLabel(), m_sCurrentPose.Get() ) == 0 )
26112611
{
26122612
return iSeq;
@@ -2635,7 +2635,7 @@ int CImportPreviewItemPanel::GetSequence( const char *pszGesture )
26352635
{
26362636
sActivity = pszActivityOverride;
26372637
}
2638-
return m_pPlayerModelPanel->FindSequenceFromActivity( &studioHdr, sActivity.Get() );
2638+
return m_pPlayerModelPanel->FindSequenceFromActivity( studioHdr, sActivity.Get() );
26392639
}
26402640

26412641

@@ -2700,7 +2700,7 @@ void CImportPreviewItemPanel::StartGesture( const char *pszGesture )
27002700
int iSequence = GetSequence( pszGesture );
27012701
if ( iSequence >= 0 )
27022702
{
2703-
CStudioHdr studioHdr( m_pPlayerModelPanel->GetStudioHdr(), g_pMDLCache );
2703+
CStudioHdr* studioHdr = m_pPlayerModelPanel->GetStudioHdrFull();
27042704

27052705
MDLSquenceLayer_t tmpSequenceLayers[1];
27062706
tmpSequenceLayers[0].m_nSequenceIndex = iSequence;
@@ -2709,7 +2709,7 @@ void CImportPreviewItemPanel::StartGesture( const char *pszGesture )
27092709
tmpSequenceLayers[0].m_flCycleBeganAt = 0.0f;
27102710
m_pPlayerModelPanel->SetSequenceLayers( tmpSequenceLayers, 1 );
27112711

2712-
float flGestureDuration = Studio_Duration( &studioHdr, iSequence, NULL );
2712+
float flGestureDuration = Studio_Duration( studioHdr, iSequence, NULL );
27132713
m_flGestureEndTime = gpGlobals->curtime + flGestureDuration;
27142714
}
27152715
}

src/public/matsys_controls/mdlpanel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ class CMDLPanel : public CPotteryWheelPanel
114114
matrix3x4_t m_MDLToWorld;
115115
bool m_bDisabled;
116116
float m_flCycleStartTime;
117+
CStudioHdr *m_pStudioHdr = NULL;
117118
};
118119

119120
MDLData_t m_RootMDL;

0 commit comments

Comments
 (0)