]> git.lizzy.rs Git - irrlicht.git/blob - source/Irrlicht/CEGLManager.cpp
Prefer static_cast to reinterpret_cast where possible.
[irrlicht.git] / source / Irrlicht / CEGLManager.cpp
1 // Copyright (C) 2013 Patryk Nadrowski\r
2 // This file is part of the "Irrlicht Engine".\r
3 // For conditions of distribution and use, see copyright notice in Irrlicht.h\r
4 \r
5 #include "CEGLManager.h"\r
6 \r
7 #ifdef _IRR_COMPILE_WITH_EGL_MANAGER_\r
8 \r
9 #include "irrString.h"\r
10 #include "irrArray.h"\r
11 #include "os.h"\r
12 #include <dlfcn.h>\r
13 \r
14 #if defined(_IRR_COMPILE_WITH_ANDROID_DEVICE_)\r
15 #include <android/native_activity.h>\r
16 #endif\r
17 \r
18 namespace irr\r
19 {\r
20 namespace video\r
21 {\r
22 \r
23 CEGLManager::CEGLManager() : IContextManager(), EglWindow(0), EglDisplay(EGL_NO_DISPLAY),\r
24     EglSurface(EGL_NO_SURFACE), EglContext(EGL_NO_CONTEXT), EglConfig(0), MajorVersion(0), MinorVersion(0), libHandle(NULL)\r
25 {\r
26         #ifdef _DEBUG\r
27         setDebugName("CEGLManager");\r
28         #endif\r
29 }\r
30 \r
31 CEGLManager::~CEGLManager()\r
32 {\r
33     destroyContext();\r
34     destroySurface();\r
35     terminate();\r
36 }\r
37 \r
38 bool CEGLManager::initialize(const SIrrlichtCreationParameters& params, const SExposedVideoData& data)\r
39 {\r
40         // store new data\r
41         Params=params;\r
42         Data=data;\r
43 \r
44         if (EglWindow != 0 && EglDisplay != EGL_NO_DISPLAY)\r
45         return true;\r
46 \r
47         // Window is depend on platform.\r
48 #if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)\r
49         EglWindow = (NativeWindowType)Data.OpenGLWin32.HWnd;\r
50         Data.OpenGLWin32.HDc = GetDC((HWND)EglWindow);\r
51         EglDisplay = eglGetDisplay((NativeDisplayType)Data.OpenGLWin32.HDc);\r
52 #elif defined(_IRR_EMSCRIPTEN_PLATFORM_)\r
53         EglWindow = 0;\r
54         EglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);\r
55 #elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)\r
56         EglWindow = (NativeWindowType)Data.OpenGLLinux.X11Window;\r
57         EglDisplay = eglGetDisplay((NativeDisplayType)Data.OpenGLLinux.X11Display);\r
58 #elif defined(_IRR_COMPILE_WITH_ANDROID_DEVICE_)\r
59         EglWindow =     (ANativeWindow*)Data.OGLESAndroid.Window;\r
60         EglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);\r
61 #elif defined(_IRR_COMPILE_WITH_FB_DEVICE_)\r
62         EglWindow = (NativeWindowType)Data.OpenGLFB.Window;\r
63         EglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);\r
64 #endif\r
65 \r
66         // We must check if EGL display is valid.\r
67         if (EglDisplay == EGL_NO_DISPLAY)\r
68     {\r
69                 os::Printer::log("Could not get EGL display.");\r
70                 terminate();\r
71         return false;\r
72     }\r
73 \r
74         // Initialize EGL here.\r
75         if (!eglInitialize(EglDisplay, &MajorVersion, &MinorVersion))\r
76     {\r
77                 os::Printer::log("Could not initialize EGL display.");\r
78 \r
79         EglDisplay = EGL_NO_DISPLAY;\r
80                 terminate();\r
81         return false;\r
82     }\r
83         else\r
84                 os::Printer::log("EGL version", core::stringc(MajorVersion+(MinorVersion*0.1f)).c_str());\r
85 \r
86     return true;\r
87 }\r
88 \r
89 void CEGLManager::terminate()\r
90 {\r
91         if (EglWindow == 0 && EglDisplay == EGL_NO_DISPLAY)\r
92                 return;\r
93 \r
94         if (EglDisplay != EGL_NO_DISPLAY)\r
95         {\r
96                 // We should unbind current EGL context before terminate EGL.\r
97                 eglMakeCurrent(EglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);\r
98 \r
99                 eglTerminate(EglDisplay);\r
100                 EglDisplay = EGL_NO_DISPLAY;\r
101         }\r
102 \r
103 #if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)\r
104         if (Data.OpenGLWin32.HDc)\r
105     {\r
106                 ReleaseDC((HWND)EglWindow, (HDC)Data.OpenGLWin32.HDc);\r
107         Data.OpenGLWin32.HDc = 0;\r
108     }\r
109 #endif\r
110 \r
111     MajorVersion = 0;\r
112     MinorVersion = 0;\r
113 \r
114         if (libHandle)\r
115                 dlclose(libHandle);\r
116 }\r
117 \r
118 bool CEGLManager::generateSurface()\r
119 {\r
120     if (EglDisplay == EGL_NO_DISPLAY)\r
121         return false;\r
122 \r
123     if (EglSurface != EGL_NO_SURFACE)\r
124         return true;\r
125 \r
126         // We should assign new WindowID on platforms, where WindowID may change at runtime,\r
127         // at this time only Android support this feature.\r
128         // this needs an update method instead!\r
129 \r
130 #if defined(_IRR_COMPILE_WITH_ANDROID_DEVICE_)\r
131         EglWindow = (ANativeWindow*)Data.OGLESAndroid.Window;\r
132 #endif\r
133 \r
134 #if defined(_IRR_EMSCRIPTEN_PLATFORM_)\r
135         // eglChooseConfig is currently only implemented as stub in emscripten (version 1.37.22 at point of writing)\r
136         // But the other solution would also be fine as it also only generates a single context so there is not much to choose from.\r
137         EglConfig = chooseConfig(ECS_IRR_CHOOSE);\r
138 #else\r
139         EglConfig = chooseConfig(ECS_EGL_CHOOSE_FIRST_LOWER_EXPECTATIONS);\r
140 #endif\r
141 \r
142         if ( EglConfig == 0 )\r
143         {\r
144                 os::Printer::log("Could not get config for EGL display.");\r
145                 return false;\r
146         }\r
147 \r
148 \r
149 #if defined(_IRR_COMPILE_WITH_ANDROID_DEVICE_)\r
150     EGLint Format = 0;\r
151     eglGetConfigAttrib(EglDisplay, EglConfig, EGL_NATIVE_VISUAL_ID, &Format);\r
152 \r
153     ANativeWindow_setBuffersGeometry(EglWindow, 0, 0, Format);\r
154 #endif\r
155 \r
156         // Now we are able to create EGL surface.\r
157         EglSurface = eglCreateWindowSurface(EglDisplay, EglConfig, EglWindow, 0);\r
158 \r
159         if (EGL_NO_SURFACE == EglSurface)\r
160                 EglSurface = eglCreateWindowSurface(EglDisplay, EglConfig, 0, 0);\r
161 \r
162         if (EGL_NO_SURFACE == EglSurface)\r
163                 os::Printer::log("Could not create EGL surface.");\r
164 \r
165 #ifdef EGL_VERSION_1_2\r
166         if (MinorVersion > 1)\r
167                 eglBindAPI(EGL_OPENGL_ES_API);\r
168 #endif\r
169 \r
170     if (Params.Vsync)\r
171                 eglSwapInterval(EglDisplay, 1);\r
172 \r
173     return true;\r
174 }\r
175 \r
176 EGLConfig CEGLManager::chooseConfig(EConfigStyle confStyle)\r
177 {\r
178         EGLConfig configResult = 0;\r
179 \r
180         // Find proper OpenGL BIT.\r
181         EGLint eglOpenGLBIT = 0;\r
182         switch (Params.DriverType)\r
183         {\r
184         case EDT_OGLES1:\r
185                 eglOpenGLBIT = EGL_OPENGL_ES_BIT;\r
186                 break;\r
187         case EDT_OGLES2:\r
188         case EDT_WEBGL1:\r
189                 eglOpenGLBIT = EGL_OPENGL_ES2_BIT;\r
190                 break;\r
191         default:\r
192                 break;\r
193         }\r
194 \r
195         if ( confStyle == ECS_EGL_CHOOSE_FIRST_LOWER_EXPECTATIONS )\r
196         {\r
197                 EGLint Attribs[] =\r
198                 {\r
199                         EGL_RED_SIZE, 8,\r
200                         EGL_GREEN_SIZE, 8,\r
201                         EGL_BLUE_SIZE, 8,\r
202                         EGL_ALPHA_SIZE, Params.WithAlphaChannel ? 1:0,\r
203                         EGL_BUFFER_SIZE, Params.Bits,\r
204                         EGL_SURFACE_TYPE, EGL_WINDOW_BIT,\r
205                         EGL_DEPTH_SIZE, Params.ZBufferBits,\r
206                         EGL_STENCIL_SIZE, Params.Stencilbuffer,\r
207                         EGL_SAMPLE_BUFFERS, Params.AntiAlias ? 1:0,\r
208                         EGL_SAMPLES, Params.AntiAlias,\r
209         #ifdef EGL_VERSION_1_3\r
210                         EGL_RENDERABLE_TYPE, eglOpenGLBIT,\r
211         #endif\r
212                         EGL_NONE, 0\r
213                 };\r
214 \r
215                 EGLint numConfigs = 0;\r
216                 u32 steps = 5;\r
217 \r
218                 // Choose the best EGL config.\r
219                         // TODO: We should also have a confStyle ECS_EGL_CHOOSE_CLOSEST\r
220                         //       which doesn't take first result of eglChooseConfigs,\r
221                         //       but the closest to requested parameters. eglChooseConfigs\r
222                         //       can return more than 1 result and first one might have\r
223                         //       "better" values than requested (more bits per pixel etc).\r
224                         //       So this returns the config which can do most, not the\r
225                         //       config which is closest to the requested parameters.\r
226                 //\r
227                 while (!eglChooseConfig(EglDisplay, Attribs, &configResult, 1, &numConfigs) || !numConfigs)\r
228                 {\r
229                         switch (steps)\r
230                         {\r
231                         case 5: // samples\r
232                                 if (Attribs[19] > 2)    // Params.AntiAlias\r
233                                         --Attribs[19];\r
234                                 else\r
235                                 {\r
236                                         Attribs[17] = 0;        // Params.Stencilbuffer\r
237                                         Attribs[19] = 0;        // Params.AntiAlias\r
238                                         --steps;\r
239                                 }\r
240                                 break;\r
241                         case 4: // alpha\r
242                                 if (Attribs[7]) // Params.WithAlphaChannel\r
243                                 {\r
244                                         Attribs[7] = 0;\r
245 \r
246                                         if (Params.AntiAlias)\r
247                                         {\r
248                                                 Attribs[17] = 1;\r
249                                                 Attribs[19] = Params.AntiAlias;\r
250                                                 steps = 5;\r
251                                         }\r
252                                 }\r
253                                 else\r
254                                         --steps;\r
255                                 break;\r
256                         case 3: // stencil\r
257                                 if (Attribs[15])        // Params.Stencilbuffer\r
258                                 {\r
259                                         Attribs[15] = 0;\r
260 \r
261                                         if (Params.AntiAlias)\r
262                                         {\r
263                                                 Attribs[17] = 1;\r
264                                                 Attribs[19] = Params.AntiAlias;\r
265                                                 steps = 5;\r
266                                         }\r
267                                 }\r
268                                 else\r
269                                         --steps;\r
270                                 break;\r
271                         case 2: // depth size\r
272                                 if (Attribs[13] > 16)   // Params.ZBufferBits\r
273                                 {\r
274                                         Attribs[13] -= 8;\r
275                                 }\r
276                                 else\r
277                                         --steps;\r
278                                 break;\r
279                         case 1: // buffer size\r
280                                 if (Attribs[9] > 16)    // Params.Bits\r
281                                 {\r
282                                         Attribs[9] -= 8;\r
283                                 }\r
284                                 else\r
285                                         --steps;\r
286                                 break;\r
287                         default:\r
288                                 return 0;\r
289                         }\r
290                 }\r
291 \r
292                 if (Params.AntiAlias && !Attribs[17])\r
293                         os::Printer::log("No multisampling.");\r
294 \r
295                 if (Params.WithAlphaChannel && !Attribs[7])\r
296                         os::Printer::log("No alpha.");\r
297 \r
298                 if (Params.Stencilbuffer && !Attribs[15])\r
299                         os::Printer::log("No stencil buffer.");\r
300 \r
301                 if (Params.ZBufferBits > Attribs[13])\r
302                         os::Printer::log("No full depth buffer.");\r
303 \r
304                 if (Params.Bits > Attribs[9])\r
305                         os::Printer::log("No full color buffer.");\r
306         }\r
307         else if ( confStyle == ECS_IRR_CHOOSE )\r
308         {\r
309                 // find number of available configs\r
310                 EGLint numConfigs;\r
311                 if ( eglGetConfigs( EglDisplay, NULL, 0, &numConfigs) == EGL_FALSE )\r
312                 {\r
313                         testEGLError();\r
314                         return 0;\r
315                 }\r
316 \r
317                 if ( numConfigs <= 0 )\r
318                         return 0;\r
319 \r
320                 // Get all available configs.\r
321                 EGLConfig * configs = new EGLConfig[numConfigs];\r
322                 if ( eglGetConfigs( EglDisplay, configs, numConfigs, &numConfigs) == EGL_FALSE )\r
323                 {\r
324                         testEGLError();\r
325                         return 0;\r
326                 }\r
327 \r
328                 // Find the best one.\r
329                 core::array<SConfigRating> ratings((u32)numConfigs);\r
330                 for ( u32 i=0; i < (u32)numConfigs; ++i )\r
331                 {\r
332                         SConfigRating r;\r
333                         r.config = configs[i];\r
334                         r.rating = rateConfig(r.config, eglOpenGLBIT);\r
335 \r
336                         if ( r.rating >= 0 )\r
337                                 ratings.push_back(r);\r
338                 }\r
339 \r
340                 if ( ratings.size() > 0 )\r
341                 {\r
342                         ratings.sort();\r
343                         configResult = ratings[0].config;\r
344 \r
345                         if ( ratings[0].rating != 0 )\r
346                         {\r
347                                 // This is just to print some log info (it also rates again while doing that, but rating is cheap enough, so that doesn't matter here).\r
348                                 rateConfig(ratings[0].config, eglOpenGLBIT, true);\r
349                         }\r
350                 }\r
351 \r
352                 delete[] configs;\r
353         }\r
354 \r
355         return configResult;\r
356 }\r
357 \r
358 irr::s32 CEGLManager::rateConfig(EGLConfig config, EGLint eglOpenGLBIT, bool log)\r
359 {\r
360         // some values must be there or we ignore the config\r
361 #ifdef EGL_VERSION_1_3\r
362         EGLint attribRenderableType = 0;\r
363         eglGetConfigAttrib( EglDisplay, config, EGL_RENDERABLE_TYPE, &attribRenderableType);\r
364         if  ( attribRenderableType != eglOpenGLBIT )\r
365         {\r
366                 if ( log )\r
367                         os::Printer::log("EGL_RENDERABLE_TYPE != eglOpenGLBIT");\r
368                 return -1;\r
369         }\r
370 #endif\r
371         EGLint attribSurfaceType = 0;\r
372         eglGetConfigAttrib( EglDisplay, config, EGL_SURFACE_TYPE, &attribSurfaceType);\r
373         if ( attribSurfaceType != EGL_WINDOW_BIT )\r
374         {\r
375                 if ( log )\r
376                         os::Printer::log("EGL_SURFACE_TYPE!= EGL_WINDOW_BIT");\r
377                 return -1;\r
378         }\r
379 \r
380         // Generally we give a really bad rating if attributes are worse than requested\r
381         // We give a slight worse rating if attributes are not exact as requested\r
382         // And we use some priorities which might make sense (but not really fine-tuned,\r
383         // so if you think other priorities would be better don't worry about changing the values.\r
384         int rating = 0;\r
385 \r
386         EGLint attribBufferSize = 0;\r
387         eglGetConfigAttrib( EglDisplay, config, EGL_BUFFER_SIZE, &attribBufferSize);\r
388         if ( attribBufferSize < Params.Bits )\r
389         {\r
390                 if ( log )\r
391                         os::Printer::log("No full color buffer.");\r
392                 rating += 100;\r
393         }\r
394         if ( attribBufferSize > Params.Bits )\r
395         {\r
396                 if ( log )\r
397                         os::Printer::log("Larger color buffer.", ELL_DEBUG);\r
398                 ++rating;\r
399         }\r
400 \r
401         EGLint attribRedSize = 0;\r
402         eglGetConfigAttrib( EglDisplay, config, EGL_RED_SIZE, &attribRedSize);\r
403         if ( attribRedSize < 5 && Params.Bits >= 4 )\r
404                 rating += 100;\r
405         else if ( attribRedSize < 8 && Params.Bits >= 24)\r
406                 rating += 10;\r
407         else if ( attribRedSize >= 8 && Params.Bits < 24 )\r
408                 rating ++;\r
409         EGLint attribGreenSize = 0;\r
410         eglGetConfigAttrib( EglDisplay, config, EGL_GREEN_SIZE, &attribGreenSize);\r
411         if ( attribGreenSize < 5 && Params.Bits >= 4 )\r
412                 rating += 100;\r
413         else if ( attribGreenSize < 8 && Params.Bits >= 24)\r
414                 rating += 10;\r
415         else if ( attribGreenSize >= 8 && Params.Bits < 24 )\r
416                 rating ++;\r
417         EGLint attribBlueSize = 0;\r
418         eglGetConfigAttrib( EglDisplay, config, EGL_BLUE_SIZE, &attribBlueSize);\r
419         if ( attribBlueSize < 5 && Params.Bits >= 4 )\r
420                 rating += 100;\r
421         else if ( attribBlueSize < 8 && Params.Bits >= 24)\r
422                 rating += 10;\r
423         else if ( attribBlueSize >= 8 && Params.Bits < 24 )\r
424                 rating ++;\r
425 \r
426         EGLint attribAlphaSize = 0;\r
427         eglGetConfigAttrib( EglDisplay, config, EGL_ALPHA_SIZE, &attribAlphaSize);\r
428         if ( Params.WithAlphaChannel && attribAlphaSize == 0 )\r
429         {\r
430                 if ( log )\r
431                         os::Printer::log("No alpha.");\r
432                 rating += 10;\r
433         }\r
434         else if ( !Params.WithAlphaChannel && attribAlphaSize > 0 )\r
435         {\r
436                 if ( log )\r
437                         os::Printer::log("Got alpha (unrequested).", ELL_DEBUG);\r
438                 rating ++;\r
439         }\r
440 \r
441         EGLint attribStencilSize = 0;\r
442         eglGetConfigAttrib( EglDisplay, config, EGL_STENCIL_SIZE, &attribStencilSize);\r
443         if ( Params.Stencilbuffer && attribStencilSize == 0 )\r
444         {\r
445                 if ( log )\r
446                         os::Printer::log("No stencil buffer.");\r
447                 rating += 10;\r
448         }\r
449         else if ( !Params.Stencilbuffer && attribStencilSize > 0 )\r
450         {\r
451                 if ( log )\r
452                         os::Printer::log("Got a stencil buffer (unrequested).", ELL_DEBUG);\r
453                 rating ++;\r
454         }\r
455 \r
456         EGLint attribDepthSize = 0;\r
457         eglGetConfigAttrib( EglDisplay, config, EGL_DEPTH_SIZE, &attribDepthSize);\r
458         if ( attribDepthSize < Params.ZBufferBits )\r
459         {\r
460                 if ( log )\r
461                 {\r
462                         if (attribDepthSize > 0)\r
463                                 os::Printer::log("No full depth buffer.");\r
464                         else\r
465                                 os::Printer::log("No depth buffer.");\r
466                 }\r
467                 rating += 50;\r
468         }\r
469         else if ( attribDepthSize != Params.ZBufferBits )\r
470         {\r
471                 if ( log )\r
472                 {\r
473                         if ( Params.ZBufferBits == 0 )\r
474                                 os::Printer::log("Got a depth buffer (unrequested).", ELL_DEBUG);\r
475                         else\r
476                                 os::Printer::log("Got a larger depth buffer.", ELL_DEBUG);\r
477                 }\r
478                 rating ++;\r
479         }\r
480 \r
481         EGLint attribSampleBuffers=0, attribSamples = 0;\r
482         eglGetConfigAttrib( EglDisplay, config, EGL_SAMPLE_BUFFERS, &attribSampleBuffers);\r
483         eglGetConfigAttrib( EglDisplay, config, EGL_SAMPLES, &attribSamples);\r
484         if ( Params.AntiAlias && attribSampleBuffers == 0 )\r
485         {\r
486                 if ( log )\r
487                         os::Printer::log("No multisampling.");\r
488                 rating += 20;\r
489         }\r
490         else if ( Params.AntiAlias && attribSampleBuffers && attribSamples < Params.AntiAlias )\r
491         {\r
492                 if ( log )\r
493                         os::Printer::log("Multisampling with less samples than requested.", ELL_DEBUG);\r
494                 rating += 10;\r
495         }\r
496         else if ( Params.AntiAlias && attribSampleBuffers && attribSamples > Params.AntiAlias )\r
497         {\r
498                 if ( log )\r
499                         os::Printer::log("Multisampling with more samples than requested.", ELL_DEBUG);\r
500                 rating += 5;\r
501         }\r
502         else if ( !Params.AntiAlias && attribSampleBuffers > 0 )\r
503         {\r
504                 if ( log )\r
505                         os::Printer::log("Got multisampling (unrequested).", ELL_DEBUG);\r
506                 rating += 3;\r
507         }\r
508 \r
509         return rating;\r
510 }\r
511 \r
512 void CEGLManager::destroySurface()\r
513 {\r
514         if (EglSurface == EGL_NO_SURFACE)\r
515                 return;\r
516 \r
517         // We should unbind current EGL context before destroy EGL surface.\r
518         eglMakeCurrent(EglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);\r
519 \r
520     eglDestroySurface(EglDisplay, EglSurface);\r
521     EglSurface = EGL_NO_SURFACE;\r
522 }\r
523 \r
524 bool CEGLManager::generateContext()\r
525 {\r
526         if (EglDisplay == EGL_NO_DISPLAY || EglSurface == EGL_NO_SURFACE)\r
527                 return false;\r
528 \r
529         if (EglContext != EGL_NO_CONTEXT)\r
530                 return true;\r
531 \r
532         EGLint OpenGLESVersion = 0;\r
533 \r
534         switch (Params.DriverType)\r
535         {\r
536         case EDT_OGLES1:\r
537                 OpenGLESVersion = 1;\r
538                 break;\r
539         case EDT_OGLES2:\r
540         case EDT_WEBGL1:\r
541                 OpenGLESVersion = 2;\r
542                 break;\r
543         default:\r
544                 break;\r
545         }\r
546 \r
547     EGLint ContextAttrib[] =\r
548         {\r
549 #ifdef EGL_VERSION_1_3\r
550                 EGL_CONTEXT_CLIENT_VERSION, OpenGLESVersion,\r
551 #endif\r
552                 EGL_NONE, 0\r
553         };\r
554 \r
555         EglContext = eglCreateContext(EglDisplay, EglConfig, EGL_NO_CONTEXT, ContextAttrib);\r
556 \r
557         if (testEGLError())\r
558         {\r
559                 os::Printer::log("Could not create EGL context.", ELL_ERROR);\r
560                 return false;\r
561         }\r
562 \r
563         os::Printer::log("EGL context created with OpenGLESVersion: ", core::stringc((int)OpenGLESVersion), ELL_DEBUG);\r
564 \r
565     return true;\r
566 }\r
567 \r
568 void CEGLManager::destroyContext()\r
569 {\r
570         if (EglContext == EGL_NO_CONTEXT)\r
571                 return;\r
572 \r
573         // We must unbind current EGL context before destroy it.\r
574         eglMakeCurrent(EglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);\r
575         eglDestroyContext(EglDisplay, EglContext);\r
576 \r
577     EglContext = EGL_NO_CONTEXT;\r
578 }\r
579 \r
580 bool CEGLManager::activateContext(const SExposedVideoData& videoData, bool restorePrimaryOnZero)\r
581 {\r
582         eglMakeCurrent(EglDisplay, EglSurface, EglSurface, EglContext);\r
583 \r
584         if (testEGLError())\r
585         {\r
586                 os::Printer::log("Could not make EGL context current.");\r
587                 return false;\r
588         }\r
589         return true;\r
590 }\r
591 \r
592 const SExposedVideoData& CEGLManager::getContext() const\r
593 {\r
594         return Data;\r
595 }\r
596 \r
597 void* CEGLManager::getProcAddress(const std::string &procName)\r
598 {\r
599         void* proc = NULL;\r
600         proc = (void*)eglGetProcAddress(procName.c_str());\r
601         if (!proc) { // fallback\r
602                 if (!libHandle)\r
603                         libHandle = dlopen("libGLESv2.so", RTLD_LAZY);\r
604                 if (libHandle)\r
605                         proc = dlsym(libHandle, procName.c_str());\r
606         }\r
607         return proc;\r
608 }\r
609 \r
610 bool CEGLManager::swapBuffers()\r
611 {\r
612     return (eglSwapBuffers(EglDisplay, EglSurface)==EGL_TRUE);\r
613 }\r
614 \r
615 bool CEGLManager::testEGLError()\r
616 {\r
617 #if defined(EGL_VERSION_1_0) && defined(_DEBUG)\r
618         EGLint status = eglGetError();\r
619 \r
620         switch (status)\r
621         {\r
622                 case EGL_SUCCESS:\r
623             return false;\r
624                 case EGL_NOT_INITIALIZED :\r
625                         os::Printer::log("Not Initialized", ELL_ERROR);\r
626             break;\r
627                 case EGL_BAD_ACCESS:\r
628                         os::Printer::log("Bad Access", ELL_ERROR);\r
629             break;\r
630                 case EGL_BAD_ALLOC:\r
631                         os::Printer::log("Bad Alloc", ELL_ERROR);\r
632             break;\r
633                 case EGL_BAD_ATTRIBUTE:\r
634                         os::Printer::log("Bad Attribute", ELL_ERROR);\r
635             break;\r
636                 case EGL_BAD_CONTEXT:\r
637                         os::Printer::log("Bad Context", ELL_ERROR);\r
638             break;\r
639                 case EGL_BAD_CONFIG:\r
640                         os::Printer::log("Bad Config", ELL_ERROR);\r
641             break;\r
642                 case EGL_BAD_CURRENT_SURFACE:\r
643                         os::Printer::log("Bad Current Surface", ELL_ERROR);\r
644             break;\r
645                 case EGL_BAD_DISPLAY:\r
646                         os::Printer::log("Bad Display", ELL_ERROR);\r
647             break;\r
648                 case EGL_BAD_SURFACE:\r
649                         os::Printer::log("Bad Surface", ELL_ERROR);\r
650             break;\r
651                 case EGL_BAD_MATCH:\r
652                         os::Printer::log("Bad Match", ELL_ERROR);\r
653             break;\r
654                 case EGL_BAD_PARAMETER:\r
655                         os::Printer::log("Bad Parameter", ELL_ERROR);\r
656             break;\r
657                 case EGL_BAD_NATIVE_PIXMAP:\r
658                         os::Printer::log("Bad Native Pixmap", ELL_ERROR);\r
659             break;\r
660                 case EGL_BAD_NATIVE_WINDOW:\r
661                         os::Printer::log("Bad Native Window", ELL_ERROR);\r
662             break;\r
663                 case EGL_CONTEXT_LOST:\r
664                         os::Printer::log("Context Lost", ELL_ERROR);\r
665             break;\r
666         default:\r
667             break;\r
668         };\r
669 \r
670         return true;\r
671 #else\r
672         return false;\r
673 #endif\r
674 }\r
675 \r
676 }\r
677 }\r
678 \r
679 #endif\r