mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-30 12:23:41 +01:00
Add performance monitor in debug compilations.
This commit is contained in:
parent
f2997102c7
commit
2f7b6e3d55
18 changed files with 204 additions and 233 deletions
|
|
@ -6,6 +6,7 @@ using Penumbra.Collections;
|
|||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.String;
|
||||
using Penumbra.String.Classes;
|
||||
using Penumbra.Util;
|
||||
using GameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject;
|
||||
|
||||
namespace Penumbra.Interop.Resolver;
|
||||
|
|
@ -110,7 +111,8 @@ public unsafe partial class PathResolver
|
|||
|
||||
private IntPtr LoadCharacterSoundDetour( IntPtr character, int unk1, int unk2, IntPtr unk3, ulong unk4, int unk5, int unk6, ulong unk7 )
|
||||
{
|
||||
var last = _characterSoundData;
|
||||
using var performance = Penumbra.Performance.Measure( PerformanceType.LoadSound );
|
||||
var last = _characterSoundData;
|
||||
_characterSoundData = IdentifyCollection( ( GameObject* )character, true );
|
||||
var ret = _loadCharacterSoundHook.Original( character, unk1, unk2, unk3, unk4, unk5, unk6, unk7 );
|
||||
_characterSoundData = last;
|
||||
|
|
@ -126,9 +128,9 @@ public unsafe partial class PathResolver
|
|||
|
||||
private ulong LoadTimelineResourcesDetour( IntPtr timeline )
|
||||
{
|
||||
TimingManager.StartTimer( TimingType.TimelineResources );
|
||||
ulong ret;
|
||||
var old = _animationLoadData;
|
||||
using var performance = Penumbra.Performance.Measure( PerformanceType.TimelineResources );
|
||||
ulong ret;
|
||||
var old = _animationLoadData;
|
||||
try
|
||||
{
|
||||
if( timeline != IntPtr.Zero )
|
||||
|
|
@ -152,8 +154,6 @@ public unsafe partial class PathResolver
|
|||
}
|
||||
|
||||
_animationLoadData = old;
|
||||
|
||||
TimingManager.StopTimer( TimingType.TimelineResources );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -167,7 +167,8 @@ public unsafe partial class PathResolver
|
|||
|
||||
private void CharacterBaseLoadAnimationDetour( IntPtr drawObject )
|
||||
{
|
||||
var last = _animationLoadData;
|
||||
using var performance = Penumbra.Performance.Measure( PerformanceType.LoadCharacterBaseAnimation );
|
||||
var last = _animationLoadData;
|
||||
_animationLoadData = _drawObjectState.LastCreatedCollection.Valid
|
||||
? _drawObjectState.LastCreatedCollection
|
||||
: FindParent( drawObject, out var collection ) != null
|
||||
|
|
@ -186,8 +187,9 @@ public unsafe partial class PathResolver
|
|||
|
||||
private void LoadSomePapDetour( IntPtr a1, int a2, IntPtr a3, int a4 )
|
||||
{
|
||||
var timelinePtr = a1 + 0x50;
|
||||
var last = _animationLoadData;
|
||||
using var performance = Penumbra.Performance.Measure( PerformanceType.LoadPap );
|
||||
var timelinePtr = a1 + 0x50;
|
||||
var last = _animationLoadData;
|
||||
if( timelinePtr != IntPtr.Zero )
|
||||
{
|
||||
var actorIdx = ( int )( *( *( ulong** )timelinePtr + 1 ) >> 3 );
|
||||
|
|
@ -207,7 +209,8 @@ public unsafe partial class PathResolver
|
|||
|
||||
private void SomeActionLoadDetour( IntPtr gameObject )
|
||||
{
|
||||
var last = _animationLoadData;
|
||||
using var performance = Penumbra.Performance.Measure( PerformanceType.LoadAction );
|
||||
var last = _animationLoadData;
|
||||
_animationLoadData = IdentifyCollection( ( GameObject* )gameObject, true );
|
||||
_someActionLoadHook.Original( gameObject );
|
||||
_animationLoadData = last;
|
||||
|
|
@ -248,8 +251,8 @@ public unsafe partial class PathResolver
|
|||
|
||||
private IntPtr LoadCharacterVfxDetour( byte* vfxPath, VfxParams* vfxParams, byte unk1, byte unk2, float unk3, int unk4 )
|
||||
{
|
||||
TimingManager.StartTimer( TimingType.LoadCharacterVfx );
|
||||
var last = _animationLoadData;
|
||||
using var performance = Penumbra.Performance.Measure( PerformanceType.LoadCharacterVfx );
|
||||
var last = _animationLoadData;
|
||||
if( vfxParams != null && vfxParams->GameObjectId != unchecked( ( uint )-1 ) )
|
||||
{
|
||||
var obj = vfxParams->GameObjectType switch
|
||||
|
|
@ -267,6 +270,7 @@ public unsafe partial class PathResolver
|
|||
{
|
||||
_animationLoadData = ResolveData.Invalid;
|
||||
}
|
||||
|
||||
var ret = _loadCharacterVfxHook.Original( vfxPath, vfxParams, unk1, unk2, unk3, unk4 );
|
||||
#if DEBUG
|
||||
var path = new ByteString( vfxPath );
|
||||
|
|
@ -274,7 +278,6 @@ public unsafe partial class PathResolver
|
|||
$"Load Character VFX: {path} {vfxParams->GameObjectId:X} {vfxParams->TargetCount} {unk1} {unk2} {unk3} {unk4} -> {ret:X} {_animationLoadData.ModCollection.Name} {_animationLoadData.AssociatedGameObject} {last.ModCollection.Name} {last.AssociatedGameObject}" );
|
||||
#endif
|
||||
_animationLoadData = last;
|
||||
TimingManager.StopTimer( TimingType.LoadCharacterVfx );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -285,8 +288,8 @@ public unsafe partial class PathResolver
|
|||
|
||||
private IntPtr LoadAreaVfxDetour( uint vfxId, float* pos, GameObject* caster, float unk1, float unk2, byte unk3 )
|
||||
{
|
||||
TimingManager.StartTimer( TimingType.LoadAreaVfx );
|
||||
var last = _animationLoadData;
|
||||
using var performance = Penumbra.Performance.Measure( PerformanceType.LoadAreaVfx );
|
||||
var last = _animationLoadData;
|
||||
if( caster != null )
|
||||
{
|
||||
_animationLoadData = IdentifyCollection( caster, true );
|
||||
|
|
@ -302,7 +305,6 @@ public unsafe partial class PathResolver
|
|||
$"Load Area VFX: {vfxId}, {pos[ 0 ]} {pos[ 1 ]} {pos[ 2 ]} {( caster != null ? new ByteString( caster->GetName() ).ToString() : "Unknown" )} {unk1} {unk2} {unk3} -> {ret:X} {_animationLoadData.ModCollection.Name} {_animationLoadData.AssociatedGameObject} {last.ModCollection.Name} {last.AssociatedGameObject}" );
|
||||
#endif
|
||||
_animationLoadData = last;
|
||||
TimingManager.StopTimer( TimingType.LoadAreaVfx );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
|||
using OtterGui.Classes;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.String.Classes;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Interop.Resolver;
|
||||
|
||||
|
|
@ -138,7 +139,8 @@ public unsafe partial class PathResolver
|
|||
|
||||
private IntPtr CharacterBaseCreateDetour( uint a, IntPtr b, IntPtr c, byte d )
|
||||
{
|
||||
TimingManager.StartTimer( TimingType.CharacterBaseCreate );
|
||||
using var performance = Penumbra.Performance.Measure( PerformanceType.CharacterBaseCreate );
|
||||
|
||||
var meta = DisposableContainer.Empty;
|
||||
if( LastGameObject != null )
|
||||
{
|
||||
|
|
@ -171,7 +173,7 @@ public unsafe partial class PathResolver
|
|||
{
|
||||
meta.Dispose();
|
||||
}
|
||||
TimingManager.StopTimer( TimingType.CharacterBaseCreate );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using OtterGui;
|
|||
using Penumbra.Collections;
|
||||
using Penumbra.GameData.Actors;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.Util;
|
||||
using Character = FFXIVClientStructs.FFXIV.Client.Game.Character.Character;
|
||||
using GameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject;
|
||||
using ObjectKind = Dalamud.Game.ClientState.Objects.Enums.ObjectKind;
|
||||
|
|
@ -19,12 +20,13 @@ public unsafe partial class PathResolver
|
|||
// Identify the correct collection for a GameObject by index and name.
|
||||
public static ResolveData IdentifyCollection( GameObject* gameObject, bool useCache )
|
||||
{
|
||||
using var performance = Penumbra.Performance.Measure( PerformanceType.IdentifyCollection );
|
||||
|
||||
if( gameObject == null )
|
||||
{
|
||||
return new ResolveData( Penumbra.CollectionManager.Default );
|
||||
}
|
||||
|
||||
TimingManager.StartTimer( TimingType.IdentifyCollection );
|
||||
try
|
||||
{
|
||||
if( useCache && IdentifiedCache.TryGetValue( gameObject, out var data ) )
|
||||
|
|
@ -69,35 +71,25 @@ public unsafe partial class PathResolver
|
|||
Penumbra.Log.Error( $"Error identifying collection:\n{e}" );
|
||||
return Penumbra.CollectionManager.Default.ToResolveData( gameObject );
|
||||
}
|
||||
finally
|
||||
{
|
||||
TimingManager.StopTimer( TimingType.IdentifyCollection );
|
||||
}
|
||||
}
|
||||
|
||||
// Get the collection applying to the current player character
|
||||
// or the default collection if no player exists.
|
||||
public static ModCollection PlayerCollection()
|
||||
{
|
||||
TimingManager.StartTimer( TimingType.IdentifyCollection );
|
||||
var gameObject = ( GameObject* )Dalamud.Objects.GetObjectAddress( 0 );
|
||||
ModCollection ret;
|
||||
using var performance = Penumbra.Performance.Measure( PerformanceType.IdentifyCollection );
|
||||
var gameObject = ( GameObject* )Dalamud.Objects.GetObjectAddress( 0 );
|
||||
if( gameObject == null )
|
||||
{
|
||||
ret = Penumbra.CollectionManager.ByType( CollectionType.Yourself )
|
||||
return Penumbra.CollectionManager.ByType( CollectionType.Yourself )
|
||||
?? Penumbra.CollectionManager.Default;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
var player = Penumbra.Actors.GetCurrentPlayer();
|
||||
ret = CollectionByIdentifier( player )
|
||||
?? CheckYourself( player, gameObject )
|
||||
?? CollectionByAttributes( gameObject )
|
||||
?? Penumbra.CollectionManager.Default;
|
||||
}
|
||||
TimingManager.StopTimer( TimingType.IdentifyCollection );
|
||||
return ret;
|
||||
var player = Penumbra.Actors.GetCurrentPlayer();
|
||||
return CollectionByIdentifier( player )
|
||||
?? CheckYourself( player, gameObject )
|
||||
?? CollectionByAttributes( gameObject )
|
||||
?? Penumbra.CollectionManager.Default;
|
||||
}
|
||||
|
||||
// Check both temporary and permanent character collections. Temporary first.
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
|||
using OtterGui.Classes;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.Util;
|
||||
using ObjectType = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.ObjectType;
|
||||
using static Penumbra.GameData.Enums.GenderRace;
|
||||
|
||||
|
|
@ -97,6 +98,7 @@ public unsafe partial class PathResolver
|
|||
{
|
||||
return;
|
||||
}
|
||||
using var performance = Penumbra.Performance.Measure( PerformanceType.UpdateModels );
|
||||
|
||||
var collection = GetResolveData( drawObject );
|
||||
using var eqp = collection.ModCollection.TemporarilySetEqpFile();
|
||||
|
|
@ -134,7 +136,7 @@ public unsafe partial class PathResolver
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var performance = Penumbra.Performance.Measure( PerformanceType.GetEqp );
|
||||
var resolveData = GetResolveData( drawObject );
|
||||
using var eqp = resolveData.ModCollection.TemporarilySetEqpFile();
|
||||
_getEqpIndirectHook.Original( drawObject );
|
||||
|
|
@ -150,6 +152,7 @@ public unsafe partial class PathResolver
|
|||
|
||||
private byte SetupVisorDetour( IntPtr drawObject, ushort modelId, byte visorState )
|
||||
{
|
||||
using var performance = Penumbra.Performance.Measure( PerformanceType.SetupVisor );
|
||||
var resolveData = GetResolveData( drawObject );
|
||||
using var gmp = resolveData.ModCollection.TemporarilySetGmpFile();
|
||||
return _setupVisorHook.Original( drawObject, modelId, visorState );
|
||||
|
|
@ -169,6 +172,7 @@ public unsafe partial class PathResolver
|
|||
}
|
||||
else
|
||||
{
|
||||
using var performance = Penumbra.Performance.Measure( PerformanceType.SetupCharacter );
|
||||
var resolveData = GetResolveData( drawObject );
|
||||
using var cmp = resolveData.ModCollection.TemporarilySetCmpFile();
|
||||
_rspSetupCharacterHook.Original( drawObject, unk2, unk3, unk4, unk5 );
|
||||
|
|
@ -184,6 +188,7 @@ public unsafe partial class PathResolver
|
|||
|
||||
private bool ChangeCustomizeDetour( IntPtr human, IntPtr data, byte skipEquipment )
|
||||
{
|
||||
using var performance = Penumbra.Performance.Measure( PerformanceType.ChangeCustomize );
|
||||
_inChangeCustomize = true;
|
||||
var resolveData = GetResolveData( human );
|
||||
using var cmp = resolveData.ModCollection.TemporarilySetCmpFile();
|
||||
|
|
|
|||
|
|
@ -95,7 +95,6 @@ public unsafe partial class PathResolver
|
|||
// Special handling for paths so that we do not store non-owned temporary strings in the dictionary.
|
||||
public void SetCollection( IntPtr gameObject, ByteString path, ModCollection collection )
|
||||
{
|
||||
TimingManager.StartTimer( TimingType.SetPathCollection );
|
||||
if( _pathCollections.ContainsKey( path ) || path.IsOwned )
|
||||
{
|
||||
_pathCollections[ path ] = collection.ToResolveData( gameObject );
|
||||
|
|
@ -104,7 +103,6 @@ public unsafe partial class PathResolver
|
|||
{
|
||||
_pathCollections[ path.Clone() ] = collection.ToResolveData( gameObject );
|
||||
}
|
||||
TimingManager.StopTimer( TimingType.SetPathCollection );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ using Penumbra.Interop.Loader;
|
|||
using Penumbra.Interop.Structs;
|
||||
using Penumbra.String;
|
||||
using Penumbra.String.Classes;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Interop.Resolver;
|
||||
|
||||
|
|
@ -113,9 +114,7 @@ public unsafe partial class PathResolver
|
|||
case ResourceType.Avfx:
|
||||
if( handle->FileSize == 0 )
|
||||
{
|
||||
TimingManager.StartTimer( TimingType.AddSubfile );
|
||||
_subFileCollection[ ( IntPtr )handle ] = resolveData;
|
||||
TimingManager.StopTimer( TimingType.AddSubfile );
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -128,9 +127,7 @@ public unsafe partial class PathResolver
|
|||
{
|
||||
case ResourceType.Mtrl:
|
||||
case ResourceType.Avfx:
|
||||
TimingManager.StartTimer( TimingType.AddSubfile );
|
||||
_subFileCollection.TryRemove( ( IntPtr )handle, out _ );
|
||||
TimingManager.StopTimer( TimingType.AddSubfile );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -167,6 +164,7 @@ public unsafe partial class PathResolver
|
|||
|
||||
private byte LoadMtrlTexDetour( IntPtr mtrlResourceHandle )
|
||||
{
|
||||
using var performance = Penumbra.Performance.Measure( PerformanceType.LoadTextures );
|
||||
_mtrlData = LoadFileHelper( mtrlResourceHandle );
|
||||
var ret = _loadMtrlTexHook.Original( mtrlResourceHandle );
|
||||
_mtrlData = ResolveData.Invalid;
|
||||
|
|
@ -179,6 +177,7 @@ public unsafe partial class PathResolver
|
|||
|
||||
private byte LoadMtrlShpkDetour( IntPtr mtrlResourceHandle )
|
||||
{
|
||||
using var performance = Penumbra.Performance.Measure( PerformanceType.LoadShaders );
|
||||
_mtrlData = LoadFileHelper( mtrlResourceHandle );
|
||||
var ret = _loadMtrlShpkHook.Original( mtrlResourceHandle );
|
||||
_mtrlData = ResolveData.Invalid;
|
||||
|
|
@ -204,6 +203,7 @@ public unsafe partial class PathResolver
|
|||
|
||||
private byte ApricotResourceLoadDetour( IntPtr handle, IntPtr unk1, byte unk2 )
|
||||
{
|
||||
using var performance = Penumbra.Performance.Measure( PerformanceType.LoadApricotResources );
|
||||
_avfxData = LoadFileHelper( handle );
|
||||
var ret = _apricotResourceLoadHook.Original( handle, unk1, unk2 );
|
||||
_avfxData = ResolveData.Invalid;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using Penumbra.GameData.Enums;
|
|||
using Penumbra.Interop.Loader;
|
||||
using Penumbra.String;
|
||||
using Penumbra.String.Classes;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Interop.Resolver;
|
||||
|
||||
|
|
@ -48,7 +49,7 @@ public partial class PathResolver : IDisposable
|
|||
// The modified resolver that handles game path resolving.
|
||||
private bool CharacterResolver( Utf8GamePath gamePath, ResourceCategory _1, ResourceType type, int _2, out (FullPath?, ResolveData) data )
|
||||
{
|
||||
TimingManager.StartTimer( TimingType.CharacterResolver );
|
||||
using var performance = Penumbra.Performance.Measure( PerformanceType.CharacterResolver );
|
||||
// Check if the path was marked for a specific collection,
|
||||
// or if it is a file loaded by a material, and if we are currently in a material load,
|
||||
// or if it is a face decal path and the current mod collection is set.
|
||||
|
|
@ -72,7 +73,6 @@ public partial class PathResolver : IDisposable
|
|||
// We also need to handle defaulted materials against a non-default collection.
|
||||
var path = resolved == null ? gamePath.Path : resolved.Value.InternalName;
|
||||
SubfileHelper.HandleCollection( resolveData, path, nonDefault, type, resolved, out data );
|
||||
TimingManager.StopTimer( TimingType.CharacterResolver );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue