Skip to content

Commit 40d1ffd

Browse files
committed
refactor: use AsyncGlContext.Request to get GlContext
1 parent fd15462 commit 40d1ffd

File tree

3 files changed

+120
-52
lines changed

3 files changed

+120
-52
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Copyright (c) 2021 homuler
2+
//
3+
// Use of this source code is governed by an MIT-style
4+
// license that can be found in the LICENSE file or at
5+
// https://opensource.org/licenses/MIT.
6+
7+
using System;
8+
using System.Runtime.InteropServices;
9+
using System.Threading;
10+
using UnityEngine;
11+
12+
namespace Mediapipe.Unity
13+
{
14+
public static class AsyncGlContext
15+
{
16+
public static AsyncGlContextRequest Request(Action<AsyncGlContextRequest> callback) => new AsyncGlContextRequest(callback);
17+
}
18+
19+
public class AsyncGlContextRequest
20+
{
21+
private static int _Counter = 0;
22+
private static readonly GlobalInstanceTable<int, AsyncGlContextRequest> _InstanceTable = new GlobalInstanceTable<int, AsyncGlContextRequest>(5);
23+
24+
private delegate void GLEventCallback(int eventId);
25+
26+
private readonly int _id;
27+
private readonly Action<AsyncGlContextRequest> _callback;
28+
29+
public IntPtr platformGlContext { get; private set; }
30+
public bool done { get; private set; }
31+
public Exception error { get; private set; }
32+
33+
internal AsyncGlContextRequest(Action<AsyncGlContextRequest> callback)
34+
{
35+
_id = Interlocked.Increment(ref _Counter);
36+
_callback = callback;
37+
_InstanceTable.Add(_id, this);
38+
39+
GLEventCallback gLEventCallback = PluginCallback;
40+
var fp = Marshal.GetFunctionPointerForDelegate(gLEventCallback);
41+
42+
GL.IssuePluginEvent(fp, _id);
43+
}
44+
45+
[AOT.MonoPInvokeCallback(typeof(GLEventCallback))]
46+
private static void PluginCallback(int eventId)
47+
{
48+
if (!_InstanceTable.TryGetValue(eventId, out var request))
49+
{
50+
Logger.LogWarning($"AsyncGlContextRequest with id {eventId} is not found, maybe already GCed");
51+
return;
52+
}
53+
54+
try
55+
{
56+
#if UNITY_ANDROID
57+
// Currently, it works only on Android
58+
request.platformGlContext = Egl.GetCurrentContext();
59+
#endif
60+
61+
request._callback?.Invoke(request);
62+
}
63+
catch (Exception e)
64+
{
65+
request.error = e;
66+
}
67+
finally
68+
{
69+
request.done = true;
70+
_InstanceTable.Remove(eventId);
71+
}
72+
}
73+
}
74+
}

Packages/com.github.homuler.mediapipe/Runtime/Scripts/Unity/AsyncGlContext.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Packages/com.github.homuler.mediapipe/Runtime/Scripts/Unity/GpuManager.cs

Lines changed: 35 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@
99
using UnityEngine;
1010
using UnityEngine.Rendering;
1111

12-
#if UNITY_ANDROID
13-
using System.Runtime.InteropServices;
14-
#endif
15-
1612
namespace Mediapipe.Unity
1713
{
1814
public static class GpuManager
@@ -22,10 +18,7 @@ public static class GpuManager
2218
private delegate void PluginCallback(int eventId);
2319

2420
private static readonly object _SetupLock = new object();
25-
#pragma warning disable IDE0044
26-
private static IntPtr _CurrentContext = IntPtr.Zero;
27-
#pragma warning restore IDE0044
28-
private static bool _IsContextInitialized = false;
21+
private static IntPtr _PlatformGlContext = IntPtr.Zero;
2922

3023
public static GpuResources GpuResources { get; private set; }
3124
public static GlCalculatorHelper GlCalculatorHelper { get; private set; }
@@ -50,48 +43,21 @@ public static IEnumerator Initialize()
5043
yield break;
5144
}
5245

53-
#if UNITY_ANDROID
54-
_IsContextInitialized = SystemInfo.graphicsDeviceType != GraphicsDeviceType.OpenGLES3;
55-
if (!_IsContextInitialized)
56-
{
57-
PluginCallback callback = GetCurrentContext;
58-
59-
var fp = Marshal.GetFunctionPointerForDelegate(callback);
60-
GL.IssuePluginEvent(fp, 1);
61-
}
62-
#else
63-
_IsContextInitialized = true;
64-
#endif
65-
66-
var count = 100;
67-
yield return new WaitUntil(() =>
68-
{
69-
return --count < 0 || _IsContextInitialized;
70-
});
71-
72-
if (!_IsContextInitialized)
73-
{
74-
Logger.LogError(_TAG, "Failed to get GlContext");
75-
yield break;
76-
}
77-
78-
#if UNITY_ANDROID
79-
if (_CurrentContext == IntPtr.Zero)
80-
{
81-
Logger.LogWarning(_TAG, "EGL context is not found, so MediaPipe won't share their EGL contexts with Unity");
82-
}
83-
else
46+
if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.OpenGLES3)
8447
{
85-
Logger.LogVerbose(_TAG, $"EGL context is found: {_CurrentContext}");
48+
var req = AsyncGlContext.Request(OnGetEglContext);
49+
yield return new WaitUntil(() => req.done);
50+
51+
if (req.error != null)
52+
{
53+
Logger.LogException(req.error);
54+
yield break;
55+
}
8656
}
87-
#endif
8857

8958
try
9059
{
91-
Logger.LogInfo(_TAG, "Initializing GpuResources...");
92-
GpuResources = GpuResources.Create(_CurrentContext);
93-
94-
Logger.LogInfo(_TAG, "Initializing GlCalculatorHelper...");
60+
GpuResources = GpuResources.Create(_PlatformGlContext);
9561
GlCalculatorHelper = new GlCalculatorHelper();
9662
GlCalculatorHelper.InitializeForTest(GpuResources);
9763

@@ -133,13 +99,30 @@ public static void Shutdown()
13399
IsInitialized = false;
134100
}
135101

136-
// Currently, it works only on Android
137-
#if UNITY_ANDROID
138-
[AOT.MonoPInvokeCallback(typeof(PluginCallback))]
139-
private static void GetCurrentContext(int eventId) {
140-
_CurrentContext = Egl.GetCurrentContext();
141-
_IsContextInitialized = true;
102+
public static void ResetGpuResources(IntPtr platformGlContext)
103+
{
104+
if (!IsInitialized)
105+
{
106+
throw new InvalidOperationException("GpuManager is not initialized");
107+
}
108+
GpuResources?.Dispose();
109+
110+
GpuResources = new GpuResources(platformGlContext);
111+
GlCalculatorHelper.InitializeForTest(GpuResources);
112+
}
113+
114+
public static GlContext GetGlContext() => GlCalculatorHelper?.GetGlContext();
115+
116+
private static void OnGetEglContext(AsyncGlContextRequest request)
117+
{
118+
if (request.platformGlContext == IntPtr.Zero)
119+
{
120+
Logger.LogWarning(_TAG, "EGL context is not found, so MediaPipe won't share their EGL contexts with Unity");
121+
return;
122+
}
123+
Logger.LogVerbose(_TAG, $"EGL context is found: {request.platformGlContext}");
124+
125+
_PlatformGlContext = request.platformGlContext;
142126
}
143-
#endif
144127
}
145128
}

0 commit comments

Comments
 (0)