Fixed Main Thread freezing on heavy tasks

- Main thread unfreezing solution-TaskCompletionSource added in RpcTest.cs
 - Updated BlendShaderController to hold TaskCompletionSource
This commit is contained in:
Max Barashev 2026-05-20 14:31:23 +03:00
parent 55b7639cd8
commit f863b8b6ca
3 changed files with 79 additions and 29 deletions

View File

@ -1569,6 +1569,7 @@ GameObject:
m_Component: m_Component:
- component: {fileID: 763126626} - component: {fileID: 763126626}
- component: {fileID: 763126625} - component: {fileID: 763126625}
- component: {fileID: 763126627}
m_Layer: 0 m_Layer: 0
m_Name: Blending m_Name: Blending
m_TagString: Untagged m_TagString: Untagged
@ -1593,7 +1594,7 @@ MonoBehaviour:
BlendShader: {fileID: 7200000, guid: 5bf2857e309eda648b826d75af82d1ab, type: 3} BlendShader: {fileID: 7200000, guid: 5bf2857e309eda648b826d75af82d1ab, type: 3}
camera1: {fileID: 146129744} camera1: {fileID: 146129744}
camera2: {fileID: 73635654} camera2: {fileID: 73635654}
QuadResolution: 256 QuadResolution: 1024
Multiplier: 2 Multiplier: 2
Reciever: {fileID: 2021891225} Reciever: {fileID: 2021891225}
OffsetMultiplier: 400 OffsetMultiplier: 400
@ -1613,6 +1614,18 @@ Transform:
m_Children: [] m_Children: []
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &763126627
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 763126624}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c61b6ef6bca767e42a8ec8ea380a4ac6, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1 &858903265 --- !u!1 &858903265
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

View File

@ -11,6 +11,14 @@ using UnityEngine.UI;
public class BlendShaderController : MonoBehaviour public class BlendShaderController : MonoBehaviour
{ {
private static int tex1Prop = Shader.PropertyToID("Camera1");
private static int tex2Prop = Shader.PropertyToID("Camera2");
private static int texResProp = Shader.PropertyToID("Result");
private static int offsetProp = Shader.PropertyToID("Offset");
private static int resXProp = Shader.PropertyToID("ResX");
private static int farClipPlaneProp = Shader.PropertyToID("FarClipPlane");
private static int monoChanelResProp = Shader.PropertyToID("MonoChannelResult");
private static string savePath = Application.streamingAssetsPath + '\\'; private static string savePath = Application.streamingAssetsPath + '\\';
private const string filename = "dsitMap"; private const string filename = "dsitMap";
private const string ext = ".txt"; private const string ext = ".txt";
@ -118,36 +126,25 @@ public class BlendShaderController : MonoBehaviour
UpdateShader(cameraTexture1, cameraTexture2); UpdateShader(cameraTexture1, cameraTexture2);
if(Input.GetKeyDown(KeyCode.S)) if(Input.GetKeyDown(KeyCode.S))
{
SaveTextureAsync();
}
if (Input.GetKeyDown(KeyCode.A))
{ {
SaveTexture(); SaveTexture();
} }
if (Input.GetKeyDown(KeyCode.J))
{
Debug.Log(GetDistanceByDepth());
}
if (Input.GetKeyDown(KeyCode.K))
{
Debug.Log(GetDistanceByRayCast());
}
if (Input.GetKeyDown(KeyCode.T))
{
camera1.targetTexture = test;
camera1.RenderWithShader(DepthShader, "fragment");
camera1.targetTexture = cameraTexture1;
}
} }
void UpdateShader(RenderTexture tex1, RenderTexture tex2) void UpdateShader(RenderTexture tex1, RenderTexture tex2)
{ {
BlendShader.SetTexture(0, "Camera1", tex1); BlendShader.SetTexture(0, tex1Prop, tex1);
BlendShader.SetTexture(0, "Camera2", tex2); BlendShader.SetTexture(0, tex2Prop, tex2);
BlendShader.SetTexture(0, "Result", Result); BlendShader.SetTexture(0, texResProp, Result);
BlendShader.SetFloat(Shader.PropertyToID("Offset"), uvOffset); BlendShader.SetFloat(offsetProp, uvOffset);
BlendShader.SetFloat(Shader.PropertyToID("ResX"), Result.width); BlendShader.SetFloat(resXProp, Result.width);
BlendShader.SetBuffer(0, "MonoChannelResult", computeBuffer); BlendShader.SetFloat(farClipPlaneProp, camera1.farClipPlane);
//BlendShader.SetTexture(0, "Test", test); BlendShader.SetBuffer(0, monoChanelResProp, computeBuffer);
BlendShader.Dispatch(0, Result.width / 8, Result.height / 8, 1); BlendShader.Dispatch(0, Result.width / 8, Result.height / 8, 1);
} }
@ -198,7 +195,7 @@ public class BlendShaderController : MonoBehaviour
SwapRenderTargets(); SwapRenderTargets();
} }
private async void SaveTexture() public async void SaveTextureAsync(TaskCompletionSource<bool> tcs = null)
{ {
Debug.Log("Start Saving"); Debug.Log("Start Saving");
resultArray = new float[currentRes * currentRes]; resultArray = new float[currentRes * currentRes];
@ -206,26 +203,54 @@ public class BlendShaderController : MonoBehaviour
Debug.Log("Data copied"); Debug.Log("Data copied");
task1 = Task.Run(() => SerializeArray()); task1 = Task.Run(() => SerializeArray());
await task1; await task1;
Debug.Log("After awaiting");
string result = task1.Result; string result = task1.Result;
task2 = SavingProcessAsync(result); task2 = SavingProcessAsync(result);
await task2; await task2;
Debug.Log("After saving");
if (tcs != null) tcs.SetResult(true);
Debug.Log("Saving finished");
}
public void SaveTexture()
{
resultArray = new float[currentRes * currentRes];
computeBuffer.GetData(resultArray);
string result = SerializeArray();
Save(result);
}
public void GetDistArray()
{
} }
private async Task SavingProcessAsync(string data) private async Task SavingProcessAsync(string data)
{ {
int filesCount = Directory.EnumerateFiles(savePath, filename + '*' + ext).Count(); int filesCount = Directory.EnumerateFiles(savePath, filename + '*' + ext).Count();
Debug.Log("Start saving");
await File.WriteAllTextAsync(savePath + filename + filesCount.ToString() + ext, data); await File.WriteAllTextAsync(savePath + filename + filesCount.ToString() + ext, data);
Debug.Log("File saved"); Debug.Log("File saved");
} }
private void Save(string data)
{
int filesCount = Directory.EnumerateFiles(savePath, filename + '*' + ext).Count();
File.WriteAllText(savePath + filename + filesCount.ToString() + ext, data);
Debug.Log("File saved");
}
private string SerializeArray() private string SerializeArray()
{ {
string result = string.Empty; string result = string.Empty;
Debug.Log("StartSerializing");
for (int i = 0; i < resultArray.Length; i += currentRes) for (int i = 0; i < resultArray.Length; i += currentRes)
{ {
result += string.Join(", ", resultArray[i..(i + currentRes)]) + '\n'; result += string.Join(", ", resultArray[i..(i + currentRes)]) + '\n';
} }
Debug.Log("EndSerializing");
return result; return result;
} }

View File

@ -5,21 +5,26 @@ using System.Threading.Tasks;
using UnityEngine; using UnityEngine;
using CloudPointRpc; using CloudPointRpc;
using System.Runtime.CompilerServices;
public class RpcTest : MonoBehaviour public class RpcTest : MonoBehaviour
{ {
private static Queue<Task> _callbackTasks = new Queue<Task>(); private static Queue<Task> _callbackTasks = new Queue<Task>();
private static BlendShaderController controller;
[AOT.MonoPInvokeCallback(typeof(CrpcTestApi.RpcStringCallback))] [AOT.MonoPInvokeCallback(typeof(CrpcTestApi.RpcStringCallback))]
public static IntPtr RpcStringCallback(IntPtr rpcString) public static IntPtr RpcStringCallback(IntPtr rpcString)
{ {
Debug.Log("smth recieved");
var rpc = new RpcString(rpcString); var rpc = new RpcString(rpcString);
var message = rpc.Data; var message = rpc.Data;
rpc.Dispose(); rpc.Dispose();
var tcs = new TaskCompletionSource<bool>();
var task = new Task(() => Debug.Log($"[RpcTest] Callback received: {message}")); var task = new Task(async () => {
Debug.Log($"[RpcTest] Callback received: {message}");
controller.SaveTextureAsync(tcs);
Debug.Log("After Saving inside task");
});
lock (_callbackTasks) lock (_callbackTasks)
{ {
@ -27,12 +32,15 @@ public class RpcTest : MonoBehaviour
} }
task.Wait(); task.Wait();
tcs.Task.Wait();
var responce = new RpcString("1"); var responce = new RpcString("1");
Debug.Log("Finished");
return responce.Handle; return responce.Handle;
} }
void Start() void Start()
{ {
controller = FindFirstObjectByType<BlendShaderController>();
CrpcTestApi.crpc_test_init(); CrpcTestApi.crpc_test_init();
CrpcTestExtensions.CrpcTestAddMethod(RpcStringCallback, "test_method"); CrpcTestExtensions.CrpcTestAddMethod(RpcStringCallback, "test_method");
Debug.Log("[RpcTest] Initialized and method added"); Debug.Log("[RpcTest] Initialized and method added");
@ -45,18 +53,22 @@ public class RpcTest : MonoBehaviour
while (_callbackTasks.Count > 0) while (_callbackTasks.Count > 0)
{ {
var task = _callbackTasks.Dequeue(); var task = _callbackTasks.Dequeue();
task.Start(); task.RunSynchronously();
Debug.Log("Update");
} }
} }
} }
private void OnDestroy() private void OnDestroy()
{ {
Debug.Log("Call deinit1");
lock (_callbackTasks) lock (_callbackTasks)
{ {
Debug.Log("Call deinit2");
_callbackTasks.Clear(); _callbackTasks.Clear();
} }
Debug.Log("Call deinit finnaly");
CrpcTestApi.crpc_test_deinit(); CrpcTestApi.crpc_test_deinit();
} }
} }