Files
sbox-public/engine/Sandbox.Engine/Systems/Render/RenderAttributes.TextureTracking.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

61 lines
1.7 KiB
C#

using NativeEngine;
namespace Sandbox;
public partial class RenderAttributes
{
// Keep a list of textures we've used, CRenderAttributes doesn't use strong handles.
// This is mainly here to keep textures alive when stored in long lived attributes like SceneObject.Attributes
// Otherwise the GC may collect them while still in use by native code.
// It could be done on CRenderAttributes natively, but we tried that before and fucked it, it's complicated.
private Dictionary<StringToken, ITexture> usedTextures; // lazy allocated
private void SetUsedTexture( StringToken k, Texture texture )
{
usedTextures ??= [];
var native = texture?.native ?? default;
// Is this key already holding a texture
if ( usedTextures.TryGetValue( k, out var old ) )
{
// Does the existing data point to the same as the new data?
// If so, nothing to do!
if ( native.IsValid && old.GetBindingPtr() == native.GetBindingPtr() )
return;
// Otherwise, kill our old handle, we're replacing it
old.DestroyStrongHandle();
}
// If our new handle is null, don't write it, just remove any possible entry
if ( native.IsNull )
{
usedTextures.Remove( k );
return;
}
// Finally COPY a strong handle, otherwise we're at the mercy of Texture.Dispose()
usedTextures[k] = native.CopyStrongHandle();
}
/// <summary>
/// Clear used textures, destroying any strong handles we've created.
/// These handles are mainly used for storage RenderAttributes like SceneObject.Attributes
/// </summary>
private void ClearUsedTextures()
{
if ( usedTextures is null )
return;
// Clean up any strong handles
foreach ( var tex in usedTextures.Values )
{
if ( !tex.IsValid ) continue;
tex.DestroyStrongHandle();
}
usedTextures.Clear();
}
}