diff --git a/Assets/Mediapipe/Samples/Common/Scripts/ImageSource/TextureFrame.cs b/Assets/Mediapipe/Samples/Common/Scripts/ImageSource/TextureFrame.cs index b6eb03945..c1508d8bb 100644 --- a/Assets/Mediapipe/Samples/Common/Scripts/ImageSource/TextureFrame.cs +++ b/Assets/Mediapipe/Samples/Common/Scripts/ImageSource/TextureFrame.cs @@ -25,6 +25,13 @@ public class ReleaseEvent : UnityEvent { } private const string _TAG = nameof(TextureFrame); private static readonly GlobalInstanceTable _InstanceTable = new GlobalInstanceTable(100); + /// + /// A dictionary to look up which native texture belongs to which . + /// + /// + /// Not all the instances are registered. + /// Texture names are queried only when necessary, and the corresponding data will be saved then. + /// private static readonly Dictionary _NameTable = new Dictionary(); private readonly Texture2D _texture; @@ -87,7 +94,7 @@ private TextureFrame(Texture2D texture) format = texture.format; OnRelease = new ReleaseEvent(); _instanceId = Guid.NewGuid(); - RegisterInstance(this); + _InstanceTable.Add(_instanceId, this); } public TextureFrame(int width, int height, TextureFormat format) : this(new Texture2D(width, height, format, false)) { } @@ -182,13 +189,14 @@ public Color32[] GetPixels32() public void SetPixels32(Color32[] pixels) { - var oldName = GetTextureName(); - _texture.SetPixels32(pixels); _texture.Apply(); - _nativeTexturePtr = IntPtr.Zero; - ChangeNameFrom(oldName); + if (!RevokeNativeTexturePtr()) + { + // If this line was executed, there must be a bug. + Logger.LogError("Failed to revoke the native texture."); + } } public NativeArray GetRawTextureData() where T : struct @@ -196,11 +204,22 @@ public NativeArray GetRawTextureData() where T : struct return _texture.GetRawTextureData(); } + /// The texture's native pointer public IntPtr GetNativeTexturePtr() { if (_nativeTexturePtr == IntPtr.Zero) { _nativeTexturePtr = _texture.GetNativeTexturePtr(); + var name = (uint)_nativeTexturePtr; + + lock (((ICollection)_NameTable).SyncRoot) + { + if (!AcquireName(name, _instanceId)) + { + throw new InvalidProgramException($"Another instance (id={_instanceId}) is using the specified name ({name}) now"); + } + _NameTable.Add(name, _instanceId); + } } return _nativeTexturePtr; } @@ -284,22 +303,6 @@ public static void OnReleaseTextureFrame(uint textureName, IntPtr syncTokenPtr) textureFrame.Release(_glSyncToken); } - private static void RegisterInstance(TextureFrame textureFrame) - { - var name = textureFrame.GetTextureName(); - var id = textureFrame._instanceId; - lock (((ICollection)_NameTable).SyncRoot) - { - if (AcquireName(name, id)) - { - _InstanceTable.Add(id, textureFrame); - _NameTable.Add(name, id); - return; - } - } - throw new ArgumentException("Another instance has the same name"); - } - /// /// Remove from if it's stale. /// If does not exist in , do nothing. @@ -328,18 +331,24 @@ private static TextureFormat GetTextureFormat(Texture texture) return GraphicsFormatUtility.GetTextureFormat(texture.graphicsFormat); } - private void ChangeNameFrom(uint oldName) + /// + /// Remove the texture name from and empty . + /// This method needs to be called when an operation is performed that may change the internal texture. + /// + private bool RevokeNativeTexturePtr() { - var newName = GetTextureName(); - lock (((ICollection)_NameTable).SyncRoot) + if (_nativeTexturePtr == IntPtr.Zero) { - if (!AcquireName(newName, _instanceId)) - { - throw new ArgumentException("Another instance is using the specified name now"); - } - var _ = _NameTable.Remove(oldName); - _NameTable.Add(newName, _instanceId); + return true; } + + var currentName = GetTextureName(); + if (!_NameTable.Remove(currentName)) + { + return false; + } + _nativeTexturePtr = IntPtr.Zero; + return true; } private Texture2D LoadToTextureBuffer(Texture texture)