|
1 /*------------------------------------------------------------------------ |
|
2 * |
|
3 * EGL 1.3 |
|
4 * ------- |
|
5 * |
|
6 * Copyright (c) 2007 The Khronos Group Inc. |
|
7 * |
|
8 * Permission is hereby granted, free of charge, to any person obtaining a |
|
9 * copy of this software and /or associated documentation files |
|
10 * (the "Materials "), to deal in the Materials without restriction, |
|
11 * including without limitation the rights to use, copy, modify, merge, |
|
12 * publish, distribute, sublicense, and/or sell copies of the Materials, |
|
13 * and to permit persons to whom the Materials are furnished to do so, |
|
14 * subject to the following conditions: |
|
15 * |
|
16 * The above copyright notice and this permission notice shall be included |
|
17 * in all copies or substantial portions of the Materials. |
|
18 * |
|
19 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
|
22 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
|
23 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
|
24 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR |
|
25 * THE USE OR OTHER DEALINGS IN THE MATERIALS. |
|
26 * |
|
27 *//** |
|
28 * \file |
|
29 * \brief Simple implementation of EGL 1.3 |
|
30 * \note caveats: |
|
31 - always renders into the backbuffer and blits it to window (no single buffered rendering) |
|
32 - no native Windows or Mac OS X pixmap support |
|
33 - no power management events |
|
34 - no support for swap interval |
|
35 * \todo what happens in egl functions when eglTerminate has been called but the context and surface are still in use? |
|
36 * \todo OSDeinitMutex should be called in case getEGL fails. |
|
37 *//*-------------------------------------------------------------------*/ |
|
38 |
|
39 #include "riMiniEGL.h" |
|
40 #include "eglprivate.h" |
|
41 #include <e32debug.h> |
|
42 namespace OpenVGRI |
|
43 { |
|
44 //using namespace OpenVGRI; |
|
45 |
|
46 RIEGLContext::RIEGLContext(OpenVGRI::VGContext* vgctx, const EGLConfig config) : |
|
47 m_vgContext(vgctx), m_config(config), m_referenceCount(0) |
|
48 { |
|
49 } |
|
50 RIEGLContext::~RIEGLContext() |
|
51 { |
|
52 RI_ASSERT(m_referenceCount == 0); |
|
53 RI_DELETE(m_vgContext); |
|
54 } |
|
55 |
|
56 /*-------------------------------------------------------------------*//*! |
|
57 * \brief |
|
58 * \param |
|
59 * \return |
|
60 * \note |
|
61 *//*-------------------------------------------------------------------*/ |
|
62 |
|
63 RIEGLSurface::RIEGLSurface(void* OSWindowContext, const EGLConfig config, |
|
64 Drawable* drawable, bool largestPbuffer, int renderBuffer) : |
|
65 m_OSWindowContext(OSWindowContext), m_config(config), m_drawable(drawable), |
|
66 m_largestPbuffer(largestPbuffer), m_renderBuffer(renderBuffer), |
|
67 m_referenceCount(0) |
|
68 { |
|
69 RI_ASSERT(m_renderBuffer == EGL_BACK_BUFFER); //only back buffer rendering is supported |
|
70 m_drawable->addReference(); |
|
71 } |
|
72 |
|
73 RIEGLSurface::~RIEGLSurface() |
|
74 { |
|
75 RI_ASSERT(m_referenceCount == 0); |
|
76 OSDestroyWindowContext(m_OSWindowContext); |
|
77 if (m_drawable) |
|
78 { |
|
79 if (!m_drawable->removeReference()) |
|
80 RI_DELETE(m_drawable); |
|
81 } |
|
82 } |
|
83 |
|
84 RIEGLDisplay::RIEGLDisplay(EGLDisplay id) : |
|
85 m_id(id), m_contexts(), m_surfaces() |
|
86 { |
|
87 RI_ASSERT(EGL_NUMCONFIGS == 60); |
|
88 |
|
89 //sorted by RGB/LUMINANCE (exact), larger total number of color bits (at least), buffer size (at least), config ID (exact) |
|
90 //NOTE: 16 bit configs need to be sorted on the fly if the request ignores some channels |
|
91 //NOTE: config IDs start from 1 |
|
92 // R B G A L bpp samples maskBits ID |
|
93 m_configs[0].set(8, 8, 8, 8, 0, 32, 1, 8, 1); //EGL_RGB_BUFFER, buffer size = 32 |
|
94 m_configs[1].set(8, 8, 8, 0, 0, 32, 1, 8, 2); //EGL_RGB_BUFFER, buffer size = 24 |
|
95 m_configs[2].set(5, 5, 5, 1, 0, 16, 1, 4, 3); //EGL_RGB_BUFFER, buffer size = 16 |
|
96 m_configs[3].set(5, 6, 5, 0, 0, 16, 1, 4, 4); //EGL_RGB_BUFFER, buffer size = 16 |
|
97 m_configs[4].set(4, 4, 4, 4, 0, 16, 1, 4, 5); //EGL_RGB_BUFFER, buffer size = 16 |
|
98 m_configs[5].set(0, 0, 0, 8, 0, 8, 1, 8, 6); //EGL_RGB_BUFFER, buffer size = 8 |
|
99 m_configs[6].set(0, 0, 0, 4, 0, 4, 1, 4, 7); //EGL_RGB_BUFFER, buffer size = 8 |
|
100 m_configs[7].set(0, 0, 0, 1, 0, 1, 1, 1, 8); //EGL_RGB_BUFFER, buffer size = 8 |
|
101 m_configs[8].set(0, 0, 0, 0, 8, 8, 1, 8, 9); //EGL_LUMINANCE_BUFFER, buffer size = 8 |
|
102 m_configs[9].set(0, 0, 0, 0, 1, 1, 1, 1, 10); //EGL_LUMINANCE_BUFFER, buffer size = 1 |
|
103 |
|
104 m_configs[10].set(8, 8, 8, 8, 0, 32, 4, 1, 11); //EGL_RGB_BUFFER, buffer size = 32 |
|
105 m_configs[11].set(8, 8, 8, 0, 0, 32, 4, 1, 12); //EGL_RGB_BUFFER, buffer size = 24 |
|
106 m_configs[12].set(5, 5, 5, 1, 0, 16, 4, 1, 13); //EGL_RGB_BUFFER, buffer size = 16 |
|
107 m_configs[13].set(5, 6, 5, 0, 0, 16, 4, 1, 14); //EGL_RGB_BUFFER, buffer size = 16 |
|
108 m_configs[14].set(4, 4, 4, 4, 0, 16, 4, 1, 15); //EGL_RGB_BUFFER, buffer size = 16 |
|
109 m_configs[15].set(0, 0, 0, 8, 0, 8, 4, 1, 16); //EGL_RGB_BUFFER, buffer size = 8 |
|
110 m_configs[16].set(0, 0, 0, 4, 0, 4, 4, 1, 17); //EGL_RGB_BUFFER, buffer size = 8 |
|
111 m_configs[17].set(0, 0, 0, 1, 0, 1, 4, 1, 18); //EGL_RGB_BUFFER, buffer size = 8 |
|
112 m_configs[18].set(0, 0, 0, 0, 8, 8, 4, 1, 19); //EGL_LUMINANCE_BUFFER, buffer size = 8 |
|
113 m_configs[19].set(0, 0, 0, 0, 1, 1, 4, 1, 20); //EGL_LUMINANCE_BUFFER, buffer size = 1 |
|
114 |
|
115 m_configs[20].set(8, 8, 8, 8, 0, 32, 32, 1, 21); //EGL_RGB_BUFFER, buffer size = 32 |
|
116 m_configs[21].set(8, 8, 8, 0, 0, 32, 32, 1, 22); //EGL_RGB_BUFFER, buffer size = 24 |
|
117 m_configs[22].set(5, 5, 5, 1, 0, 16, 32, 1, 23); //EGL_RGB_BUFFER, buffer size = 16 |
|
118 m_configs[23].set(5, 6, 5, 0, 0, 16, 32, 1, 24); //EGL_RGB_BUFFER, buffer size = 16 |
|
119 m_configs[24].set(4, 4, 4, 4, 0, 16, 32, 1, 25); //EGL_RGB_BUFFER, buffer size = 16 |
|
120 m_configs[25].set(0, 0, 0, 8, 0, 8, 32, 1, 26); //EGL_RGB_BUFFER, buffer size = 8 |
|
121 m_configs[26].set(0, 0, 0, 4, 0, 4, 32, 1, 27); //EGL_RGB_BUFFER, buffer size = 8 |
|
122 m_configs[27].set(0, 0, 0, 1, 0, 1, 32, 1, 28); //EGL_RGB_BUFFER, buffer size = 8 |
|
123 m_configs[28].set(0, 0, 0, 0, 8, 8, 32, 1, 29); //EGL_LUMINANCE_BUFFER, buffer size = 8 |
|
124 m_configs[29].set(0, 0, 0, 0, 1, 1, 32, 1, 30); //EGL_LUMINANCE_BUFFER, buffer size = 1 |
|
125 |
|
126 //configs without mask |
|
127 m_configs[30].set(8, 8, 8, 8, 0, 32, 1, 0, 31); //EGL_RGB_BUFFER, buffer size = 32 |
|
128 m_configs[31].set(8, 8, 8, 0, 0, 32, 1, 0, 32); //EGL_RGB_BUFFER, buffer size = 24 |
|
129 m_configs[32].set(5, 5, 5, 1, 0, 16, 1, 0, 33); //EGL_RGB_BUFFER, buffer size = 16 |
|
130 m_configs[33].set(5, 6, 5, 0, 0, 16, 1, 0, 34); //EGL_RGB_BUFFER, buffer size = 16 |
|
131 m_configs[34].set(4, 4, 4, 4, 0, 16, 1, 0, 35); //EGL_RGB_BUFFER, buffer size = 16 |
|
132 m_configs[35].set(0, 0, 0, 8, 0, 8, 1, 0, 36); //EGL_RGB_BUFFER, buffer size = 8 |
|
133 m_configs[36].set(0, 0, 0, 4, 0, 4, 1, 0, 37); //EGL_RGB_BUFFER, buffer size = 8 |
|
134 m_configs[37].set(0, 0, 0, 1, 0, 1, 1, 0, 38); //EGL_RGB_BUFFER, buffer size = 8 |
|
135 m_configs[38].set(0, 0, 0, 0, 8, 8, 1, 0, 39); //EGL_LUMINANCE_BUFFER, buffer size = 8 |
|
136 m_configs[39].set(0, 0, 0, 0, 1, 1, 1, 0, 40); //EGL_LUMINANCE_BUFFER, buffer size = 1 |
|
137 |
|
138 m_configs[40].set(8, 8, 8, 8, 0, 32, 4, 0, 41); //EGL_RGB_BUFFER, buffer size = 32 |
|
139 m_configs[41].set(8, 8, 8, 0, 0, 32, 4, 0, 42); //EGL_RGB_BUFFER, buffer size = 24 |
|
140 m_configs[42].set(5, 5, 5, 1, 0, 16, 4, 0, 43); //EGL_RGB_BUFFER, buffer size = 16 |
|
141 m_configs[43].set(5, 6, 5, 0, 0, 16, 4, 0, 44); //EGL_RGB_BUFFER, buffer size = 16 |
|
142 m_configs[44].set(4, 4, 4, 4, 0, 16, 4, 0, 45); //EGL_RGB_BUFFER, buffer size = 16 |
|
143 m_configs[45].set(0, 0, 0, 8, 0, 8, 4, 0, 46); //EGL_RGB_BUFFER, buffer size = 8 |
|
144 m_configs[46].set(0, 0, 0, 4, 0, 4, 4, 0, 47); //EGL_RGB_BUFFER, buffer size = 8 |
|
145 m_configs[47].set(0, 0, 0, 1, 0, 1, 4, 0, 48); //EGL_RGB_BUFFER, buffer size = 8 |
|
146 m_configs[48].set(0, 0, 0, 0, 8, 8, 4, 0, 49); //EGL_LUMINANCE_BUFFER, buffer size = 8 |
|
147 m_configs[49].set(0, 0, 0, 0, 1, 1, 4, 0, 50); //EGL_LUMINANCE_BUFFER, buffer size = 1 |
|
148 |
|
149 m_configs[50].set(8, 8, 8, 8, 0, 32, 32, 0, 51); //EGL_RGB_BUFFER, buffer size = 32 |
|
150 m_configs[51].set(8, 8, 8, 0, 0, 32, 32, 0, 52); //EGL_RGB_BUFFER, buffer size = 24 |
|
151 m_configs[52].set(5, 5, 5, 1, 0, 16, 32, 0, 53); //EGL_RGB_BUFFER, buffer size = 16 |
|
152 m_configs[53].set(5, 6, 5, 0, 0, 16, 32, 0, 54); //EGL_RGB_BUFFER, buffer size = 16 |
|
153 m_configs[54].set(4, 4, 4, 4, 0, 16, 32, 0, 55); //EGL_RGB_BUFFER, buffer size = 16 |
|
154 m_configs[55].set(0, 0, 0, 8, 0, 8, 32, 0, 56); //EGL_RGB_BUFFER, buffer size = 8 |
|
155 m_configs[56].set(0, 0, 0, 4, 0, 4, 32, 0, 57); //EGL_RGB_BUFFER, buffer size = 8 |
|
156 m_configs[57].set(0, 0, 0, 1, 0, 1, 32, 0, 58); //EGL_RGB_BUFFER, buffer size = 8 |
|
157 m_configs[58].set(0, 0, 0, 0, 8, 8, 32, 0, 59); //EGL_LUMINANCE_BUFFER, buffer size = 8 |
|
158 m_configs[59].set(0, 0, 0, 0, 1, 1, 32, 0, 60); //EGL_LUMINANCE_BUFFER, buffer size = 1 |
|
159 /* |
|
160 attrib default criteria order priority |
|
161 -------------------------------------------------------------- |
|
162 EGL_COLOR_BUFFER_TYPE EGL_RGB_BUFFER Exact None 2 |
|
163 EGL_RED_SIZE 0 AtLeast Special 3 |
|
164 EGL_GREEN_SIZE 0 AtLeast Special 3 |
|
165 EGL_BLUE_SIZE 0 AtLeast Special 3 |
|
166 EGL_LUMINANCE_SIZE 0 AtLeast Special 3 |
|
167 EGL_ALPHA_SIZE 0 AtLeast Special 3 |
|
168 EGL_BUFFER_SIZE 0 AtLeast Smaller 4 |
|
169 EGL_CONFIG_ID EGL_DONT_CARE Exact Smaller 11 |
|
170 */ |
|
171 } |
|
172 |
|
173 RIEGLDisplay::~RIEGLDisplay() |
|
174 { |
|
175 //mark everything for deletion, but don't delete the current context and surface |
|
176 for (int i = 0; i < m_contexts.size(); i++) |
|
177 { |
|
178 if (!m_contexts[i]->removeReference()) |
|
179 RI_DELETE(m_contexts[i]); |
|
180 } |
|
181 m_contexts.clear(); //remove all contexts from the list (makes further references to the current contexts invalid) |
|
182 |
|
183 for (int i = 0; i < m_surfaces.size(); i++) |
|
184 { |
|
185 if (!m_surfaces[i]->removeReference()) |
|
186 RI_DELETE(m_surfaces[i]); |
|
187 } |
|
188 m_surfaces.clear(); //remove all surfaces from the list (makes further references to the current surfaces invalid) |
|
189 } |
|
190 |
|
191 EGLBoolean RIEGLDisplay::contextExists(const EGLContext ctx) const |
|
192 { |
|
193 for (int i = 0; i < m_contexts.size(); i++) |
|
194 { |
|
195 if (m_contexts[i] == CastToRIEGLContext(ctx)) |
|
196 return EGL_TRUE; |
|
197 } |
|
198 return EGL_FALSE; |
|
199 } |
|
200 |
|
201 EGLBoolean RIEGLDisplay::surfaceExists(const EGLSurface surf) const |
|
202 { |
|
203 for (int i = 0; i < m_surfaces.size(); i++) |
|
204 { |
|
205 if (m_surfaces[i] == CastToRIEGLSurface(surf)) |
|
206 return EGL_TRUE; |
|
207 } |
|
208 return EGL_FALSE; |
|
209 } |
|
210 |
|
211 EGLBoolean RIEGLDisplay::configExists(const EGLConfig config) const |
|
212 { |
|
213 for (int i = 0; i < EGL_NUMCONFIGS; i++) |
|
214 { |
|
215 if (m_configs[i].m_config == config) |
|
216 return EGL_TRUE; |
|
217 } |
|
218 return EGL_FALSE; |
|
219 } |
|
220 |
|
221 RIEGLThread::RIEGLThread(void* currentThreadID) : |
|
222 m_context(NULL), m_surface(NULL), m_error(EGL_SUCCESS), m_threadID( |
|
223 currentThreadID), m_boundAPI(EGL_NONE) |
|
224 { |
|
225 } |
|
226 |
|
227 RIEGLThread::~RIEGLThread() |
|
228 { |
|
229 } |
|
230 |
|
231 EGL::EGL() : |
|
232 m_threads(), m_currentThreads(), m_displays(), m_referenceCount(0) |
|
233 { |
|
234 } |
|
235 EGL::~EGL() |
|
236 { |
|
237 for (int i = 0; i < m_displays.size(); i++) |
|
238 { |
|
239 RI_DELETE(m_displays[i]); |
|
240 } |
|
241 for (int i = 0; i < m_threads.size(); i++) |
|
242 { |
|
243 RI_DELETE(m_threads[i]); |
|
244 } |
|
245 //currentThreads contain just pointers to threads we just deleted |
|
246 } |
|
247 |
|
248 /*-------------------------------------------------------------------*//*! |
|
249 * \brief |
|
250 * \param |
|
251 * \return |
|
252 * \note |
|
253 *//*-------------------------------------------------------------------*/ |
|
254 |
|
255 //static EGL* g_egl = NULL; //never use this directly |
|
256 EGL* getEGL() |
|
257 { |
|
258 /*if(!g_egl) |
|
259 { |
|
260 try |
|
261 { |
|
262 g_egl = RI_NEW(EGL, ()); //throws bad_alloc |
|
263 g_egl->addReference(); |
|
264 } |
|
265 catch(std::bad_alloc) |
|
266 { |
|
267 g_egl = NULL; |
|
268 } |
|
269 } |
|
270 return g_egl; |
|
271 */ |
|
272 |
|
273 //use TLS to store static global g_egl |
|
274 EGL* pEgl = NULL; |
|
275 |
|
276 CEglThreadSession* es = reinterpret_cast<CEglThreadSession*>(Dll::Tls()); |
|
277 if (es) |
|
278 { |
|
279 return es->getEgl(); |
|
280 } |
|
281 |
|
282 const TInt err = CEglDriver::Open(); |
|
283 if (err != KErrNone) |
|
284 { |
|
285 return NULL; |
|
286 } |
|
287 |
|
288 // CEglDriver is reference counted. As we successfuly open the driver, pls.iDriver will be non-null |
|
289 // and it should be safe to cache the pointer inside CEglThreadSession |
|
290 CEglDriver* drv = CEglDriver::GetDriver(); |
|
291 __ASSERT_DEBUG(drv, User::Panic(KEglPanicCategory, EEglPanicDriverNull)); |
|
292 |
|
293 // create session object on default thread's heap |
|
294 es = new CEglThreadSession(*drv); |
|
295 |
|
296 if (!es || Dll::SetTls(es)!= KErrNone) |
|
297 { |
|
298 delete es; |
|
299 return NULL; |
|
300 } |
|
301 |
|
302 return es->getEgl(); |
|
303 |
|
304 //TODO do we need to associate EGL with session here Jose |
|
305 /* if ((pEgl = static_cast<EGL*> (Dll::Tls())) == NULL) |
|
306 { |
|
307 //create TLS instance |
|
308 pEgl = RI_NEW(EGL, ()); |
|
309 RDebug::Printf("---------- In getEGL()::Static(),Addr of pEgl Ptr = %x\n", &pEgl); |
|
310 RDebug::Printf("---------- In getEGL()::Static(),Addr of pEgl= %x\n", pEgl); |
|
311 //RDebug::Printf("In CEglThreadSession::Static(),Thread Id %Lu",(RThread().Id().Id())); |
|
312 RDebug::Printf("---------- In getEGL()::Static(),Thread Id %Lu",(RThread().Id())); |
|
313 Dll::SetTls(pEgl); |
|
314 }*/ |
|
315 //return pEgl; |
|
316 |
|
317 } |
|
318 |
|
319 |
|
320 static void releaseEGL() |
|
321 { |
|
322 /* |
|
323 if(g_egl) |
|
324 { |
|
325 if(!g_egl->removeReference()) |
|
326 { |
|
327 RI_DELETE(g_egl); |
|
328 g_egl = NULL; |
|
329 } |
|
330 } |
|
331 */ |
|
332 EGL* pEgl = static_cast<EGL*> (Dll::Tls()); |
|
333 if (pEgl) |
|
334 delete pEgl; |
|
335 Dll::SetTls(NULL); |
|
336 |
|
337 } |
|
338 |
|
339 /*-------------------------------------------------------------------*//*! |
|
340 * \brief Given a display ID, return the corresponding object, or NULL |
|
341 * if the ID hasn't been initialized. |
|
342 * \param |
|
343 * \return |
|
344 * \note if egl has been initialized for this display, the display ID can |
|
345 * be found from egl->m_displays |
|
346 *//*-------------------------------------------------------------------*/ |
|
347 |
|
348 RIEGLDisplay* EGL::getDisplay(EGLDisplay displayID) const |
|
349 { |
|
350 for (int i = 0; i < m_displays.size(); i++) |
|
351 { |
|
352 if (displayID == m_displays[i]->getID()) |
|
353 return m_displays[i]; |
|
354 } |
|
355 return NULL; //error: the display hasn't been eglInitialized |
|
356 } |
|
357 |
|
358 /*-------------------------------------------------------------------*//*! |
|
359 * \brief return EGLDisplay for the current context |
|
360 * \param |
|
361 * \return |
|
362 * \note |
|
363 *//*-------------------------------------------------------------------*/ |
|
364 |
|
365 EGLDisplay EGL::findDisplay(EGLContext ctx) const |
|
366 { |
|
367 for (int i = 0; i < m_displays.size(); i++) |
|
368 { |
|
369 if (m_displays[i]->contextExists(ctx)) |
|
370 return m_displays[i]->getID(); |
|
371 } |
|
372 return EGL_NO_DISPLAY; |
|
373 } |
|
374 |
|
375 /*-------------------------------------------------------------------*//*! |
|
376 * \brief return an EGL thread struct for the thread made current, or |
|
377 * NULL if there's no current context. |
|
378 * \param |
|
379 * \return |
|
380 * \note |
|
381 *//*-------------------------------------------------------------------*/ |
|
382 |
|
383 RIEGLThread* EGL::getCurrentThread() const |
|
384 { |
|
385 void* currentThreadID = OSGetCurrentThreadID(); |
|
386 for (int i = 0; i < m_currentThreads.size(); i++) |
|
387 { |
|
388 if (currentThreadID == m_currentThreads[i]->getThreadID()) |
|
389 return m_currentThreads[i]; |
|
390 } |
|
391 return NULL; //thread is not current |
|
392 } |
|
393 |
|
394 /*-------------------------------------------------------------------*//*! |
|
395 * \brief return an EGL thread struct corresponding to current OS thread. |
|
396 * \param |
|
397 * \return |
|
398 * \note |
|
399 *//*-------------------------------------------------------------------*/ |
|
400 |
|
401 RIEGLThread* EGL::getThread() |
|
402 { |
|
403 void* currentThreadID = OSGetCurrentThreadID(); |
|
404 for (int i = 0; i < m_threads.size(); i++) |
|
405 { |
|
406 if (currentThreadID == m_threads[i]->getThreadID()) |
|
407 return m_threads[i]; |
|
408 } |
|
409 |
|
410 //EGL doesn't have a struct for the thread yet, add it to EGL's list |
|
411 RIEGLThread* newThread = NULL; |
|
412 try |
|
413 { |
|
414 newThread = RI_NEW(RIEGLThread, (OSGetCurrentThreadID())); //throws bad_alloc |
|
415 m_threads.push_back(newThread); //throws bad_alloc |
|
416 return newThread; |
|
417 } |
|
418 catch (std::bad_alloc) |
|
419 { |
|
420 RI_DELETE(newThread); |
|
421 return NULL; |
|
422 } |
|
423 } |
|
424 |
|
425 /*-------------------------------------------------------------------*//*! |
|
426 * \brief destroy an EGL thread struct |
|
427 * \param |
|
428 * \return |
|
429 * \note |
|
430 *//*-------------------------------------------------------------------*/ |
|
431 |
|
432 void EGL::destroyThread() |
|
433 { |
|
434 void* currentThreadID = OSGetCurrentThreadID(); |
|
435 for (int i = 0; i < m_threads.size(); i++) |
|
436 { |
|
437 if (currentThreadID == m_threads[i]->getThreadID()) |
|
438 { |
|
439 RIEGLThread* thread = m_threads[i]; |
|
440 bool res = m_threads.remove(thread); |
|
441 RI_ASSERT(res); |
|
442 RI_UNREF(res); |
|
443 RI_DELETE(thread); |
|
444 break; |
|
445 } |
|
446 } |
|
447 } |
|
448 |
|
449 /*-------------------------------------------------------------------*//*! |
|
450 * \brief |
|
451 * \param |
|
452 * \return |
|
453 * \note |
|
454 *//*-------------------------------------------------------------------*/ |
|
455 |
|
456 bool EGL::isInUse(const void* image) const |
|
457 { |
|
458 for (int i = 0; i < m_currentThreads.size(); i++) |
|
459 { |
|
460 RIEGLSurface* s = m_currentThreads[i]->getCurrentSurface(); |
|
461 if (s && s->getDrawable() && s->getDrawable()->isInUse((Image*) image)) |
|
462 return true; |
|
463 } |
|
464 return false; |
|
465 } |
|
466 |
|
467 // Note: egl error handling model differs from OpenVG. The latest error is stored instead of the oldest one. |
|
468 static void eglSetError(EGL* egl, EGLint error) |
|
469 { |
|
470 RIEGLThread* thread = egl->getThread(); |
|
471 if (thread) |
|
472 thread->setError(error); |
|
473 } |
|
474 |
|
475 /*-------------------------------------------------------------------*//*! |
|
476 * \brief Returns the OpenVG context current to the calling thread. |
|
477 * \param |
|
478 * \return |
|
479 * \note This function is always called from a mutexed API function |
|
480 *//*-------------------------------------------------------------------*/ |
|
481 |
|
482 void* eglvgGetCurrentVGContext(void) |
|
483 { |
|
484 EGL* egl = getEGL(); |
|
485 /* RDebug::Printf(" \n"); |
|
486 RDebug::Printf(" \n"); |
|
487 RDebug::Printf(" \n"); |
|
488 |
|
489 |
|
490 RDebug::Printf(" $$$$$$$$$$$$$ I am in function eglvgGetCurrentVGContext $$$$$$$$$$$$$$$$$\n"); |
|
491 RDebug::Printf(" $$$$$$$$$$$$$ In eglvgGetCurrentVGContext,Thread Id %Lu $$$$$$$$$$$$$ ",(RThread().Id()));*/ |
|
492 |
|
493 |
|
494 if (egl) |
|
495 { |
|
496 RIEGLThread* thread = egl->getCurrentThread(); |
|
497 //RDebug::Printf(" $$$$$$$$$$$$$ I am in function eglvgGetCurrentVGContext.EGL addr is %x = \n",egl); |
|
498 if (thread) |
|
499 { |
|
500 RI_ASSERT(thread->getCurrentContext() && thread->getCurrentSurface()); |
|
501 return thread->getCurrentContext()->getVGContext(); |
|
502 } |
|
503 } |
|
504 return NULL; //not initialized or made current |
|
505 } |
|
506 |
|
507 /*-------------------------------------------------------------------*//*! |
|
508 * \brief Check if the image is current in any of the displays |
|
509 * \param |
|
510 * \return |
|
511 * \note This function is always called from a mutexed API function |
|
512 *//*-------------------------------------------------------------------*/ |
|
513 |
|
514 bool eglvgIsInUse(void* image) |
|
515 { |
|
516 EGL* egl = getEGL(); |
|
517 if (egl) |
|
518 { |
|
519 return egl->isInUse(image); |
|
520 } |
|
521 return false; |
|
522 } |
|
523 |
|
524 //helper functions |
|
525 RIEGLContext* CastToRIEGLContext(EGLContext aCtxId) |
|
526 { |
|
527 return (RIEGLContext*)(aCtxId); |
|
528 } |
|
529 EGLContext CastFromRIEGLContext(RIEGLContext* aCtx) |
|
530 { |
|
531 return (EGLContext)(aCtx); |
|
532 } |
|
533 |
|
534 RIEGLSurface* CastToRIEGLSurface(EGLSurface aSurfaceId) |
|
535 { |
|
536 return (RIEGLSurface*)(aSurfaceId); |
|
537 } |
|
538 EGLSurface CastFromRIEGLSurface(RIEGLSurface* aSurface) |
|
539 { |
|
540 return (EGLSurface)(aSurface); |
|
541 } |
|
542 |
|
543 Image* CastToImage(EGLClientBuffer aBufferId) |
|
544 { |
|
545 return (Image*)(aBufferId); |
|
546 } |
|
547 |
|
548 EGLClientBuffer CastFromImage(Image* aBUffer) |
|
549 { |
|
550 return (EGLClientBuffer)(aBUffer); |
|
551 } |
|
552 }// namespace OpenVGRI |
|
553 |
|
554 //============================================================================================== |
|
555 |
|
556 using namespace OpenVGRI; |
|
557 /*-------------------------------------------------------------------*//*! |
|
558 * \brief |
|
559 * \param |
|
560 * \return |
|
561 * \note |
|
562 *//*-------------------------------------------------------------------*/ |
|
563 |
|
564 #ifdef BUILD_WITH_PRIVATE_EGL |
|
565 RI_APIENTRY EGLint do_eglGetError() |
|
566 #else |
|
567 EGLint eglGetError() |
|
568 #endif |
|
569 { |
|
570 OSAcquireMutex(); |
|
571 EGLint ret = EGL_SUCCESS; |
|
572 EGL* egl = getEGL(); |
|
573 if (egl) |
|
574 { |
|
575 RIEGLThread* thread = egl->getThread(); |
|
576 if (thread) |
|
577 ret = thread->getError(); //initialized, return error code |
|
578 } |
|
579 else |
|
580 ret = EGL_NOT_INITIALIZED; |
|
581 OSReleaseMutex(); |
|
582 return ret; |
|
583 } |
|
584 |
|
585 /*-------------------------------------------------------------------*//*! |
|
586 * \brief |
|
587 * \param |
|
588 * \return |
|
589 * \note |
|
590 *//*-------------------------------------------------------------------*/ |
|
591 |
|
592 #ifdef BUILD_WITH_PRIVATE_EGL |
|
593 RI_APIENTRY EGLDisplay do_eglGetDisplay(EGLNativeDisplayType display_id) |
|
594 #else |
|
595 EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id) |
|
596 #endif |
|
597 { |
|
598 return OSGetDisplay(display_id); |
|
599 } |
|
600 |
|
601 /*-------------------------------------------------------------------*//*! |
|
602 * \brief |
|
603 * \param |
|
604 * \return |
|
605 * \note |
|
606 *//*-------------------------------------------------------------------*/ |
|
607 |
|
608 #ifdef BUILD_WITH_PRIVATE_EGL |
|
609 RI_APIENTRY EGLBoolean do_eglInitialize(EGLDisplay dpy, EGLint *major, |
|
610 EGLint *minor) |
|
611 #else |
|
612 EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) |
|
613 #endif |
|
614 { |
|
615 EGL_GET_DISPLAY(dpy, EGL_FALSE); |
|
616 EGL_IF_ERROR(display, EGL_SUCCESS, EGL_TRUE); //already initialized |
|
617 |
|
618 //create the current display |
|
619 //if a context and a surface are bound by the time of eglTerminate, they remain bound until eglMakeCurrent is called |
|
620 RIEGLDisplay* newDisplay = NULL; |
|
621 try |
|
622 { |
|
623 newDisplay = RI_NEW(RIEGLDisplay, (dpy)); //throws bad_alloc |
|
624 egl->addDisplay(newDisplay); //throws bad_alloc |
|
625 display = newDisplay; |
|
626 RI_ASSERT(display); |
|
627 } |
|
628 catch (std::bad_alloc) |
|
629 { |
|
630 RI_DELETE(newDisplay); |
|
631 EGL_RETURN(EGL_BAD_ALLOC, EGL_FALSE); |
|
632 } |
|
633 |
|
634 if (major) |
|
635 *major = 1; |
|
636 if (minor) |
|
637 *minor = 2; |
|
638 EGL_RETURN(EGL_SUCCESS, EGL_TRUE); |
|
639 } |
|
640 |
|
641 /*-------------------------------------------------------------------*//*! |
|
642 * \brief |
|
643 * \param |
|
644 * \return |
|
645 * \note |
|
646 *//*-------------------------------------------------------------------*/ |
|
647 |
|
648 #ifdef BUILD_WITH_PRIVATE_EGL |
|
649 RI_APIENTRY EGLBoolean do_eglTerminate(EGLDisplay dpy) |
|
650 #else |
|
651 EGLBoolean eglTerminate(EGLDisplay dpy) |
|
652 #endif |
|
653 { |
|
654 EGL_GET_DISPLAY(dpy, EGL_FALSE); |
|
655 EGL_IF_ERROR(!display, EGL_SUCCESS, EGL_TRUE); |
|
656 egl->removeDisplay(display); |
|
657 RI_DELETE(display); |
|
658 EGL_RETURN(EGL_SUCCESS, EGL_TRUE); |
|
659 } |
|
660 |
|
661 /*-------------------------------------------------------------------*//*! |
|
662 * \brief |
|
663 * \param |
|
664 * \return |
|
665 * \note |
|
666 *//*-------------------------------------------------------------------*/ |
|
667 |
|
668 #ifdef BUILD_WITH_PRIVATE_EGL |
|
669 RI_APIENTRY const char *do_eglQueryString(EGLDisplay dpy, EGLint name) |
|
670 #else |
|
671 const char *eglQueryString(EGLDisplay dpy, EGLint name) |
|
672 #endif |
|
673 { EGL_GET_DISPLAY(dpy, NULL); |
|
674 EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, NULL); |
|
675 |
|
676 static const char apis[] = "OpenVG"; |
|
677 static const char extensions[] = ""; |
|
678 static const char vendor[] = "Khronos Group"; |
|
679 static const char version[] = "1.3"; |
|
680 |
|
681 const char* ret = NULL; |
|
682 switch(name) |
|
683 { |
|
684 case EGL_CLIENT_APIS: |
|
685 ret = apis; |
|
686 break; |
|
687 |
|
688 case EGL_EXTENSIONS: |
|
689 ret = extensions; |
|
690 break; |
|
691 |
|
692 case EGL_VENDOR: |
|
693 ret = vendor; |
|
694 break; |
|
695 |
|
696 case EGL_VERSION: |
|
697 ret = version; |
|
698 break; |
|
699 |
|
700 default: |
|
701 EGL_RETURN(EGL_BAD_PARAMETER, NULL); |
|
702 } |
|
703 EGL_RETURN(EGL_SUCCESS, ret); |
|
704 } |
|
705 |
|
706 /*-------------------------------------------------------------------*//*! |
|
707 * \brief |
|
708 * \param |
|
709 * \return |
|
710 * \note |
|
711 *//*-------------------------------------------------------------------*/ |
|
712 |
|
713 #ifdef BUILD_WITH_PRIVATE_EGL |
|
714 RI_APIENTRY EGLBoolean do_eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, |
|
715 EGLint config_size, EGLint *num_config) |
|
716 #else |
|
717 EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) |
|
718 #endif |
|
719 { |
|
720 EGL_GET_DISPLAY(dpy, EGL_FALSE); |
|
721 EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE); |
|
722 EGL_IF_ERROR(!num_config, EGL_BAD_PARAMETER, EGL_FALSE); |
|
723 if (!configs) |
|
724 { |
|
725 *num_config = display->getNumConfigs(); |
|
726 EGL_RETURN(EGL_SUCCESS, EGL_TRUE); |
|
727 } |
|
728 *num_config = RI_INT_MIN(config_size, display->getNumConfigs()); |
|
729 for (int i = 0; i < *num_config; i++) |
|
730 configs[i] = display->getConfigByIdx(i).m_config; |
|
731 |
|
732 EGL_RETURN(EGL_SUCCESS, EGL_TRUE); |
|
733 } |
|
734 |
|
735 /*-------------------------------------------------------------------*//*! |
|
736 * \brief |
|
737 * \param |
|
738 * \return |
|
739 * \note |
|
740 *//*-------------------------------------------------------------------*/ |
|
741 |
|
742 static bool smaller(EGLint c, EGLint filter) |
|
743 { |
|
744 return (filter != EGL_DONT_CARE) && (c < filter); |
|
745 } |
|
746 |
|
747 #ifdef BUILD_WITH_PRIVATE_EGL |
|
748 RI_APIENTRY EGLBoolean do_eglChooseConfig(EGLDisplay dpy, |
|
749 const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, |
|
750 EGLint *num_config) |
|
751 #else |
|
752 EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) |
|
753 #endif |
|
754 { |
|
755 EGL_GET_DISPLAY(dpy, EGL_FALSE); |
|
756 EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE); |
|
757 EGL_IF_ERROR(!num_config, EGL_BAD_PARAMETER, EGL_FALSE); |
|
758 |
|
759 if (!configs) |
|
760 { |
|
761 *num_config = display->getNumConfigs(); |
|
762 EGL_RETURN(EGL_SUCCESS, EGL_TRUE); |
|
763 } |
|
764 *num_config = 0; |
|
765 if (!config_size) |
|
766 EGL_RETURN(EGL_SUCCESS, EGL_TRUE); |
|
767 |
|
768 int bufferSize = 0; |
|
769 int redSize = 0; |
|
770 int greenSize = 0; |
|
771 int blueSize = 0; |
|
772 int luminanceSize = 0; |
|
773 int alphaSize = 0; |
|
774 int colorBufferType = EGL_RGB_BUFFER; |
|
775 int configID = EGL_DONT_CARE; |
|
776 int sampleBuffers = 0; |
|
777 int samples = 0; |
|
778 if (attrib_list) |
|
779 { |
|
780 for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) |
|
781 { |
|
782 switch (attrib_list[i]) |
|
783 { |
|
784 case EGL_BUFFER_SIZE: //depth of the color buffer |
|
785 bufferSize = attrib_list[i + 1]; |
|
786 break; |
|
787 case EGL_RED_SIZE: //bits of Red in the color buffer |
|
788 redSize = attrib_list[i + 1]; |
|
789 break; |
|
790 case EGL_GREEN_SIZE: //bits of Green in the color buffer |
|
791 greenSize = attrib_list[i + 1]; |
|
792 break; |
|
793 case EGL_BLUE_SIZE: //bits of Blue in the color buffer |
|
794 blueSize = attrib_list[i + 1]; |
|
795 break; |
|
796 case EGL_LUMINANCE_SIZE: //bits of Luminance in the color buffer |
|
797 luminanceSize = attrib_list[i + 1]; |
|
798 break; |
|
799 case EGL_ALPHA_SIZE: //bits of Alpha in the color buffer |
|
800 alphaSize = attrib_list[i + 1]; |
|
801 break; |
|
802 case EGL_ALPHA_MASK_SIZE: //bits of Alpha in the alpha mask buffer |
|
803 if (attrib_list[i + 1] > 8) |
|
804 EGL_RETURN(EGL_SUCCESS, EGL_TRUE) |
|
805 ; //not supported |
|
806 break; |
|
807 case EGL_COLOR_BUFFER_TYPE: //enum color buffer type (EGL_RGB_BUFFER, EGL_LUMINANCE_BUFFER) |
|
808 EGL_IF_ERROR(attrib_list[i+1] != EGL_RGB_BUFFER && attrib_list[i+1] != EGL_LUMINANCE_BUFFER && attrib_list[i+1] != EGL_DONT_CARE, EGL_BAD_ATTRIBUTE, EGL_FALSE) |
|
809 ; |
|
810 colorBufferType = attrib_list[i + 1]; |
|
811 break; |
|
812 case EGL_CONFIG_ID: //unique EGLConfig identifier |
|
813 configID = attrib_list[i + 1]; |
|
814 break; |
|
815 |
|
816 case EGL_SAMPLE_BUFFERS: //integer number of multisample buffers |
|
817 sampleBuffers = attrib_list[i + 1]; |
|
818 break; |
|
819 case EGL_SAMPLES: //integer number of samples per pixel |
|
820 samples = attrib_list[i + 1]; |
|
821 break; |
|
822 |
|
823 case EGL_BIND_TO_TEXTURE_RGB: //boolean True if bindable to RGB textures. (always EGL_FALSE) |
|
824 case EGL_BIND_TO_TEXTURE_RGBA: //boolean True if bindable to RGBA textures. (always EGL_FALSE) |
|
825 case EGL_DEPTH_SIZE: //integer bits of Z in the depth buffer (always 0) |
|
826 case EGL_LEVEL: //integer frame buffer level (always 0) |
|
827 case EGL_NATIVE_RENDERABLE: //boolean EGL TRUE if native rendering APIs can render to surface (always EGL_FALSE) |
|
828 case EGL_STENCIL_SIZE: //integer bits of Stencil in the stencil buffer (always 0) |
|
829 if (attrib_list[i + 1]) |
|
830 EGL_RETURN(EGL_SUCCESS, EGL_TRUE) |
|
831 ; //not supported |
|
832 break; |
|
833 |
|
834 case EGL_CONFIG_CAVEAT: //enum any caveats for the configuration (always EGL_NONE) |
|
835 case EGL_NATIVE_VISUAL_TYPE: //integer native visual type of the associated visual (always EGL_NONE) |
|
836 if (attrib_list[i + 1] != EGL_NONE) |
|
837 EGL_RETURN(EGL_SUCCESS, EGL_TRUE) |
|
838 ; //not supported |
|
839 break; |
|
840 |
|
841 case EGL_MAX_SWAP_INTERVAL: //integer maximum swap interval (always 1) |
|
842 case EGL_MIN_SWAP_INTERVAL: //integer minimum swap interval (always 1) |
|
843 if (attrib_list[i + 1] != 1) |
|
844 EGL_RETURN(EGL_SUCCESS, EGL_TRUE) |
|
845 ; //not supported |
|
846 break; |
|
847 |
|
848 case EGL_RENDERABLE_TYPE: //bitmask which client rendering APIs are supported. (always EGL_OPENVG_BIT) |
|
849 if (!(attrib_list[i + 1] & EGL_OPENVG_BIT)) |
|
850 EGL_RETURN(EGL_SUCCESS, EGL_TRUE) |
|
851 ; //not supported |
|
852 break; |
|
853 |
|
854 case EGL_SURFACE_TYPE: //bitmask which types of EGL surfaces are supported. (always EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT | EGL_VG_COLORSPACE_LINEAR_BIT | EGL_VG_ALPHA_FORMAT_PRE_BIT) |
|
855 break; //all types are always supported |
|
856 |
|
857 case EGL_TRANSPARENT_TYPE: //enum type of transparency supported (always EGL_NONE) |
|
858 case EGL_NATIVE_VISUAL_ID: //integer handle of corresponding native visual (always 0) |
|
859 case EGL_MAX_PBUFFER_WIDTH: //integer maximum width of pbuffer (always INT_MAX) |
|
860 case EGL_MAX_PBUFFER_HEIGHT: //integer maximum height of pbuffer (always INT_MAX) |
|
861 case EGL_MAX_PBUFFER_PIXELS: //integer maximum size of pbuffer (always INT_MAX) |
|
862 case EGL_TRANSPARENT_RED_VALUE: //integer transparent red value (undefined) |
|
863 case EGL_TRANSPARENT_GREEN_VALUE: //integer transparent green value (undefined) |
|
864 case EGL_TRANSPARENT_BLUE_VALUE: //integer transparent blue value (undefined) |
|
865 break; //ignored |
|
866 |
|
867 default: |
|
868 EGL_RETURN(EGL_BAD_ATTRIBUTE, EGL_FALSE) |
|
869 ; //unknown attribute |
|
870 } |
|
871 } |
|
872 } |
|
873 |
|
874 if (configID && configID != EGL_DONT_CARE) |
|
875 { //if CONFIG_ID is defined, ignore the rest of the attribs |
|
876 for (int i = 0; i < EGL_NUMCONFIGS; i++) |
|
877 { |
|
878 if (display->getConfigByIdx(i).m_configID == configID) |
|
879 { |
|
880 *num_config = 1; |
|
881 *configs = display->getConfigByIdx(i).m_config; |
|
882 } |
|
883 } |
|
884 EGL_RETURN(EGL_SUCCESS, EGL_TRUE); |
|
885 } |
|
886 |
|
887 //go through all configs, add passed configs to return list |
|
888 //TODO take alpha mask size into account |
|
889 EGLConfig found[EGL_NUMCONFIGS]; |
|
890 int keys[EGL_NUMCONFIGS]; |
|
891 int numFound = 0; |
|
892 for (int i = 0; i < display->getNumConfigs(); i++) |
|
893 { |
|
894 const RIEGLConfig& c = display->getConfigByIdx(i); |
|
895 |
|
896 int colorBits = c.m_desc.redBits + c.m_desc.greenBits |
|
897 + c.m_desc.blueBits; |
|
898 int luminanceBits = c.m_desc.luminanceBits; |
|
899 int configBufferSize; |
|
900 if (colorBits) |
|
901 { |
|
902 RI_ASSERT(!luminanceBits); |
|
903 colorBits += c.m_desc.alphaBits; |
|
904 configBufferSize = colorBits; |
|
905 } |
|
906 else if (luminanceBits) |
|
907 { |
|
908 luminanceBits += c.m_desc.alphaBits; |
|
909 configBufferSize = luminanceBits; |
|
910 } |
|
911 else |
|
912 { //alpha only surface |
|
913 colorBits = c.m_desc.alphaBits; |
|
914 luminanceBits = c.m_desc.alphaBits; |
|
915 configBufferSize = colorBits; |
|
916 } |
|
917 |
|
918 if (smaller(configBufferSize, bufferSize)) |
|
919 continue; |
|
920 |
|
921 int configSampleBuffers = c.m_samples == 1 ? 0 : 1; |
|
922 if (smaller(configSampleBuffers, sampleBuffers)) |
|
923 continue; |
|
924 if (smaller(c.m_samples, samples)) |
|
925 continue; |
|
926 |
|
927 if (smaller(c.m_desc.redBits, redSize) || smaller(c.m_desc.greenBits, |
|
928 greenSize) || smaller(c.m_desc.blueBits, blueSize) || smaller( |
|
929 c.m_desc.alphaBits, alphaSize)) |
|
930 continue; |
|
931 |
|
932 if (smaller(c.m_desc.luminanceBits, luminanceSize)) |
|
933 continue; |
|
934 |
|
935 if ((colorBufferType == EGL_RGB_BUFFER && !colorBits) |
|
936 || (colorBufferType == EGL_LUMINANCE_BUFFER && !luminanceBits)) |
|
937 continue; |
|
938 |
|
939 int sortKey = c.m_configID; //sort from smaller to larger |
|
940 int sortBits = 0; |
|
941 if (redSize != 0 && redSize != EGL_DONT_CARE) |
|
942 sortBits += c.m_desc.redBits; |
|
943 if (greenSize != 0 && greenSize != EGL_DONT_CARE) |
|
944 sortBits += c.m_desc.greenBits; |
|
945 if (blueSize != 0 && blueSize != EGL_DONT_CARE) |
|
946 sortBits += c.m_desc.blueBits; |
|
947 if (alphaSize != 0 && alphaSize != EGL_DONT_CARE) |
|
948 sortBits += c.m_desc.alphaBits; |
|
949 if (luminanceSize != 0 && luminanceSize != EGL_DONT_CARE) |
|
950 sortBits += c.m_desc.luminanceBits; |
|
951 RI_ASSERT(c.m_configID <= EGL_NUMCONFIGS); //if there are more configs, increase the shift value |
|
952 RI_ASSERT(sortBits <= 32); |
|
953 sortKey += (32 - sortBits) << 4; //sort from larger to smaller |
|
954 |
|
955 found[numFound] = c.m_config; |
|
956 keys[numFound++] = sortKey; |
|
957 } |
|
958 if (!numFound) |
|
959 EGL_RETURN(EGL_SUCCESS, EGL_TRUE); |
|
960 |
|
961 //sort return list into increasing order |
|
962 for (int e = 0; e < numFound - 1; e++) |
|
963 { |
|
964 for (int f = e + 1; f < numFound; f++) |
|
965 { |
|
966 if (keys[e] > keys[f]) |
|
967 { |
|
968 EGLConfig tmp = found[e]; |
|
969 found[e] = found[f]; |
|
970 found[f] = tmp; |
|
971 RI_INT_SWAP(keys[e], keys[f]); |
|
972 } |
|
973 } |
|
974 } |
|
975 |
|
976 //write configs into return array |
|
977 numFound = RI_INT_MIN(numFound, config_size); |
|
978 for (int i = 0; i < numFound; i++) |
|
979 { |
|
980 configs[i] = found[i]; |
|
981 } |
|
982 *num_config = numFound; |
|
983 |
|
984 EGL_RETURN(EGL_SUCCESS, EGL_TRUE); |
|
985 } |
|
986 |
|
987 /*-------------------------------------------------------------------*//*! |
|
988 * \brief |
|
989 * \param |
|
990 * \return |
|
991 * \note |
|
992 *//*-------------------------------------------------------------------*/ |
|
993 |
|
994 #ifdef BUILD_WITH_PRIVATE_EGL |
|
995 RI_APIENTRY EGLBoolean do_eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, |
|
996 EGLint attribute, EGLint *value) |
|
997 #else |
|
998 EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) |
|
999 #endif |
|
1000 { |
|
1001 EGL_GET_DISPLAY(dpy, EGL_FALSE); |
|
1002 EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE); |
|
1003 EGL_IF_ERROR(!display->configExists(config), EGL_BAD_CONFIG, EGL_FALSE); |
|
1004 const RIEGLConfig& c = display->getConfig(config); |
|
1005 switch (attribute) |
|
1006 { |
|
1007 case EGL_BUFFER_SIZE: |
|
1008 *value = RI_INT_MAX(c.m_desc.redBits + c.m_desc.greenBits |
|
1009 + c.m_desc.blueBits + c.m_desc.alphaBits, |
|
1010 c.m_desc.luminanceBits + c.m_desc.alphaBits); |
|
1011 break; |
|
1012 |
|
1013 case EGL_RED_SIZE: |
|
1014 *value = c.m_desc.redBits; |
|
1015 break; |
|
1016 |
|
1017 case EGL_GREEN_SIZE: |
|
1018 *value = c.m_desc.greenBits; |
|
1019 break; |
|
1020 |
|
1021 case EGL_BLUE_SIZE: |
|
1022 *value = c.m_desc.blueBits; |
|
1023 break; |
|
1024 |
|
1025 case EGL_LUMINANCE_SIZE: |
|
1026 *value = c.m_desc.luminanceBits; |
|
1027 break; |
|
1028 |
|
1029 case EGL_ALPHA_SIZE: |
|
1030 *value = c.m_desc.alphaBits; |
|
1031 break; |
|
1032 |
|
1033 case EGL_ALPHA_MASK_SIZE: |
|
1034 *value = c.m_maskBits; |
|
1035 break; |
|
1036 |
|
1037 case EGL_BIND_TO_TEXTURE_RGB: |
|
1038 case EGL_BIND_TO_TEXTURE_RGBA: |
|
1039 *value = EGL_FALSE; |
|
1040 break; |
|
1041 |
|
1042 case EGL_COLOR_BUFFER_TYPE: |
|
1043 if (c.m_desc.redBits) |
|
1044 *value = EGL_RGB_BUFFER; |
|
1045 else |
|
1046 *value = EGL_LUMINANCE_BUFFER; |
|
1047 break; |
|
1048 |
|
1049 case EGL_CONFIG_CAVEAT: |
|
1050 *value = EGL_NONE; |
|
1051 break; |
|
1052 |
|
1053 case EGL_CONFIG_ID: |
|
1054 *value = c.m_configID; |
|
1055 break; |
|
1056 |
|
1057 case EGL_DEPTH_SIZE: |
|
1058 *value = 0; |
|
1059 break; |
|
1060 |
|
1061 case EGL_LEVEL: |
|
1062 *value = 0; |
|
1063 break; |
|
1064 |
|
1065 case EGL_MAX_PBUFFER_WIDTH: |
|
1066 case EGL_MAX_PBUFFER_HEIGHT: |
|
1067 *value = 16384; //NOTE arbitrary maximum |
|
1068 break; |
|
1069 |
|
1070 case EGL_MAX_PBUFFER_PIXELS: |
|
1071 *value = 16384 * 16384; //NOTE arbitrary maximum |
|
1072 break; |
|
1073 |
|
1074 case EGL_MAX_SWAP_INTERVAL: |
|
1075 case EGL_MIN_SWAP_INTERVAL: |
|
1076 *value = 1; |
|
1077 break; |
|
1078 |
|
1079 case EGL_NATIVE_RENDERABLE: |
|
1080 *value = EGL_FALSE; |
|
1081 break; |
|
1082 |
|
1083 case EGL_NATIVE_VISUAL_ID: |
|
1084 *value = 0; |
|
1085 break; |
|
1086 |
|
1087 case EGL_NATIVE_VISUAL_TYPE: |
|
1088 *value = EGL_NONE; |
|
1089 break; |
|
1090 |
|
1091 case EGL_RENDERABLE_TYPE: |
|
1092 *value = EGL_OPENVG_BIT; |
|
1093 break; |
|
1094 |
|
1095 case EGL_SAMPLE_BUFFERS: |
|
1096 *value = c.m_samples > 1 ? 1 : 0; |
|
1097 break; |
|
1098 |
|
1099 case EGL_SAMPLES: |
|
1100 *value = c.m_samples > 1 ? c.m_samples : 0; |
|
1101 break; |
|
1102 |
|
1103 case EGL_STENCIL_SIZE: |
|
1104 *value = 0; |
|
1105 break; |
|
1106 |
|
1107 case EGL_SURFACE_TYPE: |
|
1108 *value = EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT |
|
1109 | EGL_VG_COLORSPACE_LINEAR_BIT |
|
1110 | EGL_VG_ALPHA_FORMAT_PRE_BIT; |
|
1111 break; |
|
1112 |
|
1113 case EGL_TRANSPARENT_TYPE: |
|
1114 *value = EGL_NONE; |
|
1115 break; |
|
1116 |
|
1117 case EGL_TRANSPARENT_RED_VALUE: |
|
1118 case EGL_TRANSPARENT_GREEN_VALUE: |
|
1119 case EGL_TRANSPARENT_BLUE_VALUE: |
|
1120 *value = 0; |
|
1121 break; |
|
1122 |
|
1123 case EGL_CONFORMANT: |
|
1124 *value = EGL_OPENVG_BIT; //TODO return proper value |
|
1125 break; |
|
1126 |
|
1127 default: |
|
1128 EGL_RETURN(EGL_BAD_ATTRIBUTE, EGL_FALSE) |
|
1129 ; |
|
1130 } |
|
1131 EGL_RETURN(EGL_SUCCESS, EGL_TRUE); |
|
1132 } |
|
1133 |
|
1134 /*-------------------------------------------------------------------*//*! |
|
1135 * \brief |
|
1136 * \param |
|
1137 * \return |
|
1138 * \note |
|
1139 *//*-------------------------------------------------------------------*/ |
|
1140 |
|
1141 #ifdef BUILD_WITH_PRIVATE_EGL |
|
1142 RI_APIENTRY EGLSurface do_eglCreateWindowSurface(EGLDisplay dpy, |
|
1143 EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list) |
|
1144 #else |
|
1145 EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list) |
|
1146 #endif |
|
1147 { |
|
1148 EGL_GET_DISPLAY(dpy, EGL_NO_SURFACE); |
|
1149 EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_NO_SURFACE); |
|
1150 EGL_IF_ERROR(!display->configExists(config), EGL_BAD_CONFIG, EGL_NO_SURFACE); |
|
1151 |
|
1152 int renderBuffer = EGL_BACK_BUFFER; |
|
1153 int colorSpace = EGL_VG_COLORSPACE_sRGB; |
|
1154 int alphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE; |
|
1155 if (attrib_list) |
|
1156 { |
|
1157 for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) |
|
1158 { |
|
1159 switch (attrib_list[i]) |
|
1160 { |
|
1161 case EGL_RENDER_BUFFER: |
|
1162 renderBuffer = attrib_list[i + 1]; |
|
1163 break; |
|
1164 |
|
1165 case EGL_VG_COLORSPACE: |
|
1166 colorSpace = attrib_list[i + 1]; |
|
1167 break; |
|
1168 |
|
1169 case EGL_VG_ALPHA_FORMAT: |
|
1170 alphaFormat = attrib_list[i + 1]; |
|
1171 break; |
|
1172 |
|
1173 default: |
|
1174 EGL_RETURN(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE) |
|
1175 ; |
|
1176 } |
|
1177 } |
|
1178 } |
|
1179 //we ignore the renderBuffer parameter since we can only render to double buffered surfaces |
|
1180 |
|
1181 //TODO If the attributes of win do not correspond to config, then an EGL BAD MATCH error is generated. |
|
1182 //TODO If there is already an EGLConfig associated with win (as a result of a previous eglCreateWindowSurface call), then an EGL BAD ALLOC error is generated |
|
1183 |
|
1184 void* wc = NULL; |
|
1185 Drawable* d = NULL; |
|
1186 RIEGLSurface* s = NULL; |
|
1187 try |
|
1188 { |
|
1189 wc = OSCreateWindowContext(win); |
|
1190 RI_ASSERT(wc); |
|
1191 //TODO what should happen if window width or height is zero? |
|
1192 int windowWidth = 0, windowHeight = 0; |
|
1193 OSGetWindowSize(wc, windowWidth, windowHeight); |
|
1194 bool isWindow = OSIsWindow(wc); |
|
1195 if (windowWidth <= 0 || windowHeight <= 0 || !isWindow) |
|
1196 { |
|
1197 OSDestroyWindowContext(wc); |
|
1198 EGL_IF_ERROR(!isWindow, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); |
|
1199 EGL_IF_ERROR(windowWidth <= 0 || windowHeight <= 0, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); |
|
1200 } |
|
1201 d |
|
1202 = RI_NEW(Drawable, (display->getConfig(config).configToDescriptor((colorSpace == EGL_VG_COLORSPACE_LINEAR) ? false : true, (alphaFormat == EGL_VG_ALPHA_FORMAT_PRE) ? true : false), windowWidth, windowHeight, display->getConfig(config).m_samples, display->getConfig(config).m_maskBits)); //throws bad_alloc |
|
1203 RI_ASSERT(d); |
|
1204 s = RI_NEW(RIEGLSurface,(wc, config, d, false, renderBuffer)); //throws bad_alloc |
|
1205 RI_ASSERT(s); |
|
1206 s->addReference(); |
|
1207 display->addSurface(s); //throws bad_alloc |
|
1208 } |
|
1209 catch (std::bad_alloc) |
|
1210 { |
|
1211 OSDestroyWindowContext(wc); |
|
1212 RI_DELETE(d); |
|
1213 RI_DELETE(s); |
|
1214 EGL_RETURN(EGL_BAD_ALLOC, EGL_NO_SURFACE); |
|
1215 } |
|
1216 EGL_RETURN(EGL_SUCCESS, (EGLSurface)s); |
|
1217 } |
|
1218 |
|
1219 /*-------------------------------------------------------------------*//*! |
|
1220 * \brief |
|
1221 * \param |
|
1222 * \return |
|
1223 * \note |
|
1224 *//*-------------------------------------------------------------------*/ |
|
1225 |
|
1226 #ifdef BUILD_WITH_PRIVATE_EGL |
|
1227 RI_APIENTRY EGLSurface do_eglCreatePbufferSurface(EGLDisplay dpy, |
|
1228 EGLConfig config, const EGLint *attrib_list) |
|
1229 #else |
|
1230 EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) |
|
1231 #endif |
|
1232 { |
|
1233 EGL_GET_DISPLAY(dpy, EGL_NO_SURFACE); |
|
1234 EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_NO_SURFACE); |
|
1235 EGL_IF_ERROR(!display->configExists(config), EGL_BAD_CONFIG, EGL_NO_SURFACE); |
|
1236 |
|
1237 int width = 0, height = 0; |
|
1238 bool largestPbuffer = false; |
|
1239 int colorSpace = EGL_VG_COLORSPACE_sRGB; |
|
1240 int alphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE; |
|
1241 if (attrib_list) |
|
1242 { |
|
1243 for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) |
|
1244 { |
|
1245 switch (attrib_list[i]) |
|
1246 { |
|
1247 case EGL_WIDTH: |
|
1248 width = attrib_list[i + 1]; |
|
1249 break; |
|
1250 |
|
1251 case EGL_HEIGHT: |
|
1252 height = attrib_list[i + 1]; |
|
1253 break; |
|
1254 |
|
1255 case EGL_LARGEST_PBUFFER: |
|
1256 largestPbuffer = attrib_list[i + 1] ? true : false; |
|
1257 break; |
|
1258 |
|
1259 case EGL_VG_COLORSPACE: |
|
1260 colorSpace = attrib_list[i + 1]; |
|
1261 break; |
|
1262 |
|
1263 case EGL_VG_ALPHA_FORMAT: |
|
1264 alphaFormat = attrib_list[i + 1]; |
|
1265 break; |
|
1266 |
|
1267 case EGL_TEXTURE_FORMAT: //config doesn't support OpenGL ES |
|
1268 case EGL_TEXTURE_TARGET: //config doesn't support OpenGL ES |
|
1269 case EGL_MIPMAP_TEXTURE: //config doesn't support OpenGL ES |
|
1270 default: |
|
1271 EGL_RETURN(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE) |
|
1272 ; |
|
1273 } |
|
1274 } |
|
1275 } |
|
1276 EGL_IF_ERROR(width <= 0 || height <= 0, EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); |
|
1277 |
|
1278 Drawable* d = NULL; |
|
1279 RIEGLSurface* s = NULL; |
|
1280 try |
|
1281 { |
|
1282 d |
|
1283 = RI_NEW(Drawable, (display->getConfig(config).configToDescriptor((colorSpace == EGL_VG_COLORSPACE_LINEAR) ? false : true, (alphaFormat == EGL_VG_ALPHA_FORMAT_PRE) ? true : false), width, height, display->getConfig(config).m_samples, display->getConfig(config).m_maskBits)); //throws bad_alloc |
|
1284 RI_ASSERT(d); |
|
1285 s |
|
1286 = RI_NEW(RIEGLSurface,(NULL, config, d, largestPbuffer, EGL_BACK_BUFFER)); //throws bad_alloc |
|
1287 RI_ASSERT(s); |
|
1288 s->addReference(); |
|
1289 display->addSurface(s); //throws bad_alloc |
|
1290 } |
|
1291 catch (std::bad_alloc) |
|
1292 { |
|
1293 RI_DELETE(d); |
|
1294 RI_DELETE(s); |
|
1295 EGL_RETURN(EGL_BAD_ALLOC, EGL_NO_SURFACE); |
|
1296 } |
|
1297 EGL_RETURN(EGL_SUCCESS, (EGLSurface)s); |
|
1298 } |
|
1299 |
|
1300 /*-------------------------------------------------------------------*//*! |
|
1301 * \brief |
|
1302 * \param |
|
1303 * \return |
|
1304 * \note |
|
1305 *//*-------------------------------------------------------------------*/ |
|
1306 |
|
1307 #ifdef BUILD_WITH_PRIVATE_EGL |
|
1308 RI_APIENTRY EGLSurface do_eglCreatePbufferFromClientBuffer(EGLDisplay dpy, |
|
1309 EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, |
|
1310 const EGLint *attrib_list) |
|
1311 #else |
|
1312 EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list) |
|
1313 #endif |
|
1314 { |
|
1315 EGL_GET_DISPLAY(dpy, EGL_NO_SURFACE); |
|
1316 EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_NO_SURFACE); |
|
1317 EGL_IF_ERROR(buftype != EGL_OPENVG_IMAGE, EGL_BAD_PARAMETER, EGL_NO_SURFACE); |
|
1318 EGL_IF_ERROR(!buffer, EGL_BAD_PARAMETER, EGL_NO_SURFACE); //TODO should also check if buffer really is a valid VGImage object (needs VG context for that) |
|
1319 Image* image = (Image*) buffer; |
|
1320 EGL_IF_ERROR(image->isInUse(), EGL_BAD_ACCESS, EGL_NO_SURFACE); //buffer is in use by OpenVG |
|
1321 EGL_IF_ERROR(!display->configExists(config), EGL_BAD_CONFIG, EGL_NO_SURFACE); |
|
1322 EGL_IF_ERROR(attrib_list && attrib_list[0] != EGL_NONE, EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); //there are no valid attribs for OpenVG |
|
1323 const Color::Descriptor& bc = ((Image*) buffer)->getDescriptor(); |
|
1324 const Color::Descriptor& cc = display->getConfig(config).m_desc; |
|
1325 EGL_IF_ERROR(bc.redBits != cc.redBits || bc.greenBits != cc.greenBits || bc.blueBits != cc.blueBits || |
|
1326 bc.alphaBits != cc.alphaBits || bc.luminanceBits != cc.luminanceBits, EGL_BAD_MATCH, EGL_NO_SURFACE); |
|
1327 |
|
1328 //TODO If buffer is already bound to another pbuffer, an EGL BAD ACCESS error is generated. |
|
1329 |
|
1330 Drawable* d = NULL; |
|
1331 RIEGLSurface* s = NULL; |
|
1332 try |
|
1333 { |
|
1334 d = RI_NEW(Drawable, (image, display->getConfig(config).m_maskBits)); |
|
1335 RI_ASSERT(d); |
|
1336 s = RI_NEW(RIEGLSurface,(NULL, config, d, false, EGL_BACK_BUFFER)); //throws bad_alloc |
|
1337 RI_ASSERT(s); |
|
1338 s->addReference(); |
|
1339 display->addSurface(s); //throws bad_alloc |
|
1340 } |
|
1341 catch (std::bad_alloc) |
|
1342 { |
|
1343 RI_DELETE(d); |
|
1344 RI_DELETE(s); |
|
1345 EGL_RETURN(EGL_BAD_ALLOC, EGL_NO_SURFACE); |
|
1346 } |
|
1347 EGL_RETURN(EGL_SUCCESS, (EGLSurface)s); |
|
1348 } |
|
1349 |
|
1350 /*-------------------------------------------------------------------*//*! |
|
1351 * \brief |
|
1352 * \param |
|
1353 * \return |
|
1354 * \note |
|
1355 *//*-------------------------------------------------------------------*/ |
|
1356 |
|
1357 #ifdef BUILD_WITH_PRIVATE_EGL |
|
1358 RI_APIENTRY EGLSurface do_eglCreatePixmapSurface(EGLDisplay dpy, |
|
1359 EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list) |
|
1360 #else |
|
1361 EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list) |
|
1362 #endif |
|
1363 { |
|
1364 EGL_GET_DISPLAY(dpy, EGL_NO_SURFACE); |
|
1365 EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_NO_SURFACE); |
|
1366 EGL_IF_ERROR(!display->configExists(config), EGL_BAD_CONFIG, EGL_NO_SURFACE); |
|
1367 //EGL_IF_ERROR(!pixmap || !isValidImageFormat(pixmap->format) || !pixmap->data || pixmap->width <= 0 || pixmap->height <= 0, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE); |
|
1368 |
|
1369 RI_UNREF(attrib_list); |
|
1370 EGL_IF_ERROR(display->getConfig(config).m_samples != 1, EGL_BAD_MATCH, EGL_NO_SURFACE); |
|
1371 |
|
1372 //TODO If there is already an EGLSurface associated with pixmap (as a result of a previous eglCreatePixmapSurface call), then a EGL BAD ALLOC error is generated. |
|
1373 |
|
1374 |
|
1375 EGLint width = -1; |
|
1376 EGLint height = -1; |
|
1377 EGLint stride = -1; |
|
1378 VGImageFormat format; |
|
1379 int* data = NULL; |
|
1380 EGLBoolean err = OSGetNativePixmapInfo(pixmap, &width, &height, &stride, |
|
1381 &format, &data); |
|
1382 |
|
1383 Drawable* d = NULL; |
|
1384 RIEGLSurface* s = NULL; |
|
1385 try |
|
1386 { |
|
1387 d |
|
1388 = RI_NEW(Drawable, (Color::formatToDescriptor(format), width, height, stride, (RIuint8*)data, display->getConfig(config).m_maskBits)); //throws bad_alloc |
|
1389 RI_ASSERT(d); |
|
1390 s = RI_NEW(RIEGLSurface,(NULL, config, d, false, EGL_BACK_BUFFER)); //throws bad_alloc |
|
1391 RI_ASSERT(s); |
|
1392 s->addReference(); |
|
1393 display->addSurface(s); //throws bad_alloc |
|
1394 } |
|
1395 catch (std::bad_alloc) |
|
1396 { |
|
1397 RI_DELETE(d); |
|
1398 RI_DELETE(s); |
|
1399 EGL_RETURN(EGL_BAD_ALLOC, EGL_NO_SURFACE); |
|
1400 } |
|
1401 EGL_RETURN(EGL_SUCCESS, (EGLSurface)s); |
|
1402 |
|
1403 } |
|
1404 |
|
1405 /*-------------------------------------------------------------------*//*! |
|
1406 * \brief |
|
1407 * \param |
|
1408 * \return |
|
1409 * \note |
|
1410 *//*-------------------------------------------------------------------*/ |
|
1411 |
|
1412 #ifdef BUILD_WITH_PRIVATE_EGL |
|
1413 RI_APIENTRY EGLBoolean do_eglDestroySurface(EGLDisplay dpy, EGLSurface surface) |
|
1414 #else |
|
1415 EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface) |
|
1416 #endif |
|
1417 { |
|
1418 EGL_GET_DISPLAY(dpy, EGL_FALSE); |
|
1419 EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE); |
|
1420 EGL_IF_ERROR(!display->surfaceExists(surface), EGL_BAD_SURFACE, EGL_FALSE); |
|
1421 |
|
1422 display->removeSurface((RIEGLSurface*) surface); |
|
1423 if (!((RIEGLSurface*) surface)->removeReference()) |
|
1424 RI_DELETE((RIEGLSurface*)surface); |
|
1425 |
|
1426 EGL_RETURN(EGL_SUCCESS, EGL_TRUE); |
|
1427 } |
|
1428 |
|
1429 /*-------------------------------------------------------------------*//*! |
|
1430 * \brief |
|
1431 * \param |
|
1432 * \return |
|
1433 * \note |
|
1434 *//*-------------------------------------------------------------------*/ |
|
1435 |
|
1436 #ifdef BUILD_WITH_PRIVATE_EGL |
|
1437 RI_APIENTRY EGLBoolean do_eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, |
|
1438 EGLint attribute, EGLint value) |
|
1439 #else |
|
1440 EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) |
|
1441 #endif |
|
1442 { |
|
1443 EGL_GET_DISPLAY(dpy, EGL_FALSE); |
|
1444 EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE); |
|
1445 EGL_IF_ERROR(!display->surfaceExists(surface), EGL_BAD_SURFACE, EGL_FALSE); |
|
1446 RI_UNREF(attribute); |
|
1447 RI_UNREF(value); |
|
1448 //do nothing |
|
1449 EGL_RETURN(EGL_SUCCESS, EGL_TRUE); |
|
1450 } |
|
1451 |
|
1452 /*-------------------------------------------------------------------*//*! |
|
1453 * \brief |
|
1454 * \param |
|
1455 * \return |
|
1456 * \note |
|
1457 *//*-------------------------------------------------------------------*/ |
|
1458 |
|
1459 #ifdef BUILD_WITH_PRIVATE_EGL |
|
1460 RI_APIENTRY EGLBoolean do_eglQuerySurface(EGLDisplay dpy, EGLSurface surface, |
|
1461 EGLint attribute, EGLint *value) |
|
1462 #else |
|
1463 EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value) |
|
1464 #endif |
|
1465 { |
|
1466 EGL_GET_DISPLAY(dpy, EGL_FALSE); |
|
1467 EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE); |
|
1468 EGL_IF_ERROR(!display->surfaceExists(surface), EGL_BAD_SURFACE, EGL_FALSE); |
|
1469 //TODO give an error if value is NULL? |
|
1470 |
|
1471 RIEGLSurface* s = (RIEGLSurface*) surface; |
|
1472 switch (attribute) |
|
1473 { |
|
1474 case EGL_VG_ALPHA_FORMAT: |
|
1475 *value |
|
1476 = (s->getDrawable()->getDescriptor().isPremultiplied()) ? EGL_VG_ALPHA_FORMAT_PRE |
|
1477 : EGL_VG_ALPHA_FORMAT_NONPRE; |
|
1478 break; |
|
1479 |
|
1480 case EGL_VG_COLORSPACE: |
|
1481 *value |
|
1482 = (s->getDrawable()->getDescriptor().isNonlinear()) ? EGL_VG_COLORSPACE_sRGB |
|
1483 : EGL_VG_COLORSPACE_LINEAR; |
|
1484 break; |
|
1485 |
|
1486 case EGL_CONFIG_ID: |
|
1487 *value = display->getConfig(s->getConfig()).m_configID; |
|
1488 break; |
|
1489 |
|
1490 case EGL_HEIGHT: |
|
1491 *value = s->getDrawable()->getHeight(); |
|
1492 break; |
|
1493 |
|
1494 case EGL_HORIZONTAL_RESOLUTION: |
|
1495 *value = EGL_UNKNOWN; //TODO Horizontal dot pitch |
|
1496 break; |
|
1497 |
|
1498 case EGL_LARGEST_PBUFFER: |
|
1499 if (!s->getOSWindowContext()) |
|
1500 *value = s->isLargestPbuffer() ? EGL_TRUE : EGL_FALSE; |
|
1501 break; |
|
1502 |
|
1503 case EGL_MIPMAP_TEXTURE: |
|
1504 if (!s->getOSWindowContext()) |
|
1505 *value = EGL_FALSE; |
|
1506 break; |
|
1507 |
|
1508 case EGL_MIPMAP_LEVEL: |
|
1509 if (!s->getOSWindowContext()) |
|
1510 *value = 0; |
|
1511 break; |
|
1512 |
|
1513 case EGL_PIXEL_ASPECT_RATIO: |
|
1514 *value = EGL_UNKNOWN; //TODO Display aspect ratio |
|
1515 break; |
|
1516 |
|
1517 case EGL_RENDER_BUFFER: |
|
1518 *value = s->getRenderBuffer(); |
|
1519 break; |
|
1520 |
|
1521 case EGL_SWAP_BEHAVIOR: |
|
1522 *value = EGL_BUFFER_PRESERVED; |
|
1523 break; |
|
1524 |
|
1525 case EGL_TEXTURE_FORMAT: |
|
1526 if (!s->getOSWindowContext()) |
|
1527 *value = EGL_NO_TEXTURE; |
|
1528 break; |
|
1529 |
|
1530 case EGL_TEXTURE_TARGET: |
|
1531 if (!s->getOSWindowContext()) |
|
1532 *value = EGL_NO_TEXTURE; |
|
1533 break; |
|
1534 |
|
1535 case EGL_VERTICAL_RESOLUTION: |
|
1536 *value = EGL_UNKNOWN; //TODO Vertical dot pitch |
|
1537 break; |
|
1538 |
|
1539 case EGL_WIDTH: |
|
1540 *value = s->getDrawable()->getWidth(); |
|
1541 break; |
|
1542 |
|
1543 default: |
|
1544 EGL_RETURN(EGL_BAD_ATTRIBUTE, EGL_FALSE) |
|
1545 ; |
|
1546 } |
|
1547 EGL_RETURN(EGL_SUCCESS, EGL_TRUE); |
|
1548 } |
|
1549 |
|
1550 /*-------------------------------------------------------------------*//*! |
|
1551 * \brief |
|
1552 * \param |
|
1553 * \return |
|
1554 * \note |
|
1555 *//*-------------------------------------------------------------------*/ |
|
1556 |
|
1557 #ifdef BUILD_WITH_PRIVATE_EGL |
|
1558 RI_APIENTRY EGLContext do_eglCreateContext(EGLDisplay dpy, EGLConfig config, |
|
1559 EGLContext share_context, const EGLint *attrib_list) |
|
1560 #else |
|
1561 EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list) |
|
1562 #endif |
|
1563 { |
|
1564 EGL_GET_DISPLAY(dpy, EGL_NO_CONTEXT); |
|
1565 EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_NO_CONTEXT); |
|
1566 EGL_IF_ERROR(!display->configExists(config), EGL_BAD_CONFIG, EGL_NO_CONTEXT); |
|
1567 RI_UNREF(attrib_list); |
|
1568 |
|
1569 RIEGLThread* thread = egl->getThread(); |
|
1570 if (!thread) |
|
1571 EGL_RETURN(EGL_BAD_ALLOC, EGL_NO_CONTEXT); |
|
1572 |
|
1573 //creation of OpenGL ES contexts is not allowed in this implementation |
|
1574 if (thread->getBoundAPI() != EGL_OPENVG_API) |
|
1575 EGL_RETURN(EGL_BAD_MATCH, EGL_NO_CONTEXT); |
|
1576 |
|
1577 OpenVGRI::VGContext* vgctx = NULL; |
|
1578 RIEGLContext* c = NULL; |
|
1579 try |
|
1580 { |
|
1581 vgctx |
|
1582 = RI_NEW(OpenVGRI::VGContext, (share_context ? ((RIEGLContext*)share_context)->getVGContext() : NULL)); //throws bad_alloc |
|
1583 c = RI_NEW(RIEGLContext, (vgctx, config)); //throws bad_alloc |
|
1584 |
|
1585 RDebug::Printf(" ---------------------------- In eglCreateContext,VGContext addr is %x $$$$$$$$$$$$$ ",vgctx); |
|
1586 RDebug::Printf(" ---------------------------- In eglCreateContext,RIEGLContext addr is %x $$$$$$$$$$$$$ ",c); |
|
1587 c->addReference(); |
|
1588 display->addContext(c); //throws bad_alloc |
|
1589 } |
|
1590 catch (std::bad_alloc) |
|
1591 { |
|
1592 RI_DELETE(vgctx); |
|
1593 RI_DELETE(c); |
|
1594 EGL_RETURN(EGL_BAD_ALLOC, EGL_NO_CONTEXT); |
|
1595 } |
|
1596 |
|
1597 EGL_RETURN(EGL_SUCCESS, (EGLContext)c); |
|
1598 } |
|
1599 |
|
1600 /*-------------------------------------------------------------------*//*! |
|
1601 * \brief |
|
1602 * \param |
|
1603 * \return |
|
1604 * \note |
|
1605 *//*-------------------------------------------------------------------*/ |
|
1606 |
|
1607 #ifdef BUILD_WITH_PRIVATE_EGL |
|
1608 RI_APIENTRY EGLBoolean do_eglDestroyContext(EGLDisplay dpy, EGLContext ctx) |
|
1609 #else |
|
1610 EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) |
|
1611 #endif |
|
1612 { |
|
1613 EGL_GET_DISPLAY(dpy, EGL_FALSE); |
|
1614 EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE); |
|
1615 EGL_IF_ERROR(!display->contextExists(ctx), EGL_BAD_CONTEXT, EGL_FALSE); |
|
1616 |
|
1617 RIEGLContext* context = (RIEGLContext*) ctx; |
|
1618 display->removeContext(context); |
|
1619 if (!context->removeReference()) |
|
1620 RI_DELETE(context); |
|
1621 |
|
1622 EGL_RETURN(EGL_SUCCESS, EGL_TRUE); |
|
1623 } |
|
1624 |
|
1625 /*-------------------------------------------------------------------*//*! |
|
1626 * \brief |
|
1627 * \param |
|
1628 * \return |
|
1629 * \note |
|
1630 *//*-------------------------------------------------------------------*/ |
|
1631 |
|
1632 #ifdef BUILD_WITH_PRIVATE_EGL |
|
1633 RI_APIENTRY EGLBoolean do_eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, |
|
1634 EGLSurface read, EGLContext ctx) |
|
1635 #else |
|
1636 EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) |
|
1637 #endif |
|
1638 { |
|
1639 EGL_GET_DISPLAY(dpy, EGL_FALSE); |
|
1640 EGL_IF_ERROR(ctx != EGL_NO_CONTEXT && !display->contextExists(ctx), EGL_BAD_CONTEXT, EGL_FALSE); |
|
1641 EGL_IF_ERROR(draw != EGL_NO_SURFACE && !display->surfaceExists(draw), EGL_BAD_SURFACE, EGL_FALSE); |
|
1642 EGL_IF_ERROR(read != EGL_NO_SURFACE && !display->surfaceExists(read), EGL_BAD_SURFACE, EGL_FALSE); |
|
1643 EGL_IF_ERROR(draw != read, EGL_BAD_MATCH, EGL_FALSE); //TODO what's the proper error code? |
|
1644 EGL_IF_ERROR((draw != EGL_NO_SURFACE && ctx == EGL_NO_CONTEXT) || (draw == EGL_NO_SURFACE && ctx != EGL_NO_CONTEXT), EGL_BAD_MATCH, EGL_FALSE); |
|
1645 |
|
1646 RIEGLSurface* s = NULL; |
|
1647 RIEGLContext* c = NULL; |
|
1648 if (draw != EGL_NO_SURFACE && ctx != EGL_NO_CONTEXT) |
|
1649 { |
|
1650 EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE); |
|
1651 |
|
1652 s = (RIEGLSurface*) draw; |
|
1653 c = (RIEGLContext*) ctx; |
|
1654 |
|
1655 //If either draw or read are pbuffers created with eglCreatePbufferFromClientBuffer, and the underlying bound client API buffers |
|
1656 //are in use by the client API that created them, an EGL BAD ACCESS error is generated. |
|
1657 EGL_IF_ERROR(s->getDrawable()->isInUse(), EGL_BAD_ACCESS, EGL_FALSE); |
|
1658 |
|
1659 //TODO properly check compatibility of surface and context: |
|
1660 //-both have RGB or LUMINANCE configs |
|
1661 //-buffer bit depths match |
|
1662 //-configs support OpenVG |
|
1663 //-both have the same display |
|
1664 EGL_IF_ERROR(s->getConfig() != c->getConfig(), EGL_BAD_MATCH, EGL_FALSE); |
|
1665 //TODO check if context or surfaces are already bound to another thread |
|
1666 |
|
1667 //If a native window underlying either draw or read is no longer valid, an EGL BAD NATIVE WINDOW error is generated. |
|
1668 EGL_IF_ERROR(s->getOSWindowContext() && !OSIsWindow(s->getOSWindowContext()), EGL_BAD_NATIVE_WINDOW, EGL_FALSE); |
|
1669 |
|
1670 //TODO If the previous context of the calling display has unflushed commands, and the previous surface is no longer valid, an EGL BAD CURRENT SURFACE error is generated. (can this happen?) |
|
1671 //TODO If the ancillary buffers for draw and read cannot be allocated, an EGL BAD ALLOC error is generated. (mask buffer?) |
|
1672 } |
|
1673 |
|
1674 //check if the thread is current |
|
1675 RIEGLThread* thread = egl->getCurrentThread(); |
|
1676 if (thread) |
|
1677 { //thread is current, release the old bindinds and remove the thread from the current thread list |
|
1678 RIEGLContext* pc = thread->getCurrentContext(); |
|
1679 RIEGLSurface* ps = thread->getCurrentSurface(); |
|
1680 if (pc) |
|
1681 { |
|
1682 #ifdef BUILD_WITH_PRIVATE_OPENVG |
|
1683 do_vgFlush(); |
|
1684 #else |
|
1685 vgFlush(); |
|
1686 #endif |
|
1687 pc->getVGContext()->setDefaultDrawable(NULL); |
|
1688 if (!pc->removeReference()) |
|
1689 RI_DELETE(pc); |
|
1690 } |
|
1691 if (ps) |
|
1692 { |
|
1693 if (!ps->removeReference()) |
|
1694 RI_DELETE(ps); |
|
1695 } |
|
1696 |
|
1697 egl->removeCurrentThread(thread); |
|
1698 } |
|
1699 |
|
1700 if (c && s) |
|
1701 { |
|
1702 //bind context and surface to the current display |
|
1703 RIEGLThread* newThread = egl->getThread(); |
|
1704 if (!newThread) |
|
1705 EGL_RETURN(EGL_BAD_ALLOC, EGL_FALSE); |
|
1706 newThread->makeCurrent(c, s); |
|
1707 Drawable* temp = s->getDrawable(); |
|
1708 RDebug::Printf(" ------------------------------ In Drawable* temp,Drawable addr is %x $$$$$$$$$$$$$ ",temp); |
|
1709 c->getVGContext()->setDefaultDrawable(s->getDrawable()); |
|
1710 |
|
1711 try |
|
1712 { |
|
1713 egl->addCurrentThread(newThread); //throws bad_alloc |
|
1714 } |
|
1715 catch (std::bad_alloc) |
|
1716 { |
|
1717 EGL_RETURN(EGL_BAD_ALLOC, EGL_FALSE); |
|
1718 } |
|
1719 |
|
1720 c->addReference(); |
|
1721 s->addReference(); |
|
1722 } |
|
1723 EGL_RETURN(EGL_SUCCESS, EGL_TRUE); |
|
1724 } |
|
1725 |
|
1726 /*-------------------------------------------------------------------*//*! |
|
1727 * \brief |
|
1728 * \param |
|
1729 * \return |
|
1730 * \note |
|
1731 *//*-------------------------------------------------------------------*/ |
|
1732 |
|
1733 #ifdef BUILD_WITH_PRIVATE_EGL |
|
1734 RI_APIENTRY EGLContext do_eglGetCurrentContext() |
|
1735 #else |
|
1736 EGLContext eglGetCurrentContext() |
|
1737 #endif |
|
1738 { |
|
1739 EGL_GET_EGL(EGL_NO_CONTEXT); |
|
1740 EGLContext ret = EGL_NO_CONTEXT; |
|
1741 RIEGLThread* thread = egl->getCurrentThread(); |
|
1742 if (thread && thread->getBoundAPI() == EGL_OPENVG_API) |
|
1743 { |
|
1744 ret = CastFromRIEGLContext(thread->getCurrentContext()); |
|
1745 RI_ASSERT(ret); |
|
1746 } |
|
1747 EGL_RETURN(EGL_SUCCESS, ret); |
|
1748 } |
|
1749 |
|
1750 /*-------------------------------------------------------------------*//*! |
|
1751 * \brief |
|
1752 * \param |
|
1753 * \return |
|
1754 * \note |
|
1755 *//*-------------------------------------------------------------------*/ |
|
1756 |
|
1757 #ifdef BUILD_WITH_PRIVATE_EGL |
|
1758 RI_APIENTRY EGLSurface do_eglGetCurrentSurface(EGLint readdraw) |
|
1759 #else |
|
1760 EGLSurface eglGetCurrentSurface(EGLint readdraw) |
|
1761 #endif |
|
1762 { |
|
1763 EGL_GET_EGL(EGL_NO_SURFACE); |
|
1764 EGL_IF_ERROR(readdraw != EGL_READ && readdraw != EGL_DRAW, EGL_BAD_PARAMETER, EGL_NO_SURFACE); |
|
1765 EGLContext ret = EGL_NO_SURFACE; |
|
1766 RIEGLThread* thread = egl->getCurrentThread(); |
|
1767 if (thread && thread->getBoundAPI() == EGL_OPENVG_API) |
|
1768 { |
|
1769 ret = OpenVGRI::CastFromRIEGLSurface(thread->getCurrentSurface()); |
|
1770 RI_ASSERT(ret); |
|
1771 } |
|
1772 EGL_RETURN(EGL_SUCCESS, ret); |
|
1773 } |
|
1774 |
|
1775 /*-------------------------------------------------------------------*//*! |
|
1776 * \brief Returns the current display |
|
1777 * \param |
|
1778 * \return |
|
1779 * \note |
|
1780 *//*-------------------------------------------------------------------*/ |
|
1781 |
|
1782 #ifdef BUILD_WITH_PRIVATE_EGL |
|
1783 RI_APIENTRY EGLDisplay do_eglGetCurrentDisplay(void) |
|
1784 #else |
|
1785 EGLDisplay eglGetCurrentDisplay(void) |
|
1786 #endif |
|
1787 { |
|
1788 EGL_GET_EGL(EGL_NO_DISPLAY); |
|
1789 |
|
1790 RIEGLThread* thread = egl->getCurrentThread(); |
|
1791 if (!thread || thread->getBoundAPI() != EGL_OPENVG_API) |
|
1792 EGL_RETURN(EGL_SUCCESS, EGL_NO_DISPLAY); |
|
1793 |
|
1794 RIEGLContext* ctx = thread->getCurrentContext(); |
|
1795 RI_ASSERT(ctx); |
|
1796 EGLDisplay ret = egl->findDisplay(OpenVGRI::CastFromRIEGLContext(ctx)); |
|
1797 EGL_RETURN(EGL_SUCCESS, ret); |
|
1798 } |
|
1799 |
|
1800 /*-------------------------------------------------------------------*//*! |
|
1801 * \brief |
|
1802 * \param |
|
1803 * \return |
|
1804 * \note |
|
1805 *//*-------------------------------------------------------------------*/ |
|
1806 |
|
1807 #ifdef BUILD_WITH_PRIVATE_EGL |
|
1808 RI_APIENTRY EGLBoolean do_eglQueryContext(EGLDisplay dpy, EGLContext ctx, |
|
1809 EGLint attribute, EGLint* value) |
|
1810 #else |
|
1811 EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* value) |
|
1812 #endif |
|
1813 { |
|
1814 EGL_GET_DISPLAY(dpy, EGL_FALSE); |
|
1815 EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE); |
|
1816 EGL_IF_ERROR(!display->contextExists(ctx), EGL_BAD_CONTEXT, EGL_FALSE); |
|
1817 EGL_IF_ERROR(attribute != EGL_CONFIG_ID && attribute != EGL_CONTEXT_CLIENT_TYPE, EGL_BAD_ATTRIBUTE, EGL_FALSE); |
|
1818 if (attribute == EGL_CONFIG_ID) |
|
1819 *value |
|
1820 = display->getConfig(((RIEGLContext*) ctx)->getConfig()).m_configID; |
|
1821 if (attribute == EGL_CONTEXT_CLIENT_TYPE) |
|
1822 *value = EGL_OPENVG_API; |
|
1823 // \todo [kalle 05/Jul/05] Handling of EGL_RENDER_BUFFER attribute is missing. |
|
1824 EGL_RETURN(EGL_SUCCESS, EGL_TRUE); |
|
1825 } |
|
1826 |
|
1827 /*-------------------------------------------------------------------*//*! |
|
1828 * \brief |
|
1829 * \param |
|
1830 * \return |
|
1831 * \note |
|
1832 *//*-------------------------------------------------------------------*/ |
|
1833 |
|
1834 #ifdef BUILD_WITH_PRIVATE_EGL |
|
1835 RI_APIENTRY EGLBoolean do_eglBindAPI(EGLenum api) |
|
1836 #else |
|
1837 EGLBoolean eglBindAPI(EGLenum api) |
|
1838 #endif |
|
1839 { |
|
1840 EGL_GET_EGL(EGL_FALSE); |
|
1841 EGL_IF_ERROR(api != EGL_OPENVG_API && api != EGL_OPENGL_ES_API, EGL_BAD_PARAMETER, EGL_FALSE); |
|
1842 RIEGLThread* thread = egl->getThread(); |
|
1843 if (thread) |
|
1844 thread->bindAPI(api); |
|
1845 EGL_RETURN(EGL_SUCCESS, EGL_TRUE); |
|
1846 } |
|
1847 |
|
1848 /*-------------------------------------------------------------------*//*! |
|
1849 * \brief |
|
1850 * \param |
|
1851 * \return |
|
1852 * \note |
|
1853 *//*-------------------------------------------------------------------*/ |
|
1854 |
|
1855 #ifdef BUILD_WITH_PRIVATE_EGL |
|
1856 RI_APIENTRY EGLenum do_eglQueryAPI(void) |
|
1857 #else |
|
1858 EGLenum eglQueryAPI(void) |
|
1859 #endif |
|
1860 { |
|
1861 EGL_GET_EGL(EGL_NONE); |
|
1862 RIEGLThread* thread = egl->getThread(); |
|
1863 if (thread) |
|
1864 EGL_RETURN(EGL_SUCCESS, thread->getBoundAPI()); |
|
1865 EGL_RETURN(EGL_SUCCESS, EGL_NONE); |
|
1866 } |
|
1867 |
|
1868 /*-------------------------------------------------------------------*//*! |
|
1869 * \brief |
|
1870 * \param |
|
1871 * \return |
|
1872 * \note |
|
1873 *//*-------------------------------------------------------------------*/ |
|
1874 |
|
1875 #ifdef BUILD_WITH_PRIVATE_EGL |
|
1876 RI_APIENTRY EGLBoolean do_eglWaitClient() |
|
1877 #else |
|
1878 EGLBoolean eglWaitClient() |
|
1879 #endif |
|
1880 { |
|
1881 EGL_GET_EGL(EGL_FALSE); |
|
1882 RIEGLThread* thread = egl->getCurrentThread(); |
|
1883 if (thread && thread->getBoundAPI() == EGL_OPENVG_API) |
|
1884 #ifdef BUILD_WITH_PRIVATE_OPENVG |
|
1885 do_vgFinish(); |
|
1886 #else |
|
1887 vgFinish(); |
|
1888 #endif |
|
1889 EGL_RETURN(EGL_SUCCESS, EGL_TRUE); |
|
1890 } |
|
1891 |
|
1892 /*-------------------------------------------------------------------*//*! |
|
1893 * \brief Waits for OpenGL ES |
|
1894 * \param |
|
1895 * \return |
|
1896 * \note |
|
1897 *//*-------------------------------------------------------------------*/ |
|
1898 |
|
1899 #ifdef BUILD_WITH_PRIVATE_EGL |
|
1900 RI_APIENTRY EGLBoolean do_eglWaitGL(void) |
|
1901 #else |
|
1902 EGLBoolean eglWaitGL(void) |
|
1903 #endif |
|
1904 { |
|
1905 return EGL_TRUE; |
|
1906 } |
|
1907 |
|
1908 /*-------------------------------------------------------------------*//*! |
|
1909 * \brief |
|
1910 * \param |
|
1911 * \return |
|
1912 * \note We don't support native rendering |
|
1913 *//*-------------------------------------------------------------------*/ |
|
1914 |
|
1915 #ifdef BUILD_WITH_PRIVATE_EGL |
|
1916 RI_APIENTRY EGLBoolean do_eglWaitNative(EGLint engine) |
|
1917 #else |
|
1918 EGLBoolean eglWaitNative(EGLint engine) |
|
1919 #endif |
|
1920 { |
|
1921 RI_UNREF(engine); |
|
1922 return EGL_TRUE; |
|
1923 } |
|
1924 |
|
1925 /*-------------------------------------------------------------------*//*! |
|
1926 * \brief |
|
1927 * \param |
|
1928 * \return |
|
1929 * \note |
|
1930 *//*-------------------------------------------------------------------*/ |
|
1931 |
|
1932 #ifdef BUILD_WITH_PRIVATE_EGL |
|
1933 RI_APIENTRY EGLBoolean do_eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) |
|
1934 #else |
|
1935 EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) |
|
1936 #endif |
|
1937 { |
|
1938 EGL_GET_DISPLAY(dpy, EGL_FALSE); |
|
1939 EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE); |
|
1940 EGL_IF_ERROR(!display->surfaceExists(surface), EGL_BAD_SURFACE, EGL_FALSE); |
|
1941 |
|
1942 RIEGLSurface* s = (RIEGLSurface*) surface; |
|
1943 |
|
1944 RIEGLThread* currentThread = egl->getCurrentThread(); |
|
1945 EGL_IF_ERROR(!currentThread || currentThread->getCurrentSurface() != s, EGL_BAD_SURFACE, EGL_FALSE); |
|
1946 EGL_IF_ERROR(!OSIsWindow(s->getOSWindowContext()), EGL_BAD_NATIVE_WINDOW, EGL_FALSE); |
|
1947 |
|
1948 #ifdef BUILD_WITH_PRIVATE_OPENVG |
|
1949 do_vgFlush(); |
|
1950 #else |
|
1951 vgFlush(); |
|
1952 #endif |
|
1953 |
|
1954 if (!s->getOSWindowContext()) |
|
1955 { //do nothing for other than window surfaces (NOTE: single-buffered window surfaces should return immediately as well) |
|
1956 EGL_RETURN(EGL_SUCCESS, EGL_TRUE); |
|
1957 } |
|
1958 |
|
1959 int windowWidth = 0, windowHeight = 0; |
|
1960 OSGetWindowSize(s->getOSWindowContext(), windowWidth, windowHeight); |
|
1961 |
|
1962 if (windowWidth != s->getDrawable()->getWidth() || windowHeight |
|
1963 != s->getDrawable()->getHeight()) |
|
1964 { //resize the back buffer |
|
1965 RIEGLContext* c = currentThread->getCurrentContext(); |
|
1966 RI_ASSERT(c); |
|
1967 try |
|
1968 { |
|
1969 s->getDrawable()->resize(windowWidth, windowHeight); //throws bad_alloc |
|
1970 } |
|
1971 catch (std::bad_alloc) |
|
1972 { |
|
1973 c->getVGContext()->setDefaultDrawable(NULL); |
|
1974 EGL_RETURN(EGL_BAD_ALLOC, EGL_FALSE); |
|
1975 } |
|
1976 } |
|
1977 |
|
1978 OSBlitToWindow(s->getOSWindowContext(), s->getDrawable()); |
|
1979 |
|
1980 EGL_RETURN(EGL_SUCCESS, EGL_TRUE); |
|
1981 } |
|
1982 |
|
1983 /*-------------------------------------------------------------------*//*! |
|
1984 * \brief |
|
1985 * \param |
|
1986 * \return |
|
1987 * \note |
|
1988 *//*-------------------------------------------------------------------*/ |
|
1989 |
|
1990 #ifdef BUILD_WITH_PRIVATE_EGL |
|
1991 RI_APIENTRY EGLBoolean do_eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, |
|
1992 EGLNativePixmapType target) |
|
1993 #else |
|
1994 EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) |
|
1995 #endif |
|
1996 { |
|
1997 EGL_GET_DISPLAY(dpy, EGL_FALSE); |
|
1998 EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE); |
|
1999 EGL_IF_ERROR(!display->surfaceExists(surface), EGL_BAD_SURFACE, EGL_FALSE); |
|
2000 //EGL_IF_ERROR(!target || !isValidImageFormat(target->format) || !target->data || target->width <= 0 || target->height <= 0, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE); |
|
2001 EGLint width = -1; |
|
2002 EGLint height = -1; |
|
2003 EGLint stride = -1; |
|
2004 VGImageFormat format; |
|
2005 int* data = NULL; |
|
2006 EGLBoolean err = OSGetNativePixmapInfo(target, &width, &height, &stride, |
|
2007 &format, &data); |
|
2008 |
|
2009 TUint* fdata = (TUint*) ((TUint) data + (stride * (height - 1))); |
|
2010 try |
|
2011 { |
|
2012 Image output(Color::formatToDescriptor(format), width, height, -stride, |
|
2013 (RIuint8*) fdata); |
|
2014 output.addReference(); |
|
2015 output.blit(((RIEGLSurface*) surface)->getDrawable()->getColorBuffer(), |
|
2016 0, 0, 0, 0, width, height); //throws bad_alloc |
|
2017 output.removeReference(); |
|
2018 } |
|
2019 catch (std::bad_alloc) |
|
2020 { |
|
2021 } |
|
2022 EGL_RETURN(EGL_SUCCESS, EGL_TRUE); |
|
2023 |
|
2024 } |
|
2025 |
|
2026 /*-------------------------------------------------------------------*//*! |
|
2027 * \brief |
|
2028 * \param |
|
2029 * \return |
|
2030 * \note We support only swap interval one |
|
2031 *//*-------------------------------------------------------------------*/ |
|
2032 |
|
2033 #ifdef BUILD_WITH_PRIVATE_EGL |
|
2034 RI_APIENTRY EGLBoolean do_eglSwapInterval(EGLDisplay dpy, EGLint interval) |
|
2035 #else |
|
2036 EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) |
|
2037 #endif |
|
2038 { |
|
2039 EGL_GET_DISPLAY(dpy, EGL_FALSE); |
|
2040 EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE); |
|
2041 RI_UNREF(interval); |
|
2042 EGL_RETURN(EGL_SUCCESS, EGL_TRUE); |
|
2043 } |
|
2044 |
|
2045 /*-------------------------------------------------------------------*//*! |
|
2046 * \brief |
|
2047 * \param |
|
2048 * \return |
|
2049 * \note |
|
2050 *//*-------------------------------------------------------------------*/ |
|
2051 |
|
2052 typedef void RI_Proc(); |
|
2053 |
|
2054 //EGLAPI void (* EGLAPIENTRY eglGetProcAddress(const char *procname))(void); |
|
2055 |
|
2056 #ifdef BUILD_WITH_PRIVATE_EGL |
|
2057 RI_APIENTRY void (*do_eglGetProcAddress(const char *procname))(...) |
|
2058 #else |
|
2059 void (*eglGetProcAddress(const char *procname))(...) |
|
2060 #endif |
|
2061 { |
|
2062 if (!procname) |
|
2063 return NULL; |
|
2064 return NULL; |
|
2065 } |
|
2066 |
|
2067 /*-------------------------------------------------------------------*//*! |
|
2068 * \brief |
|
2069 * \param |
|
2070 * \return |
|
2071 * \note |
|
2072 *//*-------------------------------------------------------------------*/ |
|
2073 |
|
2074 #ifdef BUILD_WITH_PRIVATE_EGL |
|
2075 RI_APIENTRY EGLBoolean do_eglReleaseThread(void) |
|
2076 #else |
|
2077 EGLBoolean eglReleaseThread(void) |
|
2078 #endif |
|
2079 { |
|
2080 EGL_GET_EGL(EGL_FALSE); |
|
2081 |
|
2082 //check if the thread is current |
|
2083 RIEGLThread* thread = egl->getCurrentThread(); |
|
2084 if (thread) |
|
2085 { //thread is current, release the old bindings and remove the thread from the current thread list |
|
2086 RIEGLContext* pc = thread->getCurrentContext(); |
|
2087 RIEGLSurface* ps = thread->getCurrentSurface(); |
|
2088 if (pc) |
|
2089 { |
|
2090 #ifdef BUILD_WITH_PRIVATE_OPENVG |
|
2091 do_vgFlush(); |
|
2092 #else |
|
2093 vgFlush(); |
|
2094 #endif |
|
2095 pc->getVGContext()->setDefaultDrawable(NULL); |
|
2096 if (!pc->removeReference()) |
|
2097 RI_DELETE(pc); |
|
2098 } |
|
2099 if (ps) |
|
2100 { |
|
2101 if (!ps->removeReference()) |
|
2102 RI_DELETE(ps); |
|
2103 } |
|
2104 |
|
2105 egl->removeCurrentThread(thread); |
|
2106 } |
|
2107 |
|
2108 //destroy EGL's thread struct |
|
2109 egl->destroyThread(); |
|
2110 |
|
2111 //destroy the EGL instance |
|
2112 releaseEGL(); |
|
2113 |
|
2114 OSReleaseMutex(); |
|
2115 OSDeinitMutex(); |
|
2116 |
|
2117 return EGL_SUCCESS; |
|
2118 } |
|
2119 |
|
2120 #ifdef BUILD_WITH_PRIVATE_EGL |
|
2121 RI_APIENTRY EGLBoolean do_eglBindTexImage(EGLDisplay dpy, |
|
2122 EGLSurface surface, EGLint buffer) |
|
2123 #else |
|
2124 EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) |
|
2125 #endif |
|
2126 { |
|
2127 //not implemented |
|
2128 RI_ASSERT(0); |
|
2129 return false; |
|
2130 } |
|
2131 |
|
2132 #ifdef BUILD_WITH_PRIVATE_EGL |
|
2133 RI_APIENTRY EGLBoolean do_eglReleaseTexImage(EGLDisplay dpy, |
|
2134 EGLSurface surface, EGLint buffer) |
|
2135 #else |
|
2136 EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) |
|
2137 #endif |
|
2138 { |
|
2139 //not implemented |
|
2140 RI_ASSERT(0); |
|
2141 return false; |
|
2142 } |
|
2143 #undef EGL_NUMCONFIGS |
|
2144 |