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