1 /*
2   Simple DirectMedia Layer
3   Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
4 
5   This software is provided 'as-is', without any express or implied
6   warranty.  In no event will the authors be held liable for any damages
7   arising from the use of this software.
8 
9   Permission is granted to anyone to use this software for any purpose,
10   including commercial applications, and to alter it and redistribute it
11   freely, subject to the following restrictions:
12 
13   1. The origin of this software must not be misrepresented; you must not
14      claim that you wrote the original software. If you use this software
15      in a product, an acknowledgment in the product documentation would be
16      appreciated but is not required.
17   2. Altered source versions must be plainly marked as such, and must not be
18      misrepresented as being the original software.
19   3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../../SDL_internal.h"
22 
23 #if SDL_VIDEO_DRIVER_PANDORA
24 
25 /* SDL internals */
26 #include "../SDL_sysvideo.h"
27 #include "SDL_version.h"
28 #include "SDL_syswm.h"
29 #include "SDL_loadso.h"
30 #include "SDL_events.h"
31 #include "../../events/SDL_mouse_c.h"
32 #include "../../events/SDL_keyboard_c.h"
33 
34 /* PND declarations */
35 #include "SDL_pandora.h"
36 #include "SDL_pandora_events.h"
37 
38 /* WIZ declarations */
39 #include "GLES/gl.h"
40 #ifdef WIZ_GLES_LITE
41 static NativeWindowType hNativeWnd = 0; /* A handle to the window we will create. */
42 #endif
43 
44 static int
PND_available(void)45 PND_available(void)
46 {
47     return 1;
48 }
49 
50 static void
PND_destroy(SDL_VideoDevice * device)51 PND_destroy(SDL_VideoDevice * device)
52 {
53     if (device->driverdata != NULL) {
54         SDL_free(device->driverdata);
55         device->driverdata = NULL;
56     }
57     SDL_free(device);
58 }
59 
60 static SDL_VideoDevice *
PND_create()61 PND_create()
62 {
63     SDL_VideoDevice *device;
64     SDL_VideoData *phdata;
65     int status;
66 
67     /* Check if pandora could be initialized */
68     status = PND_available();
69     if (status == 0) {
70         /* PND could not be used */
71         return NULL;
72     }
73 
74     /* Initialize SDL_VideoDevice structure */
75     device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
76     if (device == NULL) {
77         SDL_OutOfMemory();
78         return NULL;
79     }
80 
81     /* Initialize internal Pandora specific data */
82     phdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
83     if (phdata == NULL) {
84         SDL_OutOfMemory();
85         SDL_free(device);
86         return NULL;
87     }
88 
89     device->driverdata = phdata;
90 
91     phdata->egl_initialized = SDL_TRUE;
92 
93 
94     /* Setup amount of available displays */
95     device->num_displays = 0;
96 
97     /* Set device free function */
98     device->free = PND_destroy;
99 
100     /* Setup all functions which we can handle */
101     device->VideoInit = PND_videoinit;
102     device->VideoQuit = PND_videoquit;
103     device->GetDisplayModes = PND_getdisplaymodes;
104     device->SetDisplayMode = PND_setdisplaymode;
105     device->CreateWindow = PND_createwindow;
106     device->CreateWindowFrom = PND_createwindowfrom;
107     device->SetWindowTitle = PND_setwindowtitle;
108     device->SetWindowIcon = PND_setwindowicon;
109     device->SetWindowPosition = PND_setwindowposition;
110     device->SetWindowSize = PND_setwindowsize;
111     device->ShowWindow = PND_showwindow;
112     device->HideWindow = PND_hidewindow;
113     device->RaiseWindow = PND_raisewindow;
114     device->MaximizeWindow = PND_maximizewindow;
115     device->MinimizeWindow = PND_minimizewindow;
116     device->RestoreWindow = PND_restorewindow;
117     device->SetWindowGrab = PND_setwindowgrab;
118     device->DestroyWindow = PND_destroywindow;
119     device->GetWindowWMInfo = PND_getwindowwminfo;
120     device->GL_LoadLibrary = PND_gl_loadlibrary;
121     device->GL_GetProcAddress = PND_gl_getprocaddres;
122     device->GL_UnloadLibrary = PND_gl_unloadlibrary;
123     device->GL_CreateContext = PND_gl_createcontext;
124     device->GL_MakeCurrent = PND_gl_makecurrent;
125     device->GL_SetSwapInterval = PND_gl_setswapinterval;
126     device->GL_GetSwapInterval = PND_gl_getswapinterval;
127     device->GL_SwapWindow = PND_gl_swapwindow;
128     device->GL_DeleteContext = PND_gl_deletecontext;
129     device->PumpEvents = PND_PumpEvents;
130 
131     /* !!! FIXME: implement SetWindowBordered */
132 
133     return device;
134 }
135 
136 VideoBootStrap PND_bootstrap = {
137 #ifdef WIZ_GLES_LITE
138     "wiz",
139     "SDL Wiz Video Driver",
140 #else
141     "pandora",
142     "SDL Pandora Video Driver",
143 #endif
144     PND_available,
145     PND_create
146 };
147 
148 /*****************************************************************************/
149 /* SDL Video and Display initialization/handling functions                   */
150 /*****************************************************************************/
151 int
PND_videoinit(_THIS)152 PND_videoinit(_THIS)
153 {
154     SDL_VideoDisplay display;
155     SDL_DisplayMode current_mode;
156 
157     SDL_zero(current_mode);
158 #ifdef WIZ_GLES_LITE
159     current_mode.w = 320;
160     current_mode.h = 240;
161 #else
162     current_mode.w = 800;
163     current_mode.h = 480;
164 #endif
165     current_mode.refresh_rate = 60;
166     current_mode.format = SDL_PIXELFORMAT_RGB565;
167     current_mode.driverdata = NULL;
168 
169     SDL_zero(display);
170     display.desktop_mode = current_mode;
171     display.current_mode = current_mode;
172     display.driverdata = NULL;
173 
174     SDL_AddVideoDisplay(&display);
175 
176     return 1;
177 }
178 
179 void
PND_videoquit(_THIS)180 PND_videoquit(_THIS)
181 {
182 
183 }
184 
185 void
PND_getdisplaymodes(_THIS,SDL_VideoDisplay * display)186 PND_getdisplaymodes(_THIS, SDL_VideoDisplay * display)
187 {
188 
189 }
190 
191 int
PND_setdisplaymode(_THIS,SDL_VideoDisplay * display,SDL_DisplayMode * mode)192 PND_setdisplaymode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
193 {
194     return 0;
195 }
196 
197 int
PND_createwindow(_THIS,SDL_Window * window)198 PND_createwindow(_THIS, SDL_Window * window)
199 {
200     SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
201 
202     SDL_WindowData *wdata;
203 
204     /* Allocate window internal data */
205     wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
206     if (wdata == NULL) {
207         return SDL_OutOfMemory();
208     }
209 
210     /* Setup driver data for this window */
211     window->driverdata = wdata;
212 
213     /* Check if window must support OpenGL ES rendering */
214     if ((window->flags & SDL_WINDOW_OPENGL) == SDL_WINDOW_OPENGL) {
215 
216         EGLBoolean initstatus;
217 
218         /* Mark this window as OpenGL ES compatible */
219         wdata->uses_gles = SDL_TRUE;
220 
221         /* Create connection to OpenGL ES */
222         if (phdata->egl_display == EGL_NO_DISPLAY) {
223             phdata->egl_display = eglGetDisplay((NativeDisplayType) 0);
224             if (phdata->egl_display == EGL_NO_DISPLAY) {
225                 return SDL_SetError("PND: Can't get connection to OpenGL ES");
226             }
227 
228             initstatus = eglInitialize(phdata->egl_display, NULL, NULL);
229             if (initstatus != EGL_TRUE) {
230                 return SDL_SetError("PND: Can't init OpenGL ES library");
231             }
232         }
233 
234         phdata->egl_refcount++;
235     }
236 
237     /* Window has been successfully created */
238     return 0;
239 }
240 
241 int
PND_createwindowfrom(_THIS,SDL_Window * window,const void * data)242 PND_createwindowfrom(_THIS, SDL_Window * window, const void *data)
243 {
244     return -1;
245 }
246 
247 void
PND_setwindowtitle(_THIS,SDL_Window * window)248 PND_setwindowtitle(_THIS, SDL_Window * window)
249 {
250 }
251 void
PND_setwindowicon(_THIS,SDL_Window * window,SDL_Surface * icon)252 PND_setwindowicon(_THIS, SDL_Window * window, SDL_Surface * icon)
253 {
254 }
255 void
PND_setwindowposition(_THIS,SDL_Window * window)256 PND_setwindowposition(_THIS, SDL_Window * window)
257 {
258 }
259 void
PND_setwindowsize(_THIS,SDL_Window * window)260 PND_setwindowsize(_THIS, SDL_Window * window)
261 {
262 }
263 void
PND_showwindow(_THIS,SDL_Window * window)264 PND_showwindow(_THIS, SDL_Window * window)
265 {
266 }
267 void
PND_hidewindow(_THIS,SDL_Window * window)268 PND_hidewindow(_THIS, SDL_Window * window)
269 {
270 }
271 void
PND_raisewindow(_THIS,SDL_Window * window)272 PND_raisewindow(_THIS, SDL_Window * window)
273 {
274 }
275 void
PND_maximizewindow(_THIS,SDL_Window * window)276 PND_maximizewindow(_THIS, SDL_Window * window)
277 {
278 }
279 void
PND_minimizewindow(_THIS,SDL_Window * window)280 PND_minimizewindow(_THIS, SDL_Window * window)
281 {
282 }
283 void
PND_restorewindow(_THIS,SDL_Window * window)284 PND_restorewindow(_THIS, SDL_Window * window)
285 {
286 }
287 void
PND_setwindowgrab(_THIS,SDL_Window * window,SDL_bool grabbed)288 PND_setwindowgrab(_THIS, SDL_Window * window, SDL_bool grabbed)
289 {
290 }
291 void
PND_destroywindow(_THIS,SDL_Window * window)292 PND_destroywindow(_THIS, SDL_Window * window)
293 {
294     SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
295     eglTerminate(phdata->egl_display);
296 }
297 
298 /*****************************************************************************/
299 /* SDL Window Manager function                                               */
300 /*****************************************************************************/
301 SDL_bool
PND_getwindowwminfo(_THIS,SDL_Window * window,struct SDL_SysWMinfo * info)302 PND_getwindowwminfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
303 {
304     if (info->version.major <= SDL_MAJOR_VERSION) {
305         return SDL_TRUE;
306     } else {
307         SDL_SetError("application not compiled with SDL %d.%d\n",
308                      SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
309         return SDL_FALSE;
310     }
311 
312     /* Failed to get window manager information */
313     return SDL_FALSE;
314 }
315 
316 /*****************************************************************************/
317 /* SDL OpenGL/OpenGL ES functions                                            */
318 /*****************************************************************************/
319 int
PND_gl_loadlibrary(_THIS,const char * path)320 PND_gl_loadlibrary(_THIS, const char *path)
321 {
322     /* Check if OpenGL ES library is specified for GF driver */
323     if (path == NULL) {
324         path = SDL_getenv("SDL_OPENGL_LIBRARY");
325         if (path == NULL) {
326             path = SDL_getenv("SDL_OPENGLES_LIBRARY");
327         }
328     }
329 
330     /* Check if default library loading requested */
331     if (path == NULL) {
332         /* Already linked with GF library which provides egl* subset of  */
333         /* functions, use Common profile of OpenGL ES library by default */
334 #ifdef WIZ_GLES_LITE
335     path = "/lib/libopengles_lite.so";
336 #else
337         path = "/usr/lib/libGLES_CM.so";
338 #endif
339     }
340 
341     /* Load dynamic library */
342     _this->gl_config.dll_handle = SDL_LoadObject(path);
343     if (!_this->gl_config.dll_handle) {
344         /* Failed to load new GL ES library */
345         return SDL_SetError("PND: Failed to locate OpenGL ES library");
346     }
347 
348     /* Store OpenGL ES library path and name */
349     SDL_strlcpy(_this->gl_config.driver_path, path,
350                 SDL_arraysize(_this->gl_config.driver_path));
351 
352     /* New OpenGL ES library is loaded */
353     return 0;
354 }
355 
356 void *
PND_gl_getprocaddres(_THIS,const char * proc)357 PND_gl_getprocaddres(_THIS, const char *proc)
358 {
359     void *function_address;
360 
361     /* Try to get function address through the egl interface */
362     function_address = eglGetProcAddress(proc);
363     if (function_address != NULL) {
364         return function_address;
365     }
366 
367     /* Then try to get function in the OpenGL ES library */
368     if (_this->gl_config.dll_handle) {
369         function_address =
370             SDL_LoadFunction(_this->gl_config.dll_handle, proc);
371         if (function_address != NULL) {
372             return function_address;
373         }
374     }
375 
376     /* Failed to get GL ES function address pointer */
377     SDL_SetError("PND: Cannot locate OpenGL ES function name");
378     return NULL;
379 }
380 
381 void
PND_gl_unloadlibrary(_THIS)382 PND_gl_unloadlibrary(_THIS)
383 {
384     SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
385 
386     if (phdata->egl_initialized == SDL_TRUE) {
387         /* Unload OpenGL ES library */
388         if (_this->gl_config.dll_handle) {
389             SDL_UnloadObject(_this->gl_config.dll_handle);
390             _this->gl_config.dll_handle = NULL;
391         }
392     } else {
393         SDL_SetError("PND: GF initialization failed, no OpenGL ES support");
394     }
395 }
396 
397 SDL_GLContext
PND_gl_createcontext(_THIS,SDL_Window * window)398 PND_gl_createcontext(_THIS, SDL_Window * window)
399 {
400     SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
401     SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
402     EGLBoolean status;
403     EGLint configs;
404     uint32_t attr_pos;
405     EGLint attr_value;
406     EGLint cit;
407 
408     /* Check if EGL was initialized */
409     if (phdata->egl_initialized != SDL_TRUE) {
410         SDL_SetError("PND: EGL initialization failed, no OpenGL ES support");
411         return NULL;
412     }
413 
414     /* Prepare attributes list to pass them to OpenGL ES */
415     attr_pos = 0;
416     wdata->gles_attributes[attr_pos++] = EGL_SURFACE_TYPE;
417     wdata->gles_attributes[attr_pos++] = EGL_WINDOW_BIT;
418     wdata->gles_attributes[attr_pos++] = EGL_RED_SIZE;
419     wdata->gles_attributes[attr_pos++] = _this->gl_config.red_size;
420     wdata->gles_attributes[attr_pos++] = EGL_GREEN_SIZE;
421     wdata->gles_attributes[attr_pos++] = _this->gl_config.green_size;
422     wdata->gles_attributes[attr_pos++] = EGL_BLUE_SIZE;
423     wdata->gles_attributes[attr_pos++] = _this->gl_config.blue_size;
424     wdata->gles_attributes[attr_pos++] = EGL_ALPHA_SIZE;
425 
426     /* Setup alpha size in bits */
427     if (_this->gl_config.alpha_size) {
428         wdata->gles_attributes[attr_pos++] = _this->gl_config.alpha_size;
429     } else {
430         wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
431     }
432 
433     /* Setup color buffer size */
434     if (_this->gl_config.buffer_size) {
435         wdata->gles_attributes[attr_pos++] = EGL_BUFFER_SIZE;
436         wdata->gles_attributes[attr_pos++] = _this->gl_config.buffer_size;
437     } else {
438         wdata->gles_attributes[attr_pos++] = EGL_BUFFER_SIZE;
439         wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
440     }
441 
442     /* Setup depth buffer bits */
443     wdata->gles_attributes[attr_pos++] = EGL_DEPTH_SIZE;
444     wdata->gles_attributes[attr_pos++] = _this->gl_config.depth_size;
445 
446     /* Setup stencil bits */
447     if (_this->gl_config.stencil_size) {
448         wdata->gles_attributes[attr_pos++] = EGL_STENCIL_SIZE;
449         wdata->gles_attributes[attr_pos++] = _this->gl_config.buffer_size;
450     } else {
451         wdata->gles_attributes[attr_pos++] = EGL_STENCIL_SIZE;
452         wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
453     }
454 
455     /* Set number of samples in multisampling */
456     if (_this->gl_config.multisamplesamples) {
457         wdata->gles_attributes[attr_pos++] = EGL_SAMPLES;
458         wdata->gles_attributes[attr_pos++] =
459             _this->gl_config.multisamplesamples;
460     }
461 
462     /* Multisample buffers, OpenGL ES 1.0 spec defines 0 or 1 buffer */
463     if (_this->gl_config.multisamplebuffers) {
464         wdata->gles_attributes[attr_pos++] = EGL_SAMPLE_BUFFERS;
465         wdata->gles_attributes[attr_pos++] =
466             _this->gl_config.multisamplebuffers;
467     }
468 
469     /* Finish attributes list */
470     wdata->gles_attributes[attr_pos] = EGL_NONE;
471 
472     /* Request first suitable framebuffer configuration */
473     status = eglChooseConfig(phdata->egl_display, wdata->gles_attributes,
474                              wdata->gles_configs, 1, &configs);
475     if (status != EGL_TRUE) {
476         SDL_SetError("PND: Can't find closest configuration for OpenGL ES");
477         return NULL;
478     }
479 
480     /* Check if nothing has been found, try "don't care" settings */
481     if (configs == 0) {
482         int32_t it;
483         int32_t jt;
484         GLint depthbits[4] = { 32, 24, 16, EGL_DONT_CARE };
485 
486         for (it = 0; it < 4; it++) {
487             for (jt = 16; jt >= 0; jt--) {
488                 /* Don't care about color buffer bits, use what exist */
489                 /* Replace previous set data with EGL_DONT_CARE       */
490                 attr_pos = 0;
491                 wdata->gles_attributes[attr_pos++] = EGL_SURFACE_TYPE;
492                 wdata->gles_attributes[attr_pos++] = EGL_WINDOW_BIT;
493                 wdata->gles_attributes[attr_pos++] = EGL_RED_SIZE;
494                 wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
495                 wdata->gles_attributes[attr_pos++] = EGL_GREEN_SIZE;
496                 wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
497                 wdata->gles_attributes[attr_pos++] = EGL_BLUE_SIZE;
498                 wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
499                 wdata->gles_attributes[attr_pos++] = EGL_ALPHA_SIZE;
500                 wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
501                 wdata->gles_attributes[attr_pos++] = EGL_BUFFER_SIZE;
502                 wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
503 
504                 /* Try to find requested or smallest depth */
505                 if (_this->gl_config.depth_size) {
506                     wdata->gles_attributes[attr_pos++] = EGL_DEPTH_SIZE;
507                     wdata->gles_attributes[attr_pos++] = depthbits[it];
508                 } else {
509                     wdata->gles_attributes[attr_pos++] = EGL_DEPTH_SIZE;
510                     wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
511                 }
512 
513                 if (_this->gl_config.stencil_size) {
514                     wdata->gles_attributes[attr_pos++] = EGL_STENCIL_SIZE;
515                     wdata->gles_attributes[attr_pos++] = jt;
516                 } else {
517                     wdata->gles_attributes[attr_pos++] = EGL_STENCIL_SIZE;
518                     wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
519                 }
520 
521                 wdata->gles_attributes[attr_pos++] = EGL_SAMPLES;
522                 wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
523                 wdata->gles_attributes[attr_pos++] = EGL_SAMPLE_BUFFERS;
524                 wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
525                 wdata->gles_attributes[attr_pos] = EGL_NONE;
526 
527                 /* Request first suitable framebuffer configuration */
528                 status =
529                     eglChooseConfig(phdata->egl_display,
530                                     wdata->gles_attributes,
531                                     wdata->gles_configs, 1, &configs);
532 
533                 if (status != EGL_TRUE) {
534                     SDL_SetError
535                         ("PND: Can't find closest configuration for OpenGL ES");
536                     return NULL;
537                 }
538                 if (configs != 0) {
539                     break;
540                 }
541             }
542             if (configs != 0) {
543                 break;
544             }
545         }
546 
547         /* No available configs */
548         if (configs == 0) {
549             SDL_SetError("PND: Can't find any configuration for OpenGL ES");
550             return NULL;
551         }
552     }
553 
554     /* Initialize config index */
555     wdata->gles_config = 0;
556 
557     /* Now check each configuration to find out the best */
558     for (cit = 0; cit < configs; cit++) {
559         uint32_t stencil_found;
560         uint32_t depth_found;
561 
562         stencil_found = 0;
563         depth_found = 0;
564 
565         if (_this->gl_config.stencil_size) {
566             status =
567                 eglGetConfigAttrib(phdata->egl_display,
568                                    wdata->gles_configs[cit], EGL_STENCIL_SIZE,
569                                    &attr_value);
570             if (status == EGL_TRUE) {
571                 if (attr_value != 0) {
572                     stencil_found = 1;
573                 }
574             }
575         } else {
576             stencil_found = 1;
577         }
578 
579         if (_this->gl_config.depth_size) {
580             status =
581                 eglGetConfigAttrib(phdata->egl_display,
582                                    wdata->gles_configs[cit], EGL_DEPTH_SIZE,
583                                    &attr_value);
584             if (status == EGL_TRUE) {
585                 if (attr_value != 0) {
586                     depth_found = 1;
587                 }
588             }
589         } else {
590             depth_found = 1;
591         }
592 
593         /* Exit from loop if found appropriate configuration */
594         if ((depth_found != 0) && (stencil_found != 0)) {
595             break;
596         }
597     }
598 
599     /* If best could not be found, use first */
600     if (cit == configs) {
601         cit = 0;
602     }
603     wdata->gles_config = cit;
604 
605     /* Create OpenGL ES context */
606     wdata->gles_context =
607         eglCreateContext(phdata->egl_display,
608                          wdata->gles_configs[wdata->gles_config], NULL, NULL);
609     if (wdata->gles_context == EGL_NO_CONTEXT) {
610         SDL_SetError("PND: OpenGL ES context creation has been failed");
611         return NULL;
612     }
613 
614 #ifdef WIZ_GLES_LITE
615     if( !hNativeWnd ) {
616     hNativeWnd = (NativeWindowType)malloc(16*1024);
617 
618     if(!hNativeWnd)
619         printf( "Error: Wiz framebuffer allocatation failed\n" );
620     else
621         printf( "SDL: Wiz framebuffer allocated: %X\n", hNativeWnd );
622     }
623     else {
624         printf( "SDL: Wiz framebuffer already allocated: %X\n", hNativeWnd );
625     }
626 
627     wdata->gles_surface =
628     eglCreateWindowSurface(phdata->egl_display,
629                    wdata->gles_configs[wdata->gles_config],
630                    hNativeWnd, NULL );
631 #else
632     wdata->gles_surface =
633         eglCreateWindowSurface(phdata->egl_display,
634                                wdata->gles_configs[wdata->gles_config],
635                                (NativeWindowType) 0, NULL);
636 #endif
637 
638 
639     if (wdata->gles_surface == 0) {
640         SDL_SetError("Error : eglCreateWindowSurface failed;\n");
641         return NULL;
642     }
643 
644     /* Make just created context current */
645     status =
646         eglMakeCurrent(phdata->egl_display, wdata->gles_surface,
647                        wdata->gles_surface, wdata->gles_context);
648     if (status != EGL_TRUE) {
649         /* Destroy OpenGL ES surface */
650         eglDestroySurface(phdata->egl_display, wdata->gles_surface);
651         eglDestroyContext(phdata->egl_display, wdata->gles_context);
652         wdata->gles_context = EGL_NO_CONTEXT;
653         SDL_SetError("PND: Can't set OpenGL ES context on creation");
654         return NULL;
655     }
656 
657     _this->gl_config.accelerated = 1;
658 
659     /* Always clear stereo enable, since OpenGL ES do not supports stereo */
660     _this->gl_config.stereo = 0;
661 
662     /* Get back samples and samplebuffers configurations. Rest framebuffer */
663     /* parameters could be obtained through the OpenGL ES API              */
664     status =
665         eglGetConfigAttrib(phdata->egl_display,
666                            wdata->gles_configs[wdata->gles_config],
667                            EGL_SAMPLES, &attr_value);
668     if (status == EGL_TRUE) {
669         _this->gl_config.multisamplesamples = attr_value;
670     }
671     status =
672         eglGetConfigAttrib(phdata->egl_display,
673                            wdata->gles_configs[wdata->gles_config],
674                            EGL_SAMPLE_BUFFERS, &attr_value);
675     if (status == EGL_TRUE) {
676         _this->gl_config.multisamplebuffers = attr_value;
677     }
678 
679     /* Get back stencil and depth buffer sizes */
680     status =
681         eglGetConfigAttrib(phdata->egl_display,
682                            wdata->gles_configs[wdata->gles_config],
683                            EGL_DEPTH_SIZE, &attr_value);
684     if (status == EGL_TRUE) {
685         _this->gl_config.depth_size = attr_value;
686     }
687     status =
688         eglGetConfigAttrib(phdata->egl_display,
689                            wdata->gles_configs[wdata->gles_config],
690                            EGL_STENCIL_SIZE, &attr_value);
691     if (status == EGL_TRUE) {
692         _this->gl_config.stencil_size = attr_value;
693     }
694 
695     /* Under PND OpenGL ES output can't be double buffered */
696     _this->gl_config.double_buffer = 0;
697 
698     /* GL ES context was successfully created */
699     return wdata->gles_context;
700 }
701 
702 int
PND_gl_makecurrent(_THIS,SDL_Window * window,SDL_GLContext context)703 PND_gl_makecurrent(_THIS, SDL_Window * window, SDL_GLContext context)
704 {
705     SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
706     SDL_WindowData *wdata;
707     EGLBoolean status;
708 
709     if (phdata->egl_initialized != SDL_TRUE) {
710         return SDL_SetError("PND: GF initialization failed, no OpenGL ES support");
711     }
712 
713     if ((window == NULL) && (context == NULL)) {
714         status =
715             eglMakeCurrent(phdata->egl_display, EGL_NO_SURFACE,
716                            EGL_NO_SURFACE, EGL_NO_CONTEXT);
717         if (status != EGL_TRUE) {
718             /* Failed to set current GL ES context */
719             return SDL_SetError("PND: Can't set OpenGL ES context");
720         }
721     } else {
722         wdata = (SDL_WindowData *) window->driverdata;
723         if (wdata->gles_surface == EGL_NO_SURFACE) {
724             return SDL_SetError
725                 ("PND: OpenGL ES surface is not initialized for this window");
726         }
727         if (wdata->gles_context == EGL_NO_CONTEXT) {
728             return SDL_SetError
729                 ("PND: OpenGL ES context is not initialized for this window");
730         }
731         if (wdata->gles_context != context) {
732             return SDL_SetError
733                 ("PND: OpenGL ES context is not belong to this window");
734         }
735         status =
736             eglMakeCurrent(phdata->egl_display, wdata->gles_surface,
737                            wdata->gles_surface, wdata->gles_context);
738         if (status != EGL_TRUE) {
739             /* Failed to set current GL ES context */
740             return SDL_SetError("PND: Can't set OpenGL ES context");
741         }
742     }
743     return 0;
744 }
745 
746 int
PND_gl_setswapinterval(_THIS,int interval)747 PND_gl_setswapinterval(_THIS, int interval)
748 {
749     SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
750     EGLBoolean status;
751 
752     if (phdata->egl_initialized != SDL_TRUE) {
753         return SDL_SetError("PND: EGL initialization failed, no OpenGL ES support");
754     }
755 
756     /* Check if OpenGL ES connection has been initialized */
757     if (phdata->egl_display != EGL_NO_DISPLAY) {
758         /* Set swap OpenGL ES interval */
759         status = eglSwapInterval(phdata->egl_display, interval);
760         if (status == EGL_TRUE) {
761             /* Return success to upper level */
762             phdata->swapinterval = interval;
763             return 0;
764         }
765     }
766 
767     /* Failed to set swap interval */
768     return SDL_SetError("PND: Cannot set swap interval");
769 }
770 
771 int
PND_gl_getswapinterval(_THIS)772 PND_gl_getswapinterval(_THIS)
773 {
774     return ((SDL_VideoData *) _this->driverdata)->swapinterval;
775 }
776 
777 void
PND_gl_swapwindow(_THIS,SDL_Window * window)778 PND_gl_swapwindow(_THIS, SDL_Window * window)
779 {
780     SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
781     SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
782 
783     if (phdata->egl_initialized != SDL_TRUE) {
784         SDL_SetError("PND: GLES initialization failed, no OpenGL ES support");
785         return;
786     }
787 
788     /* Many applications do not uses glFinish(), so we call it for them */
789     glFinish();
790 
791     /* Wait until OpenGL ES rendering is completed */
792     eglWaitGL();
793 
794     eglSwapBuffers(phdata->egl_display, wdata->gles_surface);
795 }
796 
797 void
PND_gl_deletecontext(_THIS,SDL_GLContext context)798 PND_gl_deletecontext(_THIS, SDL_GLContext context)
799 {
800     SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
801     EGLBoolean status;
802 
803     if (phdata->egl_initialized != SDL_TRUE) {
804         SDL_SetError("PND: GLES initialization failed, no OpenGL ES support");
805         return;
806     }
807 
808     /* Check if OpenGL ES connection has been initialized */
809     if (phdata->egl_display != EGL_NO_DISPLAY) {
810         if (context != EGL_NO_CONTEXT) {
811             status = eglDestroyContext(phdata->egl_display, context);
812             if (status != EGL_TRUE) {
813                 /* Error during OpenGL ES context destroying */
814                 SDL_SetError("PND: OpenGL ES context destroy error");
815                 return;
816             }
817         }
818     }
819 
820 #ifdef WIZ_GLES_LITE
821     if( hNativeWnd != 0 )
822     {
823       free(hNativeWnd);
824       hNativeWnd = 0;
825       printf( "SDL: Wiz framebuffer released\n" );
826     }
827 #endif
828 
829     return;
830 }
831 
832 #endif /* SDL_VIDEO_DRIVER_PANDORA */
833 
834 /* vi: set ts=4 sw=4 expandtab: */
835