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