src/video/psp/SDL_pspgl.c
author Sam Lantinga <slouken@libsdl.org>
Sat, 18 May 2013 14:17:52 -0700
changeset 7191 75360622e65f
parent 7037 3fedf1f25b94
child 8149 681eb46b8ac4
permissions -rw-r--r--
File style cleanup for the SDL 2.0 release
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2013 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 
    22 #include <stdlib.h>
    23 #include <string.h>
    24 
    25 #include "SDL_error.h"
    26 #include "SDL_pspvideo.h"
    27 #include "SDL_pspgl_c.h"
    28 
    29 /*****************************************************************************/
    30 /* SDL OpenGL/OpenGL ES functions                                            */
    31 /*****************************************************************************/
    32 #define EGLCHK(stmt)                            \
    33     do {                                        \
    34         EGLint err;                             \
    35                                                 \
    36         stmt;                                   \
    37         err = eglGetError();                    \
    38         if (err != EGL_SUCCESS) {               \
    39             SDL_SetError("EGL error %d", err);  \
    40             return 0;                           \
    41         }                                       \
    42     } while (0)
    43 
    44 int
    45 PSP_GL_LoadLibrary(_THIS, const char *path)
    46 {
    47   if (!_this->gl_config.driver_loaded) {
    48         _this->gl_config.driver_loaded = 1;
    49   }
    50 
    51   return 0;
    52 }
    53 
    54 /* pspgl doesn't provide this call, so stub it out since SDL requires it.
    55 #define GLSTUB(func,params) void func params {}
    56 
    57 GLSTUB(glOrtho,(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top,
    58                     GLdouble zNear, GLdouble zFar))
    59 */
    60 void *
    61 PSP_GL_GetProcAddress(_THIS, const char *proc)
    62 {
    63         return eglGetProcAddress(proc);
    64 }
    65 
    66 void
    67 PSP_GL_UnloadLibrary(_THIS)
    68 {
    69         eglTerminate(_this->gl_data->display);
    70 }
    71 
    72 static EGLint width = 480;
    73 static EGLint height = 272;
    74 
    75 SDL_GLContext
    76 PSP_GL_CreateContext(_THIS, SDL_Window * window)
    77 {
    78 
    79     SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
    80 
    81         EGLint attribs[32];
    82         EGLDisplay display;
    83         EGLContext context;
    84         EGLSurface surface;
    85         EGLConfig config;
    86         EGLint num_configs;
    87         int i;
    88 
    89 
    90     /* EGL init taken from glutCreateWindow() in PSPGL's glut.c. */
    91         EGLCHK(display = eglGetDisplay(0));
    92         EGLCHK(eglInitialize(display, NULL, NULL));
    93     wdata->uses_gles = SDL_TRUE;
    94         window->flags |= SDL_WINDOW_FULLSCREEN;
    95 
    96         /* Setup the config based on SDL's current values. */
    97         i = 0;
    98         attribs[i++] = EGL_RED_SIZE;
    99         attribs[i++] = _this->gl_config.red_size;
   100         attribs[i++] = EGL_GREEN_SIZE;
   101         attribs[i++] = _this->gl_config.green_size;
   102         attribs[i++] = EGL_BLUE_SIZE;
   103         attribs[i++] = _this->gl_config.blue_size;
   104         attribs[i++] = EGL_DEPTH_SIZE;
   105         attribs[i++] = _this->gl_config.depth_size;
   106 
   107         if (_this->gl_config.alpha_size)
   108         {
   109             attribs[i++] = EGL_ALPHA_SIZE;
   110             attribs[i++] = _this->gl_config.alpha_size;
   111         }
   112         if (_this->gl_config.stencil_size)
   113         {
   114             attribs[i++] = EGL_STENCIL_SIZE;
   115             attribs[i++] = _this->gl_config.stencil_size;
   116         }
   117 
   118         attribs[i++] = EGL_NONE;
   119 
   120         EGLCHK(eglChooseConfig(display, attribs, &config, 1, &num_configs));
   121 
   122         if (num_configs == 0)
   123         {
   124             SDL_SetError("No valid EGL configs for requested mode");
   125             return 0;
   126         }
   127 
   128         EGLCHK(eglGetConfigAttrib(display, config, EGL_WIDTH, &width));
   129         EGLCHK(eglGetConfigAttrib(display, config, EGL_HEIGHT, &height));
   130 
   131         EGLCHK(context = eglCreateContext(display, config, NULL, NULL));
   132         EGLCHK(surface = eglCreateWindowSurface(display, config, 0, NULL));
   133         EGLCHK(eglMakeCurrent(display, surface, surface, context));
   134 
   135         _this->gl_data->display = display;
   136         _this->gl_data->context = context;
   137         _this->gl_data->surface = surface;
   138 
   139 
   140     return context;
   141 }
   142 
   143 int
   144 PSP_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
   145 {
   146         if (!eglMakeCurrent(_this->gl_data->display, _this->gl_data->surface,
   147                           _this->gl_data->surface, _this->gl_data->context))
   148         {
   149             return SDL_SetError("Unable to make EGL context current");
   150         }
   151     return 0;
   152 }
   153 
   154 int
   155 PSP_GL_SetSwapInterval(_THIS, int interval)
   156 {
   157     EGLBoolean status;
   158     status = eglSwapInterval(_this->gl_data->display, interval);
   159     if (status == EGL_TRUE) {
   160         /* Return success to upper level */
   161         _this->gl_data->swapinterval = interval;
   162         return 0;
   163     }
   164     /* Failed to set swap interval */
   165     return SDL_SetError("Unable to set the EGL swap interval");
   166 }
   167 
   168 int
   169 PSP_GL_GetSwapInterval(_THIS)
   170 {
   171     return _this->gl_data->swapinterval;
   172 }
   173 
   174 void
   175 PSP_GL_SwapWindow(_THIS, SDL_Window * window)
   176 {
   177     eglSwapBuffers(_this->gl_data->display, _this->gl_data->surface);
   178 }
   179 
   180 void
   181 PSP_GL_DeleteContext(_THIS, SDL_GLContext context)
   182 {
   183     SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
   184     EGLBoolean status;
   185 
   186     if (phdata->egl_initialized != SDL_TRUE) {
   187         SDL_SetError("PSP: GLES initialization failed, no OpenGL ES support");
   188         return;
   189     }
   190 
   191     /* Check if OpenGL ES connection has been initialized */
   192     if (_this->gl_data->display != EGL_NO_DISPLAY) {
   193         if (context != EGL_NO_CONTEXT) {
   194             status = eglDestroyContext(_this->gl_data->display, context);
   195             if (status != EGL_TRUE) {
   196                 /* Error during OpenGL ES context destroying */
   197                 SDL_SetError("PSP: OpenGL ES context destroy error");
   198                 return;
   199             }
   200         }
   201     }
   202 
   203     return;
   204 }
   205