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