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