2 #include <os_thread.hpp>
8 typedef std::tr1::shared_ptr<Context> context_ptr_t;
9 static std::map<uintptr_t, context_ptr_t> context_map;
10 static os::recursive_mutex context_map_mutex;
14 context_ptr_t current_context;
15 context_ptr_t dummy_context; /*
16 * For cases when there is no current
17 * context, but the app still calls some
18 * GL function that expects one.
20 ThreadState() : dummy_context(new Context)
22 current_context = dummy_context;
26 static os::thread_specific_ptr<struct ThreadState> thread_state;
28 static ThreadState *get_ts(void)
30 ThreadState *ts = thread_state.get();
34 thread_state.reset(ts);
40 static void _retainContext(context_ptr_t ctx)
45 void retainContext(uintptr_t context_id)
47 context_map_mutex.lock();
48 if (context_map.find(context_id) != context_map.end())
49 _retainContext(context_map[context_id]);
50 context_map_mutex.unlock();
53 static bool _releaseContext(context_ptr_t ctx)
55 return !(--ctx->retain_count);
59 * return true if the context was destroyed, false if only its refcount
60 * got decreased. Note that even if the context was destroyed it may
61 * still live, if it's the currently selected context (by setContext).
63 bool releaseContext(uintptr_t context_id)
67 context_map_mutex.lock();
69 * This can potentially called (from glX) with an invalid context_id,
70 * so don't assert on it being valid.
72 if (context_map.find(context_id) != context_map.end()) {
73 res = _releaseContext(context_map[context_id]);
75 context_map.erase(context_id);
77 context_map_mutex.unlock();
82 void createContext(uintptr_t context_id)
84 context_ptr_t ctx(new Context);
86 context_map_mutex.lock();
89 assert(context_map.find(context_id) == context_map.end());
90 context_map[context_id] = ctx;
92 context_map_mutex.unlock();
96 * return true if the context has been destroyed, false otherwise. See
97 * the note at releaseContext about the actual ccontext lifetime.
99 bool destroyContext(uintptr_t context_id)
101 return releaseContext(context_id);
104 void setContext(uintptr_t context_id)
106 ThreadState *ts = get_ts();
109 context_map_mutex.lock();
111 assert(context_map.find(context_id) != context_map.end());
112 ctx = context_map[context_id];
114 context_map_mutex.unlock();
116 ts->current_context = ctx;
119 void clearContext(void)
121 ThreadState *ts = get_ts();
123 ts->current_context = ts->dummy_context;
126 Context *getContext(void)
128 return get_ts()->current_context.get();