|
1 #ifndef __RIMINIEGL_H |
|
2 #define __RIMINIEGL_H |
|
3 |
|
4 /*------------------------------------------------------------------------ |
|
5 * |
|
6 * EGL 1.3 |
|
7 * ------- |
|
8 * |
|
9 * Copyright (c) 2007 The Khronos Group Inc. |
|
10 * |
|
11 * Permission is hereby granted, free of charge, to any person obtaining a |
|
12 * copy of this software and /or associated documentation files |
|
13 * (the "Materials "), to deal in the Materials without restriction, |
|
14 * including without limitation the rights to use, copy, modify, merge, |
|
15 * publish, distribute, sublicense, and/or sell copies of the Materials, |
|
16 * and to permit persons to whom the Materials are furnished to do so, |
|
17 * subject to the following conditions: |
|
18 * |
|
19 * The above copyright notice and this permission notice shall be included |
|
20 * in all copies or substantial portions of the Materials. |
|
21 * |
|
22 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
23 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
|
25 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
|
26 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
|
27 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR |
|
28 * THE USE OR OTHER DEALINGS IN THE MATERIALS. |
|
29 * |
|
30 *//** |
|
31 * \file |
|
32 * \brief Simple implementation of EGL 1.3 |
|
33 * \note caveats: |
|
34 - always renders into the backbuffer and blits it to window (no single buffered rendering) |
|
35 - no native Windows or Mac OS X pixmap support |
|
36 - no power management events |
|
37 - no support for swap interval |
|
38 * \todo what happens in egl functions when eglTerminate has been called but the context and surface are still in use? |
|
39 * \todo OSDeinitMutex should be called in case getEGL fails. |
|
40 *//*-------------------------------------------------------------------*/ |
|
41 #include <e32std.h> |
|
42 #include "egl.h" |
|
43 #include "openvg.h" |
|
44 #include "riArray.h" |
|
45 #include "riMath.h" |
|
46 #include "riContext.h" |
|
47 #include "riImage.h" |
|
48 |
|
49 #ifdef BUILD_WITH_PRIVATE_EGL |
|
50 #include "eglinternal.h" |
|
51 #endif |
|
52 |
|
53 #ifdef BUILD_WITH_PRIVATE_OPENVG |
|
54 #include "openvginternal.h" |
|
55 #endif |
|
56 |
|
57 //============================================================================================== |
|
58 |
|
59 namespace OpenVGRI |
|
60 { |
|
61 void* OSGetCurrentThreadID(void); |
|
62 void OSAcquireMutex(void); |
|
63 void OSReleaseMutex(void); |
|
64 void OSDeinitMutex(void); |
|
65 |
|
66 EGLDisplay OSGetDisplay(EGLNativeDisplayType display_id); |
|
67 void* OSCreateWindowContext(EGLNativeWindowType window); |
|
68 void OSDestroyWindowContext(void* context); |
|
69 bool OSIsWindow(const void* context); |
|
70 void OSGetWindowSize(const void* context, int& width, int& height); |
|
71 void OSBlitToWindow(void* context, const Drawable* drawable); |
|
72 EGLBoolean OSGetNativePixmapInfo(NativePixmapType pixmap, int* width, int* height, int* stride, VGImageFormat* format, int** data); |
|
73 |
|
74 |
|
75 /*-------------------------------------------------------------------*//*! |
|
76 * \brief |
|
77 * \param |
|
78 * \return |
|
79 * \note |
|
80 *//*-------------------------------------------------------------------*/ |
|
81 |
|
82 class RIEGLConfig |
|
83 { |
|
84 public: |
|
85 RIEGLConfig() : m_desc(Color::formatToDescriptor(VG_sRGBA_8888)), m_configID(0) {} |
|
86 ~RIEGLConfig() {} |
|
87 void set(int r, int g, int b, int a, int l, int bpp, int samples, int maskBits, int ID) |
|
88 { |
|
89 m_desc.redBits = r; |
|
90 m_desc.greenBits = g; |
|
91 m_desc.blueBits = b; |
|
92 m_desc.alphaBits = a; |
|
93 m_desc.luminanceBits = l; |
|
94 m_desc.alphaShift = 0; |
|
95 m_desc.luminanceShift = 0; |
|
96 m_desc.blueShift = b ? a : 0; |
|
97 m_desc.greenShift = g ? a + b : 0; |
|
98 m_desc.redShift = r ? a + b + g : 0; |
|
99 m_desc.format = (VGImageFormat)-1; |
|
100 m_desc.internalFormat = l ? Color::sLA : Color::sRGBA; |
|
101 m_desc.bitsPerPixel = bpp; |
|
102 RI_ASSERT(Color::isValidDescriptor(m_desc)); |
|
103 m_samples = samples; |
|
104 m_maskBits = maskBits; |
|
105 m_configID = ID; |
|
106 m_config = (EGLConfig)ID; |
|
107 } |
|
108 |
|
109 Color::Descriptor configToDescriptor(bool sRGB, bool premultiplied) const |
|
110 { |
|
111 Color::Descriptor desc = m_desc; |
|
112 unsigned int f = m_desc.luminanceBits ? Color::LUMINANCE : 0; |
|
113 f |= sRGB ? Color::NONLINEAR : 0; |
|
114 f |= premultiplied ? Color::PREMULTIPLIED : 0; |
|
115 desc.internalFormat = (Color::InternalFormat)f; |
|
116 return desc; |
|
117 } |
|
118 |
|
119 //EGL RED SIZE bits of Red in the color buffer |
|
120 //EGL GREEN SIZE bits of Green in the color buffer |
|
121 //EGL BLUE SIZE bits of Blue in the color buffer |
|
122 //EGL ALPHA SIZE bits of Alpha in the color buffer |
|
123 //EGL LUMINANCE SIZE bits of Luminance in the color buffer |
|
124 Color::Descriptor m_desc; |
|
125 int m_samples; |
|
126 int m_maskBits; |
|
127 EGLint m_configID; //EGL CONFIG ID unique EGLConfig identifier |
|
128 EGLConfig m_config; |
|
129 //EGL BUFFER SIZE depth of the color buffer (sum of channel bits) |
|
130 //EGL ALPHA MASK SIZE number alpha mask bits (always 8) |
|
131 //EGL BIND TO TEXTURE RGB boolean True if bindable to RGB textures. (always EGL_FALSE) |
|
132 //EGL BIND TO TEXTURE RGBA boolean True if bindable to RGBA textures. (always EGL_FALSE) |
|
133 //EGL COLOR BUFFER TYPE enum color buffer type (EGL_RGB_BUFFER, EGL_LUMINANCE_BUFFER) |
|
134 //EGL CONFIG CAVEAT enum any caveats for the configuration (always EGL_NONE) |
|
135 //EGL DEPTH SIZE integer bits of Z in the depth buffer (always 0) |
|
136 //EGL LEVEL integer frame buffer level (always 0) |
|
137 //EGL MAX PBUFFER WIDTH integer maximum width of pbuffer (always INT_MAX) |
|
138 //EGL MAX PBUFFER HEIGHT integer maximum height of pbuffer (always INT_MAX) |
|
139 //EGL MAX PBUFFER PIXELS integer maximum size of pbuffer (always INT_MAX) |
|
140 //EGL MAX SWAP INTERVAL integer maximum swap interval (always 1) |
|
141 //EGL MIN SWAP INTERVAL integer minimum swap interval (always 1) |
|
142 //EGL NATIVE RENDERABLE boolean EGL TRUE if native rendering APIs can render to surface (always EGL_FALSE) |
|
143 //EGL NATIVE VISUAL ID integer handle of corresponding native visual (always 0) |
|
144 //EGL NATIVE VISUAL TYPE integer native visual type of the associated visual (always EGL_NONE) |
|
145 //EGL RENDERABLE TYPE bitmask which client rendering APIs are supported. (always EGL_OPENVG_BIT) |
|
146 //EGL SAMPLE BUFFERS integer number of multisample buffers (always 0) |
|
147 //EGL SAMPLES integer number of samples per pixel (always 0) |
|
148 //EGL STENCIL SIZE integer bits of Stencil in the stencil buffer (always 0) |
|
149 //EGL SURFACE TYPE bitmask which types of EGL surfaces are supported. (always EGL WINDOW BIT | EGL PIXMAP BIT | EGL PBUFFER BIT) |
|
150 //EGL TRANSPARENT TYPE enum type of transparency supported (always EGL_NONE) |
|
151 //EGL TRANSPARENT RED VALUE integer transparent red value (undefined) |
|
152 //EGL TRANSPARENT GREEN VALUE integer transparent green value (undefined) |
|
153 //EGL TRANSPARENT BLUE VALUE integer transparent blue value (undefined) |
|
154 }; |
|
155 |
|
156 /*-------------------------------------------------------------------*//*! |
|
157 * \brief |
|
158 * \param |
|
159 * \return |
|
160 * \note |
|
161 *//*-------------------------------------------------------------------*/ |
|
162 |
|
163 class RIEGLContext |
|
164 { |
|
165 public: |
|
166 RIEGLContext(OpenVGRI::VGContext* vgctx, const EGLConfig config); |
|
167 ~RIEGLContext(); |
|
168 void addReference() { m_referenceCount++; } |
|
169 int removeReference() { m_referenceCount--; RI_ASSERT(m_referenceCount >= 0); return m_referenceCount; } |
|
170 |
|
171 VGContext* getVGContext() const { return m_vgContext; } |
|
172 EGLConfig getConfig() const { return m_config; } |
|
173 private: |
|
174 RIEGLContext(const RIEGLContext&); |
|
175 RIEGLContext& operator=(const RIEGLContext&); |
|
176 VGContext* m_vgContext; |
|
177 const EGLConfig m_config; |
|
178 int m_referenceCount; |
|
179 }; |
|
180 |
|
181 RIEGLContext* CastToRIEGLContext(EGLContext aCtxId); |
|
182 EGLContext CastFromRIEGLContext(RIEGLContext* aCtx); |
|
183 |
|
184 /*-------------------------------------------------------------------*//*! |
|
185 * \brief |
|
186 * \param |
|
187 * \return |
|
188 * \note |
|
189 *//*-------------------------------------------------------------------*/ |
|
190 |
|
191 class RIEGLSurface |
|
192 { |
|
193 public: |
|
194 RIEGLSurface(void* OSWindowContext, const EGLConfig config, Drawable* drawable, bool largestPbuffer, int renderBuffer); |
|
195 ~RIEGLSurface(); |
|
196 void addReference() { m_referenceCount++; } |
|
197 int removeReference() { m_referenceCount--; RI_ASSERT(m_referenceCount >= 0); return m_referenceCount; } |
|
198 |
|
199 void* getOSWindowContext() const { return m_OSWindowContext; } |
|
200 EGLConfig getConfig() const { return m_config; } |
|
201 Drawable* getDrawable() const { return m_drawable; } |
|
202 bool isLargestPbuffer() const { return m_largestPbuffer; } |
|
203 int getRenderBuffer() const { return m_renderBuffer; } |
|
204 |
|
205 private: |
|
206 RIEGLSurface(const RIEGLSurface&); |
|
207 RIEGLSurface& operator=(const RIEGLSurface&); |
|
208 void* m_OSWindowContext; |
|
209 const EGLConfig m_config; |
|
210 Drawable* m_drawable; |
|
211 bool m_largestPbuffer; |
|
212 int m_renderBuffer; //EGL_BACK_BUFFER or EGL_SINGLE_BUFFER |
|
213 int m_referenceCount; |
|
214 }; |
|
215 |
|
216 RIEGLSurface* CastToRIEGLSurface(EGLSurface aSurfaceId); |
|
217 EGLSurface CastFromRIEGLSurface(RIEGLSurface* aSurface); |
|
218 |
|
219 /*-------------------------------------------------------------------*//*! |
|
220 * \brief |
|
221 * \param |
|
222 * \return |
|
223 * \note |
|
224 *//*-------------------------------------------------------------------*/ |
|
225 |
|
226 #define EGL_NUMCONFIGS 60 |
|
227 |
|
228 class RIEGLDisplay |
|
229 { |
|
230 public: |
|
231 RIEGLDisplay(EGLDisplay id); |
|
232 ~RIEGLDisplay(); |
|
233 |
|
234 int getNumConfigs() const { return EGL_NUMCONFIGS; } |
|
235 const RIEGLConfig& getConfigByIdx(int i) const { RI_ASSERT(i >= 0 && i < EGL_NUMCONFIGS); return m_configs[i]; } |
|
236 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]; } |
|
237 |
|
238 EGLDisplay getID() const { return m_id; } |
|
239 |
|
240 void addContext(RIEGLContext* ctx) { RI_ASSERT(ctx); m_contexts.push_back(ctx); } //throws bad_alloc |
|
241 void removeContext(RIEGLContext* ctx) { RI_ASSERT(ctx); bool res = m_contexts.remove(ctx); RI_ASSERT(res); RI_UNREF(res); } |
|
242 |
|
243 void addSurface(RIEGLSurface* srf) { RI_ASSERT(srf); m_surfaces.push_back(srf); } //throws bad_alloc |
|
244 void removeSurface(RIEGLSurface* srf) { RI_ASSERT(srf); bool res = m_surfaces.remove(srf); RI_ASSERT(res); RI_UNREF(res); } |
|
245 |
|
246 EGLBoolean contextExists(const EGLContext ctx) const; |
|
247 EGLBoolean surfaceExists(const EGLSurface srf) const; |
|
248 EGLBoolean configExists(const EGLConfig cfg) const; |
|
249 |
|
250 private: |
|
251 RIEGLDisplay(const RIEGLDisplay& t); |
|
252 RIEGLDisplay& operator=(const RIEGLDisplay&t); |
|
253 |
|
254 EGLDisplay m_id; |
|
255 |
|
256 Array<RIEGLContext*> m_contexts; |
|
257 Array<RIEGLSurface*> m_surfaces; |
|
258 |
|
259 RIEGLConfig m_configs[EGL_NUMCONFIGS]; |
|
260 }; |
|
261 |
|
262 |
|
263 /*-------------------------------------------------------------------*//*! |
|
264 * \brief |
|
265 * \param |
|
266 * \return |
|
267 * \note |
|
268 *//*-------------------------------------------------------------------*/ |
|
269 |
|
270 class RIEGLThread |
|
271 { |
|
272 public: |
|
273 RIEGLThread(void* currentThreadID); |
|
274 ~RIEGLThread(); |
|
275 |
|
276 void* getThreadID() const { return m_threadID; } |
|
277 |
|
278 void makeCurrent(RIEGLContext* c, RIEGLSurface* s) { m_context = c; m_surface = s; } |
|
279 RIEGLContext* getCurrentContext() const { return m_context; } |
|
280 RIEGLSurface* getCurrentSurface() const { return m_surface; } |
|
281 |
|
282 void setError(EGLint error) { m_error = error; } |
|
283 EGLint getError() const { return m_error; } |
|
284 |
|
285 void bindAPI(EGLint api) { m_boundAPI = api; } |
|
286 EGLint getBoundAPI() const { return m_boundAPI; } |
|
287 |
|
288 private: |
|
289 RIEGLThread(const RIEGLThread&); |
|
290 RIEGLThread operator=(const RIEGLThread&); |
|
291 |
|
292 RIEGLContext* m_context; |
|
293 RIEGLSurface* m_surface; |
|
294 EGLint m_error; |
|
295 void* m_threadID; |
|
296 EGLint m_boundAPI; |
|
297 }; |
|
298 |
|
299 |
|
300 Image* CastToImage(EGLClientBuffer aBufferId); |
|
301 EGLClientBuffer CastFromImage(Image* aBUffer); |
|
302 |
|
303 /*-------------------------------------------------------------------*//*! |
|
304 * \brief |
|
305 * \param |
|
306 * \return |
|
307 * \note |
|
308 *//*-------------------------------------------------------------------*/ |
|
309 |
|
310 class EGL |
|
311 { |
|
312 public: |
|
313 EGL(); |
|
314 ~EGL(); |
|
315 |
|
316 void addReference() { m_referenceCount++; } |
|
317 int removeReference() { m_referenceCount--; RI_ASSERT(m_referenceCount >= 0); return m_referenceCount; } |
|
318 |
|
319 void addDisplay(RIEGLDisplay* display) { RI_ASSERT(display); m_displays.push_back(display); } //throws bad alloc |
|
320 void removeDisplay(RIEGLDisplay* display) { RI_ASSERT(display); bool res = m_displays.remove(display); RI_ASSERT(res); RI_UNREF(res); } |
|
321 RIEGLDisplay* getDisplay(const EGLDisplay displayID) const; |
|
322 EGLDisplay findDisplay(const EGLContext ctx) const; |
|
323 |
|
324 void addCurrentThread(RIEGLThread* thread) { RI_ASSERT(thread); m_currentThreads.push_back(thread); } //throws bad alloc |
|
325 void removeCurrentThread(RIEGLThread* thread) { RI_ASSERT(thread); bool res = m_currentThreads.remove(thread); RI_ASSERT(res); RI_UNREF(res); } |
|
326 RIEGLThread* getCurrentThread() const; |
|
327 |
|
328 RIEGLThread* getThread(); |
|
329 void destroyThread(); |
|
330 |
|
331 bool isInUse(const void* image) const; |
|
332 |
|
333 private: |
|
334 EGL(const EGL&); // Not allowed. |
|
335 const EGL& operator=(const EGL&); // Not allowed. |
|
336 |
|
337 Array<RIEGLThread*> m_threads; //threads that have called EGL |
|
338 Array<RIEGLThread*> m_currentThreads; //threads that have a bound context |
|
339 Array<RIEGLDisplay*> m_displays; |
|
340 |
|
341 int m_referenceCount; |
|
342 }; |
|
343 |
|
344 |
|
345 void* eglvgGetCurrentVGContext(void); |
|
346 bool eglvgIsInUse(void* image); |
|
347 |
|
348 } //end of namespace |
|
349 |
|
350 |
|
351 /*-------------------------------------------------------------------*//*! |
|
352 * \brief |
|
353 * \param |
|
354 * \return |
|
355 * \note |
|
356 *//*-------------------------------------------------------------------*/ |
|
357 |
|
358 #define EGL_GET_DISPLAY(DISPLAY, RETVAL) \ |
|
359 OSAcquireMutex(); \ |
|
360 EGL* egl = getEGL(); \ |
|
361 if(!egl) \ |
|
362 { \ |
|
363 OSReleaseMutex(); \ |
|
364 return RETVAL; \ |
|
365 } \ |
|
366 RIEGLDisplay* display = egl->getDisplay(DISPLAY); \ |
|
367 |
|
368 #define EGL_GET_EGL(RETVAL) \ |
|
369 OSAcquireMutex(); \ |
|
370 EGL* egl = getEGL(); \ |
|
371 if(!egl) \ |
|
372 { \ |
|
373 OSReleaseMutex(); \ |
|
374 return RETVAL; \ |
|
375 } \ |
|
376 |
|
377 #define EGL_IF_ERROR(COND, ERRORCODE, RETVAL) \ |
|
378 if(COND) { eglSetError(egl, ERRORCODE); OSReleaseMutex(); return RETVAL; } \ |
|
379 |
|
380 #define EGL_RETURN(ERRORCODE, RETVAL) \ |
|
381 { \ |
|
382 eglSetError(egl, ERRORCODE); \ |
|
383 OSReleaseMutex(); \ |
|
384 return RETVAL; \ |
|
385 } |
|
386 |
|
387 //#undef EGL_NUMCONFIGS |
|
388 |
|
389 #endif /* __RIMINIEGL_H */ |
|
390 |
|
391 |