-
-
Notifications
You must be signed in to change notification settings - Fork 484
/
Copy pathGpuManager.cs
148 lines (127 loc) · 4.03 KB
/
GpuManager.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// Copyright (c) 2021 homuler
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Rendering;
#if UNITY_ANDROID
using System.Runtime.InteropServices;
#endif
namespace Mediapipe.Unity
{
public static class GpuManager
{
private const string _TAG = nameof(GpuManager);
private delegate void PluginCallback(int eventId);
private static readonly object _SetupLock = new object();
#pragma warning disable IDE0044
private static IntPtr _CurrentContext = IntPtr.Zero;
#pragma warning restore IDE0044
private static bool _IsContextInitialized = false;
public static GpuResources GpuResources { get; private set; }
public static GlCalculatorHelper GlCalculatorHelper { get; private set; }
public static bool IsInitialized { get; private set; }
/// <summary>
/// Initialize GPU resources.
/// If it finishes successfully, <see cref="IsInitialized" /> will be set to <c>true</c>.
/// </summary>
/// <remarks>
/// If <see cref="IsInitialized" /> is <c>true</c>, it will do nothing.
/// Before the application exits, don't forget to call <see cref="Shutdown" />.
/// </remarks>
public static IEnumerator Initialize()
{
lock (_SetupLock)
{
if (IsInitialized)
{
Logger.LogInfo(_TAG, "Already initialized");
yield break;
}
#if UNITY_ANDROID
_IsContextInitialized = SystemInfo.graphicsDeviceType != GraphicsDeviceType.OpenGLES3;
if (!_IsContextInitialized)
{
PluginCallback callback = GetCurrentContext;
var fp = Marshal.GetFunctionPointerForDelegate(callback);
GL.IssuePluginEvent(fp, 1);
}
#else
_IsContextInitialized = true;
#endif
var count = 100;
yield return new WaitUntil(() =>
{
return --count < 0 || _IsContextInitialized;
});
if (!_IsContextInitialized)
{
Logger.LogError(_TAG, "Failed to get GlContext");
yield break;
}
#if UNITY_ANDROID
if (_CurrentContext == IntPtr.Zero)
{
Logger.LogWarning(_TAG, "EGL context is not found, so MediaPipe won't share their EGL contexts with Unity");
}
else
{
Logger.LogVerbose(_TAG, $"EGL context is found: {_CurrentContext}");
}
#endif
try
{
Logger.LogInfo(_TAG, "Initializing GpuResources...");
var statusOrGpuResources = GpuResources.Create(_CurrentContext);
statusOrGpuResources.status.AssertOk();
GpuResources = statusOrGpuResources.Value();
Logger.LogInfo(_TAG, "Initializing GlCalculatorHelper...");
GlCalculatorHelper = new GlCalculatorHelper();
GlCalculatorHelper.InitializeForTest(GpuResources);
IsInitialized = true;
}
catch (EntryPointNotFoundException e)
{
Logger.LogException(e);
Logger.LogError(_TAG, "Failed to create GpuResources. Did you build libraries with GPU enabled?");
}
catch (Exception e)
{
Logger.LogException(e);
}
}
}
/// <summary>
/// Dispose GPU resources.
/// </summary>
/// <remarks>
/// This has to be called before the application exits.
/// Otherwise, UnityEditor can freeze.
/// </remarks>
public static void Shutdown()
{
if (GpuResources != null)
{
GpuResources.Dispose();
GpuResources = null;
}
if (GlCalculatorHelper != null)
{
GlCalculatorHelper.Dispose();
GlCalculatorHelper = null;
}
IsInitialized = false;
}
// Currently, it works only on Android
#if UNITY_ANDROID
[AOT.MonoPInvokeCallback(typeof(PluginCallback))]
private static void GetCurrentContext(int eventId) {
_CurrentContext = Egl.GetCurrentContext();
_IsContextInitialized = true;
}
#endif
}
}