1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved.
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software.
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DEALINGS IN THE SOFTWARE.
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdlib.h>
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <string.h>
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "egllog.h"
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "eglmutex.h"
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "eglcurrent.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "eglglobals.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* This should be kept in sync with _eglInitThreadInfo() */
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define _EGL_THREAD_INFO_INITIALIZER \
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   { EGL_SUCCESS, { NULL }, 0 }
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* a fallback thread info to guarantee that every thread always has one */
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic _EGLThreadInfo dummy_thread = _EGL_THREAD_INFO_INITIALIZER;
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if HAVE_PTHREAD
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <pthread.h>
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic _EGL_DECLARE_MUTEX(_egl_TSDMutex);
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic EGLBoolean _egl_TSDInitialized;
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic pthread_key_t _egl_TSD;
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void (*_egl_FreeTSD)(_EGLThreadInfo *);
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef GLX_USE_TLS
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic __thread const _EGLThreadInfo *_egl_TLS
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   __attribute__ ((tls_model("initial-exec")));
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void _eglSetTSD(const _EGLThreadInfo *t)
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pthread_setspecific(_egl_TSD, (const void *) t);
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef GLX_USE_TLS
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _egl_TLS = t;
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE _EGLThreadInfo *_eglGetTSD(void)
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef GLX_USE_TLS
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (_EGLThreadInfo *) _egl_TLS;
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (_EGLThreadInfo *) pthread_getspecific(_egl_TSD);
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void _eglFiniTSD(void)
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _eglLockMutex(&_egl_TSDMutex);
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (_egl_TSDInitialized) {
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _EGLThreadInfo *t = _eglGetTSD();
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _egl_TSDInitialized = EGL_FALSE;
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (t && _egl_FreeTSD)
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _egl_FreeTSD((void *) t);
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pthread_key_delete(_egl_TSD);
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _eglUnlockMutex(&_egl_TSDMutex);
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE EGLBoolean _eglInitTSD(void (*dtor)(_EGLThreadInfo *))
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!_egl_TSDInitialized) {
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglLockMutex(&_egl_TSDMutex);
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* check again after acquiring lock */
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!_egl_TSDInitialized) {
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (pthread_key_create(&_egl_TSD, (void (*)(void *)) dtor) != 0) {
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            _eglUnlockMutex(&_egl_TSDMutex);
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return EGL_FALSE;
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _egl_FreeTSD = dtor;
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _eglAddAtExitCall(_eglFiniTSD);
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         _egl_TSDInitialized = EGL_TRUE;
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglUnlockMutex(&_egl_TSDMutex);
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return EGL_TRUE;
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else /* HAVE_PTHREAD */
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const _EGLThreadInfo *_egl_TSD;
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void (*_egl_FreeTSD)(_EGLThreadInfo *);
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void _eglSetTSD(const _EGLThreadInfo *t)
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _egl_TSD = t;
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE _EGLThreadInfo *_eglGetTSD(void)
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (_EGLThreadInfo *) _egl_TSD;
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void _eglFiniTSD(void)
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (_egl_FreeTSD && _egl_TSD)
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _egl_FreeTSD((_EGLThreadInfo *) _egl_TSD);
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE EGLBoolean _eglInitTSD(void (*dtor)(_EGLThreadInfo *))
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!_egl_FreeTSD && dtor) {
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _egl_FreeTSD = dtor;
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglAddAtExitCall(_eglFiniTSD);
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return EGL_TRUE;
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* !HAVE_PTHREAD */
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_eglInitThreadInfo(_EGLThreadInfo *t)
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(t, 0, sizeof(*t));
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   t->LastError = EGL_SUCCESS;
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* default, per EGL spec */
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   t->CurrentAPIIndex = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Allocate and init a new _EGLThreadInfo object.
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic _EGLThreadInfo *
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_eglCreateThreadInfo(void)
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _EGLThreadInfo *t = (_EGLThreadInfo *) calloc(1, sizeof(_EGLThreadInfo));
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (t)
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglInitThreadInfo(t);
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      t = &dummy_thread;
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return t;
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Delete/free a _EGLThreadInfo object.
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_eglDestroyThreadInfo(_EGLThreadInfo *t)
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (t != &dummy_thread)
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      free(t);
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Make sure TSD is initialized and return current value.
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE _EGLThreadInfo *
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_eglCheckedGetTSD(void)
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (_eglInitTSD(&_eglDestroyThreadInfo) != EGL_TRUE) {
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglLog(_EGL_FATAL, "failed to initialize \"current\" system");
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return _eglGetTSD();
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return the calling thread's thread info.
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If the calling thread nevers calls this function before, or if its thread
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * info was destroyed, a new one is created.  This function never returns NULL.
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * In the case allocation fails, a dummy one is returned.  See also
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * _eglIsCurrentThreadDummy.
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_EGLThreadInfo *
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_eglGetCurrentThread(void)
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _EGLThreadInfo *t = _eglCheckedGetTSD();
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!t) {
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      t = _eglCreateThreadInfo();
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglSetTSD(t);
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return t;
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Destroy the calling thread's thread info.
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_eglDestroyCurrentThread(void)
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _EGLThreadInfo *t = _eglCheckedGetTSD();
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (t) {
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglDestroyThreadInfo(t);
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglSetTSD(NULL);
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return true if the calling thread's thread info is dummy.
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * A dummy thread info is shared by all threads and should not be modified.
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Functions like eglBindAPI or eglMakeCurrent should check for dummy-ness
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * before updating the thread info.
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgEGLBoolean
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_eglIsCurrentThreadDummy(void)
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _EGLThreadInfo *t = _eglCheckedGetTSD();
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (!t || t == &dummy_thread);
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return the currently bound context of the given API, or NULL.
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgPUBLIC _EGLContext *
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_eglGetAPIContext(EGLenum api)
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _EGLThreadInfo *t = _eglGetCurrentThread();
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return t->CurrentContexts[_eglConvertApiToIndex(api)];
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return the currently bound context of the current API, or NULL.
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_EGLContext *
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_eglGetCurrentContext(void)
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _EGLThreadInfo *t = _eglGetCurrentThread();
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return t->CurrentContexts[t->CurrentAPIIndex];
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Record EGL error code and return EGL_FALSE.
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgEGLBoolean
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_eglError(EGLint errCode, const char *msg)
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _EGLThreadInfo *t = _eglGetCurrentThread();
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (t == &dummy_thread)
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return EGL_FALSE;
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   t->LastError = errCode;
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (errCode != EGL_SUCCESS) {
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const char *s;
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (errCode) {
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_BAD_ACCESS:
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         s = "EGL_BAD_ACCESS";
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_BAD_ALLOC:
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         s = "EGL_BAD_ALLOC";
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_BAD_ATTRIBUTE:
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         s = "EGL_BAD_ATTRIBUTE";
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_BAD_CONFIG:
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         s = "EGL_BAD_CONFIG";
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_BAD_CONTEXT:
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         s = "EGL_BAD_CONTEXT";
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_BAD_CURRENT_SURFACE:
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         s = "EGL_BAD_CURRENT_SURFACE";
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_BAD_DISPLAY:
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         s = "EGL_BAD_DISPLAY";
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_BAD_MATCH:
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         s = "EGL_BAD_MATCH";
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_BAD_NATIVE_PIXMAP:
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         s = "EGL_BAD_NATIVE_PIXMAP";
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_BAD_NATIVE_WINDOW:
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         s = "EGL_BAD_NATIVE_WINDOW";
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_BAD_PARAMETER:
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         s = "EGL_BAD_PARAMETER";
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_BAD_SURFACE:
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         s = "EGL_BAD_SURFACE";
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_NOT_INITIALIZED:
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         s = "EGL_NOT_INITIALIZED";
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef EGL_MESA_screen_surface
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_BAD_SCREEN_MESA:
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         s = "EGL_BAD_SCREEN_MESA";
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case EGL_BAD_MODE_MESA:
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         s = "EGL_BAD_MODE_MESA";
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         s = "other EGL error";
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _eglLog(_EGL_DEBUG, "EGL user error 0x%x (%s) in %s\n", errCode, s, msg);
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return EGL_FALSE;
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
336