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