SHA256
Fix Little Memory Leak Risk
This commit is contained in:
1 parent
6bd4a8975e
commit
bc7a7eca75
3 files changed
+47
-11
No files matched your search
@@ -624,6 +624,22 @@ namespace ADOFAIRenderer.Core
|
|||||||
GCS.customLevelPaths = null;
|
GCS.customLevelPaths = null;
|
||||||
GCS.customLevelId = null;
|
GCS.customLevelId = null;
|
||||||
|
|
||||||
|
lock (ImageQueue)
|
||||||
|
{
|
||||||
|
foreach (var kvp in ImageQueue.Values)
|
||||||
|
{
|
||||||
|
if (kvp.ManagedBuffer != null && kvp.ManagedBuffer.Length > 0)
|
||||||
|
{
|
||||||
|
ArrayPool<byte>.Shared.Return(kvp.ManagedBuffer);
|
||||||
|
}
|
||||||
|
if (kvp.ReadbackState != null)
|
||||||
|
{
|
||||||
|
_frameReader?.RecycleState(kvp.ReadbackState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImageQueue.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
_frameReader?.Dispose();
|
_frameReader?.Dispose();
|
||||||
ADOBase.loader.LoadSceneWithTransition(WipeDirection.StartsFromRight, "scnEditor");
|
ADOBase.loader.LoadSceneWithTransition(WipeDirection.StartsFromRight, "scnEditor");
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-6
@@ -1,8 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using ADOFAIRenderer.Core;
|
using ADOFAIRenderer.Core;
|
||||||
using ADOFAIRenderer.Util.FFmpeg;
|
|
||||||
using MelonLoader;
|
using MelonLoader;
|
||||||
using Unity.Collections;
|
using Unity.Collections;
|
||||||
using Unity.Collections.LowLevel.Unsafe;
|
using Unity.Collections.LowLevel.Unsafe;
|
||||||
@@ -16,6 +16,7 @@ namespace ADOFAIRenderer.Util
|
|||||||
private const int InitialBufferSize = 16;
|
private const int InitialBufferSize = 16;
|
||||||
|
|
||||||
private readonly Stack<ReadbackRequestState> _statePool = new Stack<ReadbackRequestState>();
|
private readonly Stack<ReadbackRequestState> _statePool = new Stack<ReadbackRequestState>();
|
||||||
|
private readonly List<ReadbackRequestState> _allocatedStates = new List<ReadbackRequestState>();
|
||||||
private readonly object _poolLock = new object();
|
private readonly object _poolLock = new object();
|
||||||
private bool _isInitialized;
|
private bool _isInitialized;
|
||||||
private volatile bool _isDisposed;
|
private volatile bool _isDisposed;
|
||||||
@@ -27,13 +28,14 @@ namespace ADOFAIRenderer.Util
|
|||||||
|
|
||||||
private void InitializePool()
|
private void InitializePool()
|
||||||
{
|
{
|
||||||
|
|
||||||
lock (_poolLock)
|
lock (_poolLock)
|
||||||
{
|
{
|
||||||
if (_isInitialized) return;
|
if (_isInitialized) return;
|
||||||
for (var i = 0; i < InitialBufferSize; i++)
|
for (var i = 0; i < InitialBufferSize; i++)
|
||||||
{
|
{
|
||||||
_statePool.Push(new ReadbackRequestState(this));
|
var state = new ReadbackRequestState(this);
|
||||||
|
_statePool.Push(state);
|
||||||
|
_allocatedStates.Add(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
_isInitialized = true;
|
_isInitialized = true;
|
||||||
@@ -47,7 +49,17 @@ namespace ADOFAIRenderer.Util
|
|||||||
|
|
||||||
lock (_poolLock)
|
lock (_poolLock)
|
||||||
{
|
{
|
||||||
state = _statePool.Count == 0 ? new ReadbackRequestState(this) : _statePool.Pop();
|
if (_statePool.Count == 0)
|
||||||
|
{
|
||||||
|
state = new ReadbackRequestState(this);
|
||||||
|
_allocatedStates.Add(state);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state = _statePool.Pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
state.IsInFlight = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var bufferSize = texture.width * texture.height * 4; // RGBA = 4 channel
|
var bufferSize = texture.width * texture.height * 4; // RGBA = 4 channel
|
||||||
@@ -67,6 +79,7 @@ namespace ADOFAIRenderer.Util
|
|||||||
|
|
||||||
lock (_poolLock)
|
lock (_poolLock)
|
||||||
{
|
{
|
||||||
|
state.IsInFlight = false;
|
||||||
if (_isDisposed)
|
if (_isDisposed)
|
||||||
{
|
{
|
||||||
state.Dispose();
|
state.Dispose();
|
||||||
@@ -146,11 +159,12 @@ namespace ADOFAIRenderer.Util
|
|||||||
{
|
{
|
||||||
if (_isDisposed) return;
|
if (_isDisposed) return;
|
||||||
_isDisposed = true;
|
_isDisposed = true;
|
||||||
while (_statePool.Count > 0)
|
foreach (var state in _allocatedStates.Where(state => !state.IsInFlight))
|
||||||
{
|
{
|
||||||
var state = _statePool.Pop();
|
|
||||||
state.Dispose();
|
state.Dispose();
|
||||||
}
|
}
|
||||||
|
_statePool.Clear();
|
||||||
|
_allocatedStates.Clear();
|
||||||
_isInitialized = false;
|
_isInitialized = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -161,6 +175,7 @@ namespace ADOFAIRenderer.Util
|
|||||||
private readonly FrameReader _owner;
|
private readonly FrameReader _owner;
|
||||||
public long FrameIndex { get; private set; }
|
public long FrameIndex { get; private set; }
|
||||||
public NativeArray<byte> NativeBuffer;
|
public NativeArray<byte> NativeBuffer;
|
||||||
|
public bool IsInFlight { get; internal set; }
|
||||||
|
|
||||||
public readonly Action<AsyncGPUReadbackRequest> CachedCallback;
|
public readonly Action<AsyncGPUReadbackRequest> CachedCallback;
|
||||||
|
|
||||||
|
|||||||
+10
-5
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using MelonLoader;
|
||||||
|
|
||||||
namespace ADOFAIRenderer.Util
|
namespace ADOFAIRenderer.Util
|
||||||
{
|
{
|
||||||
@@ -13,11 +14,15 @@ namespace ADOFAIRenderer.Util
|
|||||||
|
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
// Create an unmanaged memory stream that wraps the native pointer
|
try
|
||||||
// (This does not allocate new memory; it references the existing pointer)
|
{
|
||||||
using var unmanagedStream = new UnmanagedMemoryStream((byte*)nativePtr, length);
|
var span = new ReadOnlySpan<byte>((void*)nativePtr, length);
|
||||||
// Copy the data directly into your target stream
|
destinationStream.Write(span);
|
||||||
unmanagedStream.CopyTo(destinationStream);
|
}
|
||||||
|
catch (IOException err)
|
||||||
|
{
|
||||||
|
Melon<RenderMod>.Logger.Error($"FFmpeg 파이프가 예상치 못하게 닫혔습니다: {err.Message}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user