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