1 #include "EXGLContextManager.h"
2 
3 namespace expo {
4 namespace gl_cpp {
5 
6 struct ContextState {
7   EXGLContext *ctx;
8   std::shared_mutex mutex;
9 };
10 
11 struct ContextManager {
12   std::unordered_map<EXGLContextId, ContextState> contextMap;
13   std::mutex contextLookupMutex;
14   EXGLContextId nextId = 1;
15 };
16 
17 ContextManager manager;
18 
19 ContextWithLock ContextGet(EXGLContextId id) {
20   std::lock_guard lock(manager.contextLookupMutex);
21   auto iter = manager.contextMap.find(id);
22   // if ctx is null then destroy is in progress
23   if (iter == manager.contextMap.end() || iter->second.ctx == nullptr) {
24     return {nullptr, std::shared_lock<std::shared_mutex>()};
25   }
26   return {iter->second.ctx, std::shared_lock(iter->second.mutex)};
27 }
28 
29 EXGLContextId ContextCreate() {
30   // Out of ids?
31   if (manager.nextId >= std::numeric_limits<EXGLContextId>::max()) {
32     EXGLSysLog("Ran out of EXGLContext ids!");
33     return 0;
34   }
35 
36   std::lock_guard<std::mutex> lock(manager.contextLookupMutex);
37   EXGLContextId ctxId = manager.nextId++;
38   if (manager.contextMap.find(ctxId) != manager.contextMap.end()) {
39     EXGLSysLog("Tried to reuse an EXGLContext id. This shouldn't really happen...");
40     return 0;
41   }
42   manager.contextMap[ctxId].ctx = new EXGLContext(ctxId);
43   return ctxId;
44 }
45 
46 void ContextDestroy(EXGLContextId id) {
47   std::lock_guard lock(manager.contextLookupMutex);
48 
49   auto iter = manager.contextMap.find(id);
50   if (iter != manager.contextMap.end()) {
51     {
52       std::unique_lock lock(iter->second.mutex);
53       delete iter->second.ctx;
54     }
55     manager.contextMap.erase(iter);
56   }
57 }
58 
59 } // namespace gl_cpp
60 } // namespace expo
61