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