SDL_pspgl.c (6265B)
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2014 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 44int 45PSP_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 57GLSTUB(glOrtho,(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, 58 GLdouble zNear, GLdouble zFar)) 59*/ 60void * 61PSP_GL_GetProcAddress(_THIS, const char *proc) 62{ 63 return eglGetProcAddress(proc); 64} 65 66void 67PSP_GL_UnloadLibrary(_THIS) 68{ 69 eglTerminate(_this->gl_data->display); 70} 71 72static EGLint width = 480; 73static EGLint height = 272; 74 75SDL_GLContext 76PSP_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 143int 144PSP_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 154int 155PSP_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 168int 169PSP_GL_GetSwapInterval(_THIS) 170{ 171 return _this->gl_data->swapinterval; 172} 173 174void 175PSP_GL_SwapWindow(_THIS, SDL_Window * window) 176{ 177 eglSwapBuffers(_this->gl_data->display, _this->gl_data->surface); 178} 179 180void 181PSP_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