using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using InterprocessLib;
using Microsoft.CodeAnalysis;
using Renderite.Shared;
using Renderite.Unity;
using ResoniteSpout.Shared;
using UnityEngine;
using UnityEngine.Rendering;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("ResoniteSpout.Renderer")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+700ffc21a6d0b02ec24d0b1bcaa5eb277bb74fb7")]
[assembly: AssemblyProduct("ResoniteSpout.Renderer")]
[assembly: AssemblyTitle("ResoniteSpout.Renderer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace ResoniteSpout.Shared
{
public enum SpoutCommandType
{
Create,
Delete,
Update,
ReceiverCreate,
ReceiverDelete,
ReceiverUpdate
}
public class SpoutCommand : RendererCommand
{
public SpoutCommandType Type;
public string SpoutName = "";
public int AssetId;
public override void Pack(ref MemoryPacker packer)
{
((MemoryPacker)(ref packer)).Write<SpoutCommandType>(Type);
((MemoryPacker)(ref packer)).Write<int>(AssetId);
((MemoryPacker)(ref packer)).Write(SpoutName);
}
public override void Unpack(ref MemoryUnpacker unpacker)
{
((MemoryUnpacker)(ref unpacker)).Read<SpoutCommandType>(ref Type);
((MemoryUnpacker)(ref unpacker)).Read<int>(ref AssetId);
((MemoryUnpacker)(ref unpacker)).Read(ref SpoutName);
}
}
}
namespace ResoniteSpoutRenderer
{
[BepInPlugin("zozokasu.ResoniteSpout.Renderer", "ResoniteSpoutRenderer", "0.2.0")]
public class ResoniteSpoutRenderer : BaseUnityPlugin
{
public class SpoutStruct
{
public string SpoutName;
public int AssetId;
public IntPtr SpoutSender;
public Texture2D SharedTexture;
public int InitializationAttempts;
public bool IsValid => SpoutSender != IntPtr.Zero;
public bool IsReady
{
get
{
if (IsValid)
{
return (Object)(object)SharedTexture != (Object)null;
}
return false;
}
}
public bool TryCreateSharedTexture()
{
InitializationAttempts++;
if (SpoutSender == IntPtr.Zero)
{
Log.LogError((object)("[" + SpoutName + "] Sender is null, cannot create shared texture"));
return false;
}
IntPtr intPtr = PluginEntry.Sender_GetTexturePointer(SpoutSender);
if (intPtr == IntPtr.Zero)
{
if (InitializationAttempts > 100)
{
Log.LogError((object)$"[{SpoutName}] Failed to get texture pointer after {InitializationAttempts} attempts");
return false;
}
return false;
}
int num = PluginEntry.Sender_GetTextureWidth(SpoutSender);
int num2 = PluginEntry.Sender_GetTextureHeight(SpoutSender);
SharedTexture = Texture2D.CreateExternalTexture(num, num2, (TextureFormat)5, false, false, intPtr);
((Object)SharedTexture).hideFlags = (HideFlags)52;
Log.LogInfo((object)$"[{SpoutName}] Created shared texture {num}x{num2} after {InitializationAttempts} attempts");
return true;
}
public void Dispose()
{
if (SpoutSender != IntPtr.Zero)
{
SpoutSender = IntPtr.Zero;
}
if ((Object)(object)SharedTexture != (Object)null)
{
Object.Destroy((Object)(object)SharedTexture);
SharedTexture = null;
}
Log.LogInfo((object)("[" + SpoutName + "] Disposed"));
}
}
public class SpoutReceiverStruct
{
public string SpoutName;
public int AssetId;
public IntPtr SpoutReceiver;
public Texture2D ReceivedTexture;
public int InitializationAttempts;
public bool IsValid => SpoutReceiver != IntPtr.Zero;
public bool IsReady
{
get
{
if (IsValid)
{
return (Object)(object)ReceivedTexture != (Object)null;
}
return false;
}
}
public bool TryCreateReceivedTexture()
{
InitializationAttempts++;
if (SpoutReceiver == IntPtr.Zero)
{
Log.LogError((object)("[Receiver:" + SpoutName + "] Receiver is null, cannot create texture"));
return false;
}
Util.IssueReceiverPluginEvent(PluginEntry.Event.Update, SpoutReceiver);
bool flag = PluginEntry.CheckValid(SpoutReceiver);
IntPtr intPtr = PluginEntry.Receiver_GetTexturePointer(SpoutReceiver);
if (intPtr == IntPtr.Zero)
{
if (InitializationAttempts == 100 || InitializationAttempts % 300 == 0)
{
Log.LogWarning((object)$"[Receiver:{SpoutName}] Still waiting for texture pointer (attempt {InitializationAttempts}, valid={flag})");
Log.LogWarning((object)("[Receiver:" + SpoutName + "] Make sure the Spout source '" + SpoutName + "' is actively sending"));
}
return false;
}
int textureWidth = PluginEntry.GetTextureWidth(SpoutReceiver);
int textureHeight = PluginEntry.GetTextureHeight(SpoutReceiver);
if (textureWidth <= 0 || textureHeight <= 0)
{
if (InitializationAttempts % 60 == 0)
{
Log.LogWarning((object)$"[Receiver:{SpoutName}] Invalid dimensions: {textureWidth}x{textureHeight}");
}
return false;
}
ReceivedTexture = Texture2D.CreateExternalTexture(textureWidth, textureHeight, (TextureFormat)63, false, false, intPtr);
((Object)ReceivedTexture).hideFlags = (HideFlags)52;
Log.LogInfo((object)$"[Receiver:{SpoutName}] Created received texture {textureWidth}x{textureHeight} after {InitializationAttempts} attempts");
return true;
}
public void UpdateReceivedTexture()
{
if (!(SpoutReceiver == IntPtr.Zero) && !((Object)(object)ReceivedTexture == (Object)null))
{
IntPtr intPtr = PluginEntry.Receiver_GetTexturePointer(SpoutReceiver);
if (intPtr != IntPtr.Zero)
{
ReceivedTexture.UpdateExternalTexture(intPtr);
}
}
}
public void Dispose()
{
if (SpoutReceiver != IntPtr.Zero)
{
SpoutReceiver = IntPtr.Zero;
}
if ((Object)(object)ReceivedTexture != (Object)null)
{
Object.Destroy((Object)(object)ReceivedTexture);
ReceivedTexture = null;
}
Log.LogInfo((object)("[Receiver:" + SpoutName + "] Disposed"));
}
}
public static ManualLogSource Log;
private Messenger _msg;
private readonly ConcurrentQueue<Action> _mainQueue = new ConcurrentQueue<Action>();
private static Dictionary<string, SpoutStruct> spouts = new Dictionary<string, SpoutStruct>();
private static Dictionary<string, SpoutReceiverStruct> receivers = new Dictionary<string, SpoutReceiverStruct>();
private void Awake()
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Expected O, but got Unknown
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
_msg = new Messenger("Zozokasu.ResoniteSpout", new List<Type>(1) { typeof(SpoutCommand) }, (List<Type>)null);
_msg.ReceiveObject<SpoutCommand>("SpoutCommand", (Action<SpoutCommand>)delegate(SpoutCommand command)
{
SpoutCommand command2 = command;
_mainQueue.Enqueue(delegate
{
ProcessCommand(command2);
});
Log.LogInfo((object)$"Command received: {command2.Type}, Name: '{command2.SpoutName}', AssetId: {command2.AssetId}");
});
_msg.ReceiveString("DbgMessage", (Action<string>)delegate(string? s)
{
Log.LogInfo((object)("[DEBUG]: " + s));
});
Log.LogInfo((object)$"[ResoniteSpoutRenderer] Initialized. Graphics: {SystemInfo.graphicsDeviceType}");
}
private void Update()
{
Action result;
while (_mainQueue.TryDequeue(out result))
{
try
{
result();
}
catch (Exception arg)
{
Log.LogError((object)$"Error processing command: {arg}");
}
}
SendRenderTextures();
ReceiveToRenderTextures();
}
private void OnDestroy()
{
foreach (SpoutStruct value in spouts.Values)
{
value.Dispose();
}
spouts.Clear();
foreach (SpoutReceiverStruct value2 in receivers.Values)
{
value2.Dispose();
}
receivers.Clear();
}
private void ProcessCommand(SpoutCommand command)
{
switch (command.Type)
{
case SpoutCommandType.Create:
CreateSpout(command.SpoutName, command.AssetId);
break;
case SpoutCommandType.Update:
UpdateSpout(command.SpoutName, command.AssetId);
break;
case SpoutCommandType.Delete:
DeleteSpout(command.SpoutName);
break;
case SpoutCommandType.ReceiverCreate:
CreateReceiver(command.SpoutName, command.AssetId);
break;
case SpoutCommandType.ReceiverUpdate:
UpdateReceiver(command.SpoutName, command.AssetId);
break;
case SpoutCommandType.ReceiverDelete:
DeleteReceiver(command.SpoutName);
break;
}
}
private void CreateSpout(string spoutName, int assetId)
{
Log.LogInfo((object)$"[{spoutName}] CreateSpout called with AssetId: {assetId}");
if (spouts.ContainsKey(spoutName))
{
Log.LogInfo((object)("[" + spoutName + "] Already exists, recreating..."));
spouts[spoutName].Dispose();
spouts.Remove(spoutName);
}
RenderTextureAsset asset = RenderingManager.Instance.RenderTextures.GetAsset(assetId);
if ((Object)(object)((asset != null) ? asset.Texture : null) == (Object)null)
{
Log.LogError((object)$"[{spoutName}] RenderTexture not found for AssetId: {assetId}");
return;
}
RenderTexture texture = asset.Texture;
Log.LogInfo((object)$"[{spoutName}] RenderTexture found: {((Texture)texture).width}x{((Texture)texture).height}");
Log.LogInfo((object)$"[{spoutName}] Calling CreateSender('{spoutName}', {((Texture)texture).width}, {((Texture)texture).height})...");
IntPtr intPtr;
try
{
intPtr = PluginEntry.CreateSender(spoutName, ((Texture)texture).width, ((Texture)texture).height);
}
catch (Exception arg)
{
Log.LogError((object)$"[{spoutName}] CreateSender threw exception: {arg}");
return;
}
if (intPtr == IntPtr.Zero)
{
Log.LogError((object)("[" + spoutName + "] Failed to create Spout sender (returned IntPtr.Zero)"));
return;
}
Log.LogInfo((object)$"[{spoutName}] Spout sender created: {intPtr}");
Util.IssueSenderPluginEvent(PluginEntry.Event.Update, intPtr);
SpoutStruct value = new SpoutStruct
{
SpoutName = spoutName,
AssetId = assetId,
SpoutSender = intPtr,
InitializationAttempts = 0
};
spouts[spoutName] = value;
Log.LogInfo((object)$"[{spoutName}] Added to spouts dictionary. Total spouts: {spouts.Count}");
}
private void UpdateSpout(string spoutName, int assetId)
{
if (!spouts.ContainsKey(spoutName))
{
Log.LogWarning((object)("[" + spoutName + "] Not found for update, creating new..."));
CreateSpout(spoutName, assetId);
return;
}
SpoutStruct spoutStruct = spouts[spoutName];
if (spoutStruct.AssetId == assetId)
{
Log.LogInfo((object)$"[{spoutName}] AssetId unchanged ({assetId}), skipping update");
return;
}
Log.LogInfo((object)$"[{spoutName}] Updating: AssetId {spoutStruct.AssetId} → {assetId}");
CreateSpout(spoutName, assetId);
}
private void DeleteSpout(string spoutName)
{
if (spouts.ContainsKey(spoutName))
{
spouts[spoutName].Dispose();
spouts.Remove(spoutName);
Log.LogInfo((object)$"[{spoutName}] Deleted. Remaining spouts: {spouts.Count}");
}
else
{
Log.LogWarning((object)("[" + spoutName + "] Not found for deletion"));
}
}
private void CreateReceiver(string spoutName, int assetId)
{
Log.LogInfo((object)$"[Receiver:{spoutName}] CreateReceiver called with AssetId: {assetId}");
ScanAndLogAvailableSpoutSources();
if (receivers.ContainsKey(spoutName))
{
Log.LogInfo((object)("[Receiver:" + spoutName + "] Already exists, recreating..."));
receivers[spoutName].Dispose();
receivers.Remove(spoutName);
}
IntPtr intPtr = PluginEntry.CreateReceiver(spoutName);
if (intPtr == IntPtr.Zero)
{
Log.LogError((object)("[Receiver:" + spoutName + "] Failed to create Spout receiver"));
return;
}
Log.LogInfo((object)$"[Receiver:{spoutName}] Spout receiver created: {intPtr}");
Util.IssueReceiverPluginEvent(PluginEntry.Event.Update, intPtr);
SpoutReceiverStruct value = new SpoutReceiverStruct
{
SpoutName = spoutName,
AssetId = assetId,
SpoutReceiver = intPtr,
InitializationAttempts = 0
};
receivers[spoutName] = value;
Log.LogInfo((object)$"[Receiver:{spoutName}] Added to receivers dictionary. Total receivers: {receivers.Count}");
}
private void ScanAndLogAvailableSpoutSources()
{
int num = PluginEntry.ScanSharedObjects();
Log.LogInfo((object)$"[Spout] Found {num} available Spout sources:");
for (int i = 0; i < num; i++)
{
string sharedObjectNameString = PluginEntry.GetSharedObjectNameString(i);
Log.LogInfo((object)$" [{i}] '{sharedObjectNameString}'");
}
}
private void UpdateReceiver(string spoutName, int assetId)
{
if (!receivers.ContainsKey(spoutName))
{
Log.LogWarning((object)("[Receiver:" + spoutName + "] Not found for update, creating new..."));
CreateReceiver(spoutName, assetId);
return;
}
SpoutReceiverStruct spoutReceiverStruct = receivers[spoutName];
if (spoutReceiverStruct.AssetId == assetId)
{
Log.LogInfo((object)$"[Receiver:{spoutName}] AssetId unchanged ({assetId}), skipping update");
return;
}
Log.LogInfo((object)$"[Receiver:{spoutName}] Updating: AssetId {spoutReceiverStruct.AssetId} → {assetId}");
spoutReceiverStruct.AssetId = assetId;
}
private void DeleteReceiver(string spoutName)
{
if (receivers.ContainsKey(spoutName))
{
receivers[spoutName].Dispose();
receivers.Remove(spoutName);
Log.LogInfo((object)$"[Receiver:{spoutName}] Deleted. Remaining receivers: {receivers.Count}");
}
else
{
Log.LogWarning((object)("[Receiver:" + spoutName + "] Not found for deletion"));
}
}
private void SendRenderTextures()
{
//IL_0127: Unknown result type (might be due to invalid IL or missing references)
//IL_0136: Unknown result type (might be due to invalid IL or missing references)
if (spouts.Count == 0)
{
return;
}
foreach (KeyValuePair<string, SpoutStruct> spout in spouts)
{
string key = spout.Key;
SpoutStruct value = spout.Value;
try
{
if (!value.IsValid)
{
continue;
}
RenderTextureAsset asset = RenderingManager.Instance.RenderTextures.GetAsset(value.AssetId);
if ((Object)(object)((asset != null) ? asset.Texture : null) == (Object)null)
{
if (value.InitializationAttempts == 1)
{
Log.LogWarning((object)$"[{key}] RenderTexture not available for AssetId: {value.AssetId}");
}
continue;
}
Util.IssueSenderPluginEvent(PluginEntry.Event.Update, value.SpoutSender);
if (!((Object)(object)value.SharedTexture == (Object)null))
{
goto IL_00f5;
}
if (value.InitializationAttempts < 5 || value.InitializationAttempts % 60 == 0)
{
Log.LogInfo((object)$"[{key}] Attempting to create shared texture (attempt {value.InitializationAttempts})...");
}
if (value.TryCreateSharedTexture())
{
goto IL_00f5;
}
goto end_IL_0035;
IL_00f5:
RenderTexture texture = asset.Texture;
RenderTexture temporary = RenderTexture.GetTemporary(((Texture)value.SharedTexture).width, ((Texture)value.SharedTexture).height, 0, (RenderTextureFormat)0);
Graphics.Blit((Texture)(object)texture, temporary, new Vector2(1f, -1f), new Vector2(0f, 1f));
Graphics.CopyTexture((Texture)(object)temporary, (Texture)(object)value.SharedTexture);
RenderTexture.ReleaseTemporary(temporary);
end_IL_0035:;
}
catch (Exception arg)
{
Log.LogError((object)$"[{key}] Error sending texture: {arg}");
}
}
}
private void ReceiveToRenderTextures()
{
//IL_0116: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Unknown result type (might be due to invalid IL or missing references)
if (receivers.Count == 0)
{
return;
}
foreach (KeyValuePair<string, SpoutReceiverStruct> receiver in receivers)
{
string key = receiver.Key;
SpoutReceiverStruct value = receiver.Value;
try
{
if (value.IsValid)
{
Util.IssueReceiverPluginEvent(PluginEntry.Event.Update, value.SpoutReceiver);
if (!((Object)(object)value.ReceivedTexture == (Object)null))
{
value.UpdateReceivedTexture();
goto IL_00a3;
}
if (value.InitializationAttempts < 5 || value.InitializationAttempts % 60 == 0)
{
Log.LogInfo((object)$"[Receiver:{key}] Attempting to create received texture (attempt {value.InitializationAttempts})...");
}
if (value.TryCreateReceivedTexture())
{
goto IL_00a3;
}
}
goto end_IL_0035;
IL_00a3:
RenderTextureAsset asset = RenderingManager.Instance.RenderTextures.GetAsset(value.AssetId);
if ((Object)(object)((asset != null) ? asset.Texture : null) == (Object)null)
{
if (value.InitializationAttempts == 1)
{
Log.LogWarning((object)$"[Receiver:{key}] Target RenderTexture not available for AssetId: {value.AssetId}");
}
}
else
{
RenderTexture texture = asset.Texture;
Graphics.Blit((Texture)(object)value.ReceivedTexture, texture, new Vector2(1f, -1f), new Vector2(0f, 1f));
}
end_IL_0035:;
}
catch (Exception arg)
{
Log.LogError((object)$"[Receiver:{key}] Error receiving texture: {arg}");
}
}
}
}
internal static class PluginEntry
{
internal enum Event
{
Update,
Dispose
}
internal static bool IsAvailable => (int)SystemInfo.graphicsDeviceType == 2;
[DllImport("KlakSpout_send.dll", EntryPoint = "GetRenderEventFunc")]
internal static extern IntPtr Sender_GetRenderEventFunc();
[DllImport("KlakSpout_send.dll")]
internal static extern IntPtr CreateSender(string name, int width, int height);
[DllImport("KlakSpout_send.dll", EntryPoint = "GetTexturePointer")]
internal static extern IntPtr Sender_GetTexturePointer(IntPtr ptr);
[DllImport("KlakSpout_send.dll", EntryPoint = "GetTextureWidth")]
internal static extern int Sender_GetTextureWidth(IntPtr ptr);
[DllImport("KlakSpout_send.dll", EntryPoint = "GetTextureHeight")]
internal static extern int Sender_GetTextureHeight(IntPtr ptr);
[DllImport("KlakSpout.dll", EntryPoint = "GetRenderEventFunc")]
internal static extern IntPtr Receiver_GetRenderEventFunc();
[DllImport("KlakSpout.dll")]
internal static extern IntPtr CreateReceiver(string name);
[DllImport("KlakSpout.dll", EntryPoint = "GetTexturePointer")]
internal static extern IntPtr Receiver_GetTexturePointer(IntPtr ptr);
[DllImport("KlakSpout.dll")]
internal static extern int GetTextureWidth(IntPtr ptr);
[DllImport("KlakSpout.dll")]
internal static extern int GetTextureHeight(IntPtr ptr);
[DllImport("KlakSpout.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool CheckValid(IntPtr ptr);
[DllImport("KlakSpout.dll")]
internal static extern int ScanSharedObjects();
[DllImport("KlakSpout.dll")]
internal static extern IntPtr GetSharedObjectName(int index);
internal static string GetSharedObjectNameString(int index)
{
IntPtr sharedObjectName = GetSharedObjectName(index);
if (!(sharedObjectName != IntPtr.Zero))
{
return null;
}
return Marshal.PtrToStringAnsi(sharedObjectName);
}
}
internal static class Util
{
private static CommandBuffer _senderCommandBuffer;
private static CommandBuffer _receiverCommandBuffer;
internal static void Destroy(Object obj)
{
if (!(obj == (Object)null))
{
if (Application.isPlaying)
{
Object.Destroy(obj);
}
else
{
Object.DestroyImmediate(obj);
}
}
}
internal static void IssueSenderPluginEvent(PluginEntry.Event pluginEvent, IntPtr ptr)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
if (_senderCommandBuffer == null)
{
_senderCommandBuffer = new CommandBuffer();
}
_senderCommandBuffer.IssuePluginEventAndData(PluginEntry.Sender_GetRenderEventFunc(), (int)pluginEvent, ptr);
Graphics.ExecuteCommandBuffer(_senderCommandBuffer);
_senderCommandBuffer.Clear();
}
internal static void IssueReceiverPluginEvent(PluginEntry.Event pluginEvent, IntPtr ptr)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
if (_receiverCommandBuffer == null)
{
_receiverCommandBuffer = new CommandBuffer();
}
_receiverCommandBuffer.IssuePluginEventAndData(PluginEntry.Receiver_GetRenderEventFunc(), (int)pluginEvent, ptr);
Graphics.ExecuteCommandBuffer(_receiverCommandBuffer);
_receiverCommandBuffer.Clear();
}
}
}