src/video/pandora/SDL_pandora.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 09 Dec 2016 01:47:43 -0800
changeset 10690 23a825f341e6
parent 10208 49c460371a4a
child 10737 3406a0f8b041
permissions -rw-r--r--
Fixed bug 3513 - SDL_GL_SwapWindow does not return error status

Return an error code from SDL_GL_SwapWindow(), like the other SDL APIs.
     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
    45 PND_available(void)
    46 {
    47     return 1;
    48 }
    49 
    50 static void
    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 *
    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
   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
   180 PND_videoquit(_THIS)
   181 {
   182 
   183 }
   184 
   185 void
   186 PND_getdisplaymodes(_THIS, SDL_VideoDisplay * display)
   187 {
   188 
   189 }
   190 
   191 int
   192 PND_setdisplaymode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
   193 {
   194     return 0;
   195 }
   196 
   197 int
   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
   242 PND_createwindowfrom(_THIS, SDL_Window * window, const void *data)
   243 {
   244     return -1;
   245 }
   246 
   247 void
   248 PND_setwindowtitle(_THIS, SDL_Window * window)
   249 {
   250 }
   251 void
   252 PND_setwindowicon(_THIS, SDL_Window * window, SDL_Surface * icon)
   253 {
   254 }
   255 void
   256 PND_setwindowposition(_THIS, SDL_Window * window)
   257 {
   258 }
   259 void
   260 PND_setwindowsize(_THIS, SDL_Window * window)
   261 {
   262 }
   263 void
   264 PND_showwindow(_THIS, SDL_Window * window)
   265 {
   266 }
   267 void
   268 PND_hidewindow(_THIS, SDL_Window * window)
   269 {
   270 }
   271 void
   272 PND_raisewindow(_THIS, SDL_Window * window)
   273 {
   274 }
   275 void
   276 PND_maximizewindow(_THIS, SDL_Window * window)
   277 {
   278 }
   279 void
   280 PND_minimizewindow(_THIS, SDL_Window * window)
   281 {
   282 }
   283 void
   284 PND_restorewindow(_THIS, SDL_Window * window)
   285 {
   286 }
   287 void
   288 PND_setwindowgrab(_THIS, SDL_Window * window, SDL_bool grabbed)
   289 {
   290 }
   291 void
   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
   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
   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 *
   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
   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
   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
   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
   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
   772 PND_gl_getswapinterval(_THIS)
   773 {
   774     return ((SDL_VideoData *) _this->driverdata)->swapinterval;
   775 }
   776 
   777 int
   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         return SDL_SetError("PND: GLES initialization failed, no OpenGL ES support");
   785     }
   786 
   787     /* Many applications do not uses glFinish(), so we call it for them */
   788     glFinish();
   789 
   790     /* Wait until OpenGL ES rendering is completed */
   791     eglWaitGL();
   792 
   793     eglSwapBuffers(phdata->egl_display, wdata->gles_surface);
   794     return 0;
   795 }
   796 
   797 void
   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: */