Optimize editor profiler native allocations when capturing data

This commit is contained in:
Wojtek Figat
2025-06-09 15:23:31 +02:00
parent 057ec9d41e
commit d7ff9fdade
7 changed files with 83 additions and 3 deletions

View File

@@ -800,6 +800,23 @@ void Content::deleteFileSafety(const StringView& path, const Guid& id)
#endif
}
#if !COMPILE_WITHOUT_CSHARP
#include "Engine/Scripting/ManagedCLR/MUtils.h"
void* Content::GetAssetsInternal()
{
AssetsLocker.Lock();
MArray* result = MCore::Array::New(Asset::TypeInitializer.GetClass(), Assets.Count());
int32 i = 0;
for (const auto& e : Assets)
MCore::GC::WriteArrayRef(result, e.Value->GetOrCreateManagedInstance(), i++);
AssetsLocker.Unlock();
return result;
}
#endif
#if USE_EDITOR
bool Content::RenameAsset(const StringView& oldPath, const StringView& newPath)

View File

@@ -1,5 +1,6 @@
// Copyright (c) Wojciech Figat. All rights reserved.
using FlaxEngine.Interop;
using System;
using System.Runtime.CompilerServices;
@@ -7,6 +8,19 @@ namespace FlaxEngine
{
partial class Content
{
/// <summary>
/// Gets the assets (loaded or during load).
/// </summary>
public static Asset[] Assets
{
get
{
IntPtr ptr = Internal_GetAssetsInternal();
ManagedArray array = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(ptr).Target);
return NativeInterop.GCHandleArrayToManagedArray<Asset>(array);
}
}
/// <summary>
/// Loads asset to the Content Pool and holds it until it won't be referenced by any object. Returns null if asset is missing. Actual asset data loading is performed on a other thread in async.
/// </summary>

View File

@@ -122,7 +122,7 @@ public:
/// Gets the assets (loaded or during load).
/// </summary>
/// <returns>The collection of assets.</returns>
API_PROPERTY() static Array<Asset*, HeapAllocation> GetAssets();
static Array<Asset*, HeapAllocation> GetAssets();
/// <summary>
/// Gets the raw dictionary of assets (loaded or during load).
@@ -368,4 +368,9 @@ private:
static void onAssetUnload(Asset* asset);
static void onAssetChangeId(Asset* asset, const Guid& oldId, const Guid& newId);
static void deleteFileSafety(const StringView& path, const Guid& id);
// Internal bindings
#if !COMPILE_WITHOUT_CSHARP
API_FUNCTION(NoProxy) static void* GetAssetsInternal();
#endif
};

View File

@@ -201,7 +201,10 @@ namespace FlaxEngine.Interop
Span<IntPtr> span = ptrArray.ToSpan<IntPtr>();
T[] managedArray = new T[ptrArray.Length];
for (int i = 0; i < managedArray.Length; i++)
managedArray[i] = span[i] != IntPtr.Zero ? (T)ManagedHandle.FromIntPtr(span[i]).Target : default;
{
IntPtr ptr = span[i];
managedArray[i] = ptr != IntPtr.Zero ? (T)ManagedHandle.FromIntPtr(ptr).Target : default;
}
return managedArray;
}

View File

@@ -1,9 +1,27 @@
// Copyright (c) Wojciech Figat. All rights reserved.
using System;
using System.Runtime.CompilerServices;
using FlaxEngine.Interop;
namespace FlaxEngine
{
partial class GPUDevice
{
/// <summary>
/// Gets the list with all active GPU resources.
/// </summary>
public GPUResource[] Resources
{
get
{
IntPtr ptr = Internal_GetResourcesInternal(__unmanagedPtr);
ManagedArray array = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(ptr).Target);
return NativeInterop.GCHandleArrayToManagedArray<GPUResource>(array);
}
}
}
partial struct GPUBufferDescription : IEquatable<GPUBufferDescription>
{
/// <summary>

View File

@@ -648,6 +648,23 @@ GPUTasksExecutor* GPUDevice::CreateTasksExecutor()
return New<DefaultGPUTasksExecutor>();
}
#if !COMPILE_WITHOUT_CSHARP
#include "Engine/Scripting/ManagedCLR/MUtils.h"
void* GPUDevice::GetResourcesInternal()
{
_resourcesLock.Lock();
MArray* result = MCore::Array::New(GPUResource::TypeInitializer.GetClass(), _resources.Count());
int32 i = 0;
for (const auto& e : _resources)
MCore::GC::WriteArrayRef(result, e->GetOrCreateManagedInstance(), i++);
_resourcesLock.Unlock();
return result;
}
#endif
void GPUDevice::Draw()
{
PROFILE_MEM(Graphics);

View File

@@ -236,7 +236,7 @@ public:
/// <summary>
/// Gets the list with all active GPU resources.
/// </summary>
API_PROPERTY() Array<GPUResource*> GetResources() const;
Array<GPUResource*> GetResources() const;
/// <summary>
/// Gets the GPU asynchronous work manager.
@@ -432,6 +432,12 @@ public:
/// </summary>
/// <returns>The GPU tasks executor.</returns>
virtual GPUTasksExecutor* CreateTasksExecutor();
private:
// Internal bindings
#if !COMPILE_WITHOUT_CSHARP
API_FUNCTION(NoProxy) void* GetResourcesInternal();
#endif
};
/// <summary>