Skip to content
This repository has been archived by the owner on Sep 4, 2019. It is now read-only.

Commit

Permalink
Add OpenGL support to SDL. This allows applications to request a SDL_…
Browse files Browse the repository at this point in the history
…OPENGL main video surface.

Note that only OpenGL ES 1.1 is actually supported.
  • Loading branch information
Artem Simonov committed Feb 13, 2012
1 parent c1346d7 commit baaf155
Show file tree
Hide file tree
Showing 7 changed files with 342 additions and 3 deletions.
4 changes: 4 additions & 0 deletions .cproject
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
<listOptionValue builtIn="false" value="screen"/>
<listOptionValue builtIn="false" value="EGL"/>
<listOptionValue builtIn="false" value="m"/>
<listOptionValue builtIn="false" value="GLESv1_CM"/>
<listOptionValue builtIn="false" value="GLESv2"/>
<listOptionValue builtIn="false" value="asound"/>
</option>
<inputType id="com.qnx.qcc.inputType.linker.1668012069" superClass="com.qnx.qcc.inputType.linker">
Expand Down Expand Up @@ -127,6 +129,7 @@
<listOptionValue builtIn="false" value="screen"/>
<listOptionValue builtIn="false" value="EGL"/>
<listOptionValue builtIn="false" value="m"/>
<listOptionValue builtIn="false" value="GLESv1_CM"/>
<listOptionValue builtIn="false" value="GLESv2"/>
<listOptionValue builtIn="false" value="asound"/>
</option>
Expand Down Expand Up @@ -202,6 +205,7 @@
<listOptionValue builtIn="false" value="screen"/>
<listOptionValue builtIn="false" value="EGL"/>
<listOptionValue builtIn="false" value="m"/>
<listOptionValue builtIn="false" value="GLESv1_CM"/>
<listOptionValue builtIn="false" value="GLESv2"/>
<listOptionValue builtIn="false" value="asound"/>
</option>
Expand Down
44 changes: 44 additions & 0 deletions include/SDL_gliop.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
SDL - Simple DirectMedia Layer
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#ifndef GLIOP_H
#define GLIOP_H

#define GL_VERSION_1_5
#define GL_ES
#define GL_ES_VERSION_1_1

#include <begin_code.h>

#include <GLES/gl.h>

#ifdef __cplusplus
extern "C" {
#endif
/*
These are not defined in GLES
*/
typedef double GLdouble;
typedef double GLclampd;
#ifdef __cplusplus
}
#endif
#include <close_code.h>
#endif
5 changes: 5 additions & 0 deletions src/video/SDL_cursor.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,11 @@ void SDL_SetCursor (SDL_Cursor *cursor)
return;
}

#ifdef __PLAYBOOK__ // FIXME: Hack to prevent cursor drawing in OpenGL.
if (video->screen->flags & SDL_OPENGL)
return;
#endif

/* Prevent the event thread from moving the mouse */
SDL_LockCursor();

Expand Down
24 changes: 22 additions & 2 deletions src/video/playbook/SDL_playbookvideo.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
#include "SDL_playbookvideo.h"
#include "SDL_playbookvideo_c.h"
#include "SDL_playbookvideo_8bit_c.h"
#include "SDL_playbookvideo_gl_c.h"
#include "SDL_playbookevents_c.h"
#include "SDL_playbookhw_c.h"
#include "SDL_playbooktouch_c.h"
Expand Down Expand Up @@ -116,6 +117,12 @@ static SDL_VideoDevice *PLAYBOOK_CreateDevice(int devindex)
device->InitOSKeymap = PLAYBOOK_InitOSKeymap;
device->PumpEvents = PLAYBOOK_PumpEvents;

device->GL_LoadLibrary = 0; //PLAYBOOK_GL_LoadLibrary;
device->GL_GetProcAddress = PLAYBOOK_GL_GetProcAddress;
device->GL_GetAttribute = PLAYBOOK_GL_GetAttribute;
device->GL_MakeCurrent = PLAYBOOK_GL_MakeCurrent;
device->GL_SwapBuffers = PLAYBOOK_GL_SwapBuffers;

device->free = PLAYBOOK_DeleteDevice;

return device;
Expand Down Expand Up @@ -222,6 +229,9 @@ int PLAYBOOK_VideoInit(_THIS, SDL_PixelFormat *vformat)

_priv->screenWindow = 0;
_priv->surface = 0;
_priv->eglInfo.eglDisplay = 0;
_priv->eglInfo.eglContext = 0;
_priv->eglInfo.eglSurface = 0;

for ( i=0; i<SDL_NUMMODES; ++i ) {
_priv->SDL_modelist[i] = SDL_malloc(sizeof(SDL_Rect));
Expand Down Expand Up @@ -322,6 +332,9 @@ SDL_Surface *PLAYBOOK_SetVideoMode(_THIS, SDL_Surface *current,
_priv->eventYOffset = 40;
height = 480;
}
if (flags & SDL_OPENGL) {
return PLAYBOOK_SetVideoMode_GL(this, current, width, height, bpp, flags);
}
screen_window_t screenWindow = PLAYBOOK_CreateWindow(this, current, width, height, bpp);
if (screenWindow == NULL)
return NULL;
Expand Down Expand Up @@ -505,8 +518,15 @@ int PLAYBOOK_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
void PLAYBOOK_VideoQuit(_THIS)
{
if (_priv->screenWindow) {
screen_destroy_window_buffers(_priv->screenWindow);
screen_destroy_window(_priv->screenWindow);
if (_priv->eglInfo.eglDisplay) {
eglDestroySurface(_priv->eglInfo.eglDisplay, _priv->eglInfo.eglSurface);
screen_destroy_window(_priv->screenWindow);
eglDestroyContext(_priv->eglInfo.eglDisplay, _priv->eglInfo.eglContext);
eglTerminate(_priv->eglInfo.eglDisplay);
} else {
screen_destroy_window_buffers(_priv->screenWindow);
screen_destroy_window(_priv->screenWindow);
}
}
screen_stop_events(_priv->screenContext);
screen_destroy_event(_priv->screenEvent);
Expand Down
2 changes: 1 addition & 1 deletion src/video/playbook/SDL_playbookvideo.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ struct SDL_PrivateVideoData {

SDL_Rect *SDL_modelist[SDL_NUMMODES+1];

// For 8bit video driver
// For 8bit video driver and OpenGL windows
struct {
void *eglDisplay;
void *eglContext;
Expand Down
232 changes: 232 additions & 0 deletions src/video/playbook/SDL_playbookvideo_gl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
/*
* SDL_playbookvideo_gl.c
*
* Created on: 2012-01-17
* Author: asimonov
*/

#include "SDL_config.h"

#include "SDL_video.h"
#include "SDL_mouse.h"
#include "../SDL_sysvideo.h"
#include "../SDL_pixels_c.h"
#include "../../events/SDL_events_c.h"

#include <bps/bps.h>
#include <bps/screen.h>
#include <bps/event.h>
#include <bps/orientation.h>
#include <bps/navigator.h>

#include "touchcontroloverlay.h"

#include "SDL_playbookvideo_c.h"
#include "SDL_playbookvideo_gl_c.h"
#include "SDL_playbookevents_c.h"
#include "SDL_playbookhw_c.h"
#include "SDL_playbooktouch_c.h"
#include "SDL_playbookyuv_c.h"

#include <EGL/egl.h>
#include <GLES/gl.h>
#include <errno.h> // ::errno
#include <time.h> // struct tm, clock_gettime

static void egl_perror(const char *msg)
{
static const char *errmsg[] = {
"function succeeded",
"EGL is not initialized, or could not be initialized, for the specified display",
"cannot access a requested resource",
"failed to allocate resources for the requested operation",
"an unrecognized attribute or attribute value was passed in an attribute list",
"an EGLConfig argument does not name a valid EGLConfig",
"an EGLContext argument does not name a valid EGLContext",
"the current surface of the calling thread is no longer valid",
"an EGLDisplay argument does not name a valid EGLDisplay",
"arguments are inconsistent",
"an EGLNativePixmapType argument does not refer to a valid native pixmap",
"an EGLNativeWindowType argument does not refer to a valid native window",
"one or more argument values are invalid",
"an EGLSurface argument does not name a valid surface configured for rendering",
"a power management event has occurred",
};

fprintf(stderr, "%s: %s\n", msg, errmsg[eglGetError() - EGL_SUCCESS]);
}

SDL_Surface *PLAYBOOK_SetVideoMode_GL(_THIS, SDL_Surface *current,
int width, int height, int bpp, Uint32 flags)
{
int rc;
EGLint attributes[] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
EGL_NONE
};
EGLint contextAttributes[3] = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE };
EGLConfig configs[1];
EGLint configCount;
screen_window_t screenWindow;
int format = SCREEN_FORMAT_RGBX8888;
int sizeOfWindow[2] = {1024, 600};
int sizeOfBuffer[2] = {width, height};
int usage = SCREEN_USAGE_OPENGL_ES1;
EGLint eglSurfaceAttributes[3] = { EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE };

if (_priv->screenWindow) {
fprintf(stderr, "OpenGL window already created... this WILL fail\n"); // FIXME
}

_priv->eglInfo.eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (_priv->eglInfo.eglDisplay == EGL_NO_DISPLAY) {
egl_perror("eglGetDisplay");
goto error1;
}

rc = eglInitialize(_priv->eglInfo.eglDisplay, NULL, NULL);
if (rc != EGL_TRUE) {
egl_perror("eglInitialize");
goto error1;
}

rc = eglBindAPI(EGL_OPENGL_ES_API);
if (rc != EGL_TRUE) {
egl_perror("eglBindAPI");
goto error2;
}

rc = eglChooseConfig(_priv->eglInfo.eglDisplay, attributes, configs, 1, &configCount);
if (rc != EGL_TRUE) {
egl_perror("eglBindAPI");
eglTerminate(_priv->eglInfo.eglDisplay);
return NULL;
} else if (configCount <= 0) {
fprintf(stderr, "No matching configurations found.");
goto error2;
}

_priv->eglInfo.eglContext = eglCreateContext(_priv->eglInfo.eglDisplay, configs[0], EGL_NO_CONTEXT, contextAttributes);
if (_priv->eglInfo.eglContext == EGL_NO_CONTEXT) {
egl_perror("eglCreateContext");
goto error2;
}

screenWindow = PLAYBOOK_CreateWindow(this, current, width, height, bpp);
if (screenWindow == NULL) {
goto error3;
}

rc = screen_set_window_property_iv(screenWindow, SCREEN_PROPERTY_SIZE, sizeOfWindow);
if (rc) {
SDL_SetError("Cannot resize window: %s", strerror(errno));
screen_destroy_window(screenWindow);
return NULL;
}

// rc = screen_set_window_property_iv(screenWindow, SCREEN_PROPERTY_BUFFER_SIZE, sizeOfBuffer);
// if (rc) {
// SDL_SetError("Cannot resize window buffer: %s", strerror(errno));
// screen_destroy_window(screenWindow);
// return NULL;
// }

rc = screen_set_window_property_iv(screenWindow, SCREEN_PROPERTY_FORMAT, &format);
if (rc) {
SDL_SetError("Cannot set window format: %s", strerror(errno));
goto error4;
}

rc = screen_set_window_property_iv(screenWindow, SCREEN_PROPERTY_USAGE, &usage);
if (rc) {
SDL_SetError("Cannot set window usage: %s", strerror(errno));
goto error4;
}

rc = screen_create_window_buffers(screenWindow, 2);
if (rc) {
SDL_SetError("Cannot create window buffers: %s", strerror(errno));
goto error4;
}

_priv->eglInfo.eglSurface = eglCreateWindowSurface(_priv->eglInfo.eglDisplay, configs[0],
screenWindow, (EGLint*)&eglSurfaceAttributes);
if (_priv->eglInfo.eglSurface == EGL_NO_SURFACE) {
egl_perror("eglCreateWindowSurface");
goto error4;
}

rc = eglMakeCurrent(_priv->eglInfo.eglDisplay, _priv->eglInfo.eglSurface, _priv->eglInfo.eglSurface, _priv->eglInfo.eglContext);
if (rc != EGL_TRUE) {
egl_perror("eglMakeCurrent");
goto error5;
}


initializeOverlay(this, screenWindow);

_priv->screenWindow = screenWindow;

current->flags &= ~SDL_RESIZABLE;
current->flags |= SDL_FULLSCREEN;
current->flags |= SDL_HWSURFACE;
current->flags |= SDL_OPENGL;
current->w = width;
current->h = height;
current->pixels = 0;
_priv->surface = current;
return current;
error5:
eglDestroySurface(_priv->eglInfo.eglDisplay, _priv->eglInfo.eglSurface);
_priv->eglInfo.eglSurface = 0;
error4:
screen_destroy_window(screenWindow);
error3:
eglDestroyContext(_priv->eglInfo.eglDisplay, _priv->eglInfo.eglContext);
_priv->eglInfo.eglContext = 0;
error2:
eglTerminate(_priv->eglInfo.eglDisplay);
_priv->eglInfo.eglDisplay = 0;
error1:
return NULL;
}

/* Sets the dll to use for OpenGL and loads it */
int PLAYBOOK_GL_LoadLibrary(_THIS, const char *path)
{
fprintf(stderr, "%s\n", __FUNCTION__);
return 0;
}

/* Retrieves the address of a function in the gl library */
void* PLAYBOOK_GL_GetProcAddress(_THIS, const char *proc) {
fprintf(stderr, "%s\n", __FUNCTION__);
return 0;
}

/* Get attribute information from the windowing system. */
int PLAYBOOK_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
{
fprintf(stderr, "%s\n", __FUNCTION__);
return 0;
}

/* Make the context associated with this driver current */
int PLAYBOOK_GL_MakeCurrent(_THIS)
{
int rc = eglMakeCurrent(_priv->eglInfo.eglDisplay, _priv->eglInfo.eglSurface, _priv->eglInfo.eglSurface, _priv->eglInfo.eglContext);
// fprintf(stderr, "%s: %d\n", __FUNCTION__, rc);
return rc;
}

/* Swap the current buffers in double buffer mode. */
void PLAYBOOK_GL_SwapBuffers(_THIS)
{
// fprintf(stderr, "%s\n", __FUNCTION__);
eglSwapBuffers(_priv->eglInfo.eglDisplay, _priv->eglInfo.eglSurface);
}
Loading

0 comments on commit baaf155

Please sign in to comment.