diff options
author | joel@teichroeb.net <none@none> | 2010-12-06 10:58:43 -0800 |
---|---|---|
committer | Benjamin Franzke <benjaminfranzke@googlemail.com> | 2012-02-28 08:29:07 +0100 |
commit | a7df2b521e786001c737ed44b4b667802237e450 (patch) | |
tree | 2057271a3006c67c7a27fd0d2a0c713842f1b39b | |
parent | f18dd535801bcb50a63d932cfe3826a3aa15fdf0 (diff) |
Started on the wayland platform
-rw-r--r-- | src/video/wayland/SDL_waylandevents.c | 39 | ||||
-rw-r--r-- | src/video/wayland/SDL_waylandevents_c.h | 28 | ||||
-rw-r--r-- | src/video/wayland/SDL_waylandgl.c | 191 | ||||
-rw-r--r-- | src/video/wayland/SDL_waylandgl.h | 15 | ||||
-rw-r--r-- | src/video/wayland/SDL_waylandrender.c | 349 | ||||
-rw-r--r-- | src/video/wayland/SDL_waylandrender_c.h | 28 | ||||
-rw-r--r-- | src/video/wayland/SDL_waylandvideo.c | 265 | ||||
-rw-r--r-- | src/video/wayland/SDL_waylandvideo.h | 60 | ||||
-rw-r--r-- | src/video/wayland/SDL_waylandwindow.c | 70 | ||||
-rw-r--r-- | src/video/wayland/SDL_waylandwindow.h | 28 |
10 files changed, 1073 insertions, 0 deletions
diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c new file mode 100644 index 00000000..1219ae47 --- /dev/null +++ b/src/video/wayland/SDL_waylandevents.c @@ -0,0 +1,39 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 Sam Lantinga + + 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 + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* Being a null driver, there's no event stream. We just define stubs for + most of the API. */ + +#include "../../events/SDL_sysevents.h" +#include "../../events/SDL_events_c.h" + +#include "SDL_waylandvideo.h" +#include "SDL_waylandevents_c.h" + +void +Wayland_PumpEvents(_THIS) +{ + /* do nothing. */ +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/wayland/SDL_waylandevents_c.h b/src/video/wayland/SDL_waylandevents_c.h new file mode 100644 index 00000000..92ce0ad2 --- /dev/null +++ b/src/video/wayland/SDL_waylandevents_c.h @@ -0,0 +1,28 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 Sam Lantinga + + 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 + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#include "SDL_waylandvideo.h" + +extern void Wayland_PumpEvents(_THIS); + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/wayland/SDL_waylandgl.c b/src/video/wayland/SDL_waylandgl.c new file mode 100644 index 00000000..f1c4ad21 --- /dev/null +++ b/src/video/wayland/SDL_waylandgl.c @@ -0,0 +1,191 @@ +#include "SDL_config.h" + +#include "SDL_waylandgl.h" +#include "SDL_waylandwindow.h" + + +void Wayland_GL_SwapWindow(_THIS, SDL_Window * window) +{ + printf("Wayland_GL_SwapWindow\n"); + SDL_WaylandWindow *data = window->driverdata; + data->current ^= 1; + + glFramebufferRenderbuffer(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_RENDERBUFFER, + data->rbo[data->current]); + + wl_surface_attach(data->surface, + data->buffer[data->current ^ 1]); + wl_surface_damage(data->surface, 0, 0, + window->w, window->h); +} + +int +Wayland_GL_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context) +{ + printf("Wayland_GL_MakeCurrent\n"); + SDL_WaylandData *data = _this->driverdata; + SDL_WaylandWindow *wind = (SDL_WaylandWindow *) window->driverdata; + if (!eglMakeCurrent(data->edpy,EGL_NO_SURFACE, + EGL_NO_SURFACE,wind->context)) { + SDL_SetError("Unable to make EGL context current"); + return -1; + } + + return 1; +} + +int +Wayland_GL_LoadLibrary(_THIS, const char *path) +{ +/* void *handle; + int dlopen_flags; + + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + if (_this->gles_data->egl_active) { + SDL_SetError("OpenGL ES context already created"); + return -1; + } +#ifdef RTLD_GLOBAL + dlopen_flags = RTLD_LAZY | RTLD_GLOBAL; +#else + dlopen_flags = RTLD_LAZY; +#endif + handle = dlopen(path, dlopen_flags); + /* Catch the case where the application isn't linked with EGL *//* + if ((dlsym(handle, "eglChooseConfig") == NULL) && (path == NULL)) { + + dlclose(handle); + path = getenv("SDL_VIDEO_GL_DRIVER"); + if (path == NULL) { + path = DEFAULT_OPENGL; + } + handle = dlopen(path, dlopen_flags); + } + + if (handle == NULL) { + SDL_SetError("Could not load OpenGL ES/EGL library"); + return -1; + } + + /* Unload the old driver and reset the pointers *//* + Wayland_GL_UnloadLibrary(_this); + + + + _this->gles_data->egl_display = + _this->gles_data->eglGetDisplay((NativeDisplayType) data->display); + + if (!_this->gles_data->egl_display) { + SDL_SetError("Could not get EGL display"); + return -1; + } + + if (eglInitialize(_this->gles_data->egl_display, NULL, + NULL) != EGL_TRUE) { + SDL_SetError("Could not initialize EGL"); + return -1; + } + + _this->gl_config.dll_handle = handle; + _this->gl_config.driver_loaded = 1; + + if (path) { + strncpy(_this->gl_config.driver_path, path, + sizeof(_this->gl_config.driver_path) - 1); + } else { + strcpy(_this->gl_config.driver_path, ""); + }*/ + SDL_WaylandData *data = _this->driverdata; + + data->edpy = eglGetDRMDisplayMESA(data->drm_fd); + + int major, minor; + if (!eglInitialize(data->edpy, &major, &minor)) { + fprintf(stderr, "failed to initialize display\n"); + return -1; + } + +/* if (!eglBindAPI(EGL_OPENGL_ES_API)) { + fprintf(stderr, "failed to bind EGL_OPENGL_ES_API\n"); + return -1; + } + + data->context = eglCreateContext(data->edpy, NULL, + EGL_NO_CONTEXT, context_attribs); + if (data->context == NULL) { + fprintf(stderr, "failed to create context\n"); + return -1; + } + + if (!eglMakeCurrent(data->edpy, EGL_NO_SURFACE, + EGL_NO_SURFACE, data->context)) { + fprintf(stderr, "failed to make context current\n"); + return -1; + }*/ + return 0; +} + +void +Wayland_GL_UnloadLibrary(_THIS) +{ + /*if (_this->gl_config.driver_loaded) { + _this->gles_data->eglTerminate(_this->gles_data->egl_display); + + dlclose(_this->gl_config.dll_handle); + + _this->gles_data->eglGetProcAddress = NULL; + _this->gles_data->eglChooseConfig = NULL; + _this->gles_data->eglCreateContext = NULL; + _this->gles_data->eglCreateWindowSurface = NULL; + _this->gles_data->eglDestroyContext = NULL; + _this->gles_data->eglDestroySurface = NULL; + _this->gles_data->eglMakeCurrent = NULL; + _this->gles_data->eglSwapBuffers = NULL; + _this->gles_data->eglGetDisplay = NULL; + _this->gles_data->eglTerminate = NULL; + + _this->gl_config.dll_handle = NULL; + _this->gl_config.driver_loaded = 0; + }*/ +} + +SDL_GLContext +Wayland_GL_CreateContext(_THIS, SDL_Window * window) +{ + SDL_WaylandData *data = _this->driverdata; + SDL_WaylandWindow *wind = (SDL_WaylandWindow *) window->driverdata; + //Display *display = data->videodata->display; + + + static const EGLint context_attribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE + }; + wind->context = eglCreateContext(data->edpy, NULL, EGL_NO_CONTEXT, context_attribs); + + + if (wind->context == EGL_NO_CONTEXT) { + SDL_SetError("Could not create EGL context"); + return NULL; + } + + //data->egl_active = 1; + + + return 1; +} + +int +Wayland_GL_SetSwapInterval(_THIS, int interval) +{ + return 0; +} + +int +Wayland_GL_GetSwapInterval(_THIS) +{ + return 0; +} diff --git a/src/video/wayland/SDL_waylandgl.h b/src/video/wayland/SDL_waylandgl.h new file mode 100644 index 00000000..b566cbf5 --- /dev/null +++ b/src/video/wayland/SDL_waylandgl.h @@ -0,0 +1,15 @@ +#include "SDL_config.h" + +#ifndef _SDL_waylandgl_h +#define _SDL_waylandgl_h +#include "SDL_waylandwindow.h" +#include </home/joel/install/include/wayland-client-protocol.h> + +void Wayland_GL_SwapWindow(_THIS, SDL_Window * window); +int Wayland_GL_GetSwapInterval(_THIS); +int Wayland_GL_SetSwapInterval(_THIS, int interval); +int Wayland_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); +SDL_GLContext Wayland_GL_CreateContext(_THIS, SDL_Window * window); +int Wayland_GL_LoadLibrary(_THIS, const char *path); +void Wayland_GL_UnloadLibrary(_THIS); +#endif diff --git a/src/video/wayland/SDL_waylandrender.c b/src/video/wayland/SDL_waylandrender.c new file mode 100644 index 00000000..15476779 --- /dev/null +++ b/src/video/wayland/SDL_waylandrender.c @@ -0,0 +1,349 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 Sam Lantinga + + 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 + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#include "SDL_video.h" +#include "../SDL_sysvideo.h" +#include "../SDL_yuv_sw_c.h" +#include "../SDL_renderer_sw.h" + + +/* SDL surface based renderer implementation */ + +static SDL_Renderer *SDL_Wayland_CreateRenderer(SDL_Window * window, + Uint32 flags); +static int SDL_Wayland_RenderDrawPoints(SDL_Renderer * renderer, + const SDL_Point * points, int count); +static int SDL_Wayland_RenderDrawLines(SDL_Renderer * renderer, + const SDL_Point * points, int count); +static int SDL_Wayland_RenderDrawRects(SDL_Renderer * renderer, + const SDL_Rect ** rects, int count); +static int SDL_Wayland_RenderFillRects(SDL_Renderer * renderer, + const SDL_Rect ** rects, int count); +static int SDL_Wayland_RenderCopy(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_Rect * dstrect); +static int SDL_Wayland_RenderReadPixels(SDL_Renderer * renderer, + const SDL_Rect * rect, + Uint32 format, + void * pixels, int pitch); +static int SDL_Wayland_RenderWritePixels(SDL_Renderer * renderer, + const SDL_Rect * rect, + Uint32 format, + const void * pixels, int pitch); +static void SDL_Wayland_RenderPresent(SDL_Renderer * renderer); +static void SDL_Wayland_DestroyRenderer(SDL_Renderer * renderer); +static int *SDL_Wayland_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture); + +SDL_RenderDriver SDL_Wayland_RenderDriver = { + SDL_Wayland_CreateRenderer, + { + "Wayland", + (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY | + SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 | + SDL_RENDERER_PRESENTDISCARD), + } +}; + +typedef struct +{ + int current_screen; + SDL_Surface *screens[3]; +} SDL_Wayland_RenderData; + +SDL_Renderer * +SDL_Wayland_CreateRenderer(SDL_Window * window, Uint32 flags) +{ + SDL_VideoDisplay *display = window->display; + SDL_DisplayMode *displayMode = &display->current_mode; + SDL_Renderer *renderer; + SDL_Wayland_RenderData *data; + int i, n; + int bpp; + Uint32 Rmask, Gmask, Bmask, Amask; + + if (!SDL_PixelFormatEnumToMasks + (displayMode->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { + SDL_SetError("Unknown display format"); + return NULL; + } + + renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); + if (!renderer) { + SDL_OutOfMemory(); + return NULL; + } + + data = (SDL_Wayland_RenderData *) SDL_malloc(sizeof(*data)); + if (!data) { + SDL_Wayland_DestroyRenderer(renderer); + SDL_OutOfMemory(); + return NULL; + } + SDL_zerop(data); + + renderer->RenderDrawPoints = SDL_Wayland_RenderDrawPoints; + renderer->RenderDrawLines = SDL_Wayland_RenderDrawLines; + renderer->RenderDrawRects = SDL_Wayland_RenderDrawRects; + renderer->RenderFillRects = SDL_Wayland_RenderFillRects; + renderer->RenderCopy = SDL_Wayland_RenderCopy; + renderer->RenderReadPixels = SDL_Wayland_RenderReadPixels; + renderer->RenderWritePixels = SDL_Wayland_RenderWritePixels; + renderer->RenderPresent = SDL_Wayland_RenderPresent; + renderer->DestroyRenderer = SDL_Wayland_DestroyRenderer; + //renderer->CreateTexture = SDL_Wayland_CreateTexture; + renderer->info.name = SDL_Wayland_RenderDriver.info.name; + renderer->info.flags = 0; + renderer->window = window; + renderer->driverdata = data; + Setup_SoftwareRenderer(renderer); + + if (flags & SDL_RENDERER_PRESENTFLIP2) { + renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2; + n = 2; + } else if (flags & SDL_RENDERER_PRESENTFLIP3) { + renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3; + n = 3; + } else { + renderer->info.flags |= SDL_RENDERER_PRESENTCOPY; + n = 1; + } + for (i = 0; i < n; ++i) { + data->screens[i] = + SDL_CreateRGBSurface(0, window->w, window->h, bpp, Rmask, Gmask, + Bmask, Amask); + if (!data->screens[i]) { + SDL_Wayland_DestroyRenderer(renderer); + return NULL; + } + SDL_SetSurfacePalette(data->screens[i], display->palette); + } + data->current_screen = 0; + + return renderer; +} + +static int +SDL_Wayland_RenderDrawPoints(SDL_Renderer * renderer, + const SDL_Point * points, int count) +{ + SDL_Wayland_RenderData *data = + (SDL_Wayland_RenderData *) renderer->driverdata; + SDL_Surface *target = data->screens[data->current_screen]; + + if (renderer->blendMode == SDL_BLENDMODE_NONE || + renderer->blendMode == SDL_BLENDMODE_MASK) { + Uint32 color = SDL_MapRGBA(target->format, + renderer->r, renderer->g, renderer->b, + renderer->a); + + return SDL_DrawPoints(target, points, count, color); + } else { + return SDL_BlendPoints(target, points, count, renderer->blendMode, + renderer->r, renderer->g, renderer->b, + renderer->a); + } +} + +static int +SDL_Wayland_RenderDrawLines(SDL_Renderer * renderer, + const SDL_Point * points, int count) +{ + SDL_Wayland_RenderData *data = + (SDL_Wayland_RenderData *) renderer->driverdata; + SDL_Surface *target = data->screens[data->current_screen]; + + if (renderer->blendMode == SDL_BLENDMODE_NONE || + renderer->blendMode == SDL_BLENDMODE_MASK) { + Uint32 color = SDL_MapRGBA(target->format, + renderer->r, renderer->g, renderer->b, + renderer->a); + + return SDL_DrawLines(target, points, count, color); + } else { + return SDL_BlendLines(target, points, count, renderer->blendMode, + renderer->r, renderer->g, renderer->b, + renderer->a); + } +} + +static int +SDL_Wayland_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, + int count) +{ + SDL_Wayland_RenderData *data = + (SDL_Wayland_RenderData *) renderer->driverdata; + SDL_Surface *target = data->screens[data->current_screen]; + + if (renderer->blendMode == SDL_BLENDMODE_NONE || + renderer->blendMode == SDL_BLENDMODE_MASK) { + Uint32 color = SDL_MapRGBA(target->format, + renderer->r, renderer->g, renderer->b, + renderer->a); + + return SDL_DrawRects(target, rects, count, color); + } else { + return SDL_BlendRects(target, rects, count, + renderer->blendMode, + renderer->r, renderer->g, renderer->b, + renderer->a); + } +} + +static int +SDL_Wayland_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, + int count) +{ + SDL_Wayland_RenderData *data = + (SDL_Wayland_RenderData *) renderer->driverdata; + SDL_Surface *target = data->screens[data->current_screen]; + + if (renderer->blendMode == SDL_BLENDMODE_NONE || + renderer->blendMode == SDL_BLENDMODE_MASK) { + Uint32 color = SDL_MapRGBA(target->format, + renderer->r, renderer->g, renderer->b, + renderer->a); + + return SDL_FillRects(target, rects, count, color); + } else { + return SDL_BlendFillRects(target, rects, count, + renderer->blendMode, + renderer->r, renderer->g, renderer->b, + renderer->a); + } +} + +static int +SDL_Wayland_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_Rect * dstrect) +{ + SDL_Wayland_RenderData *data = + (SDL_Wayland_RenderData *) renderer->driverdata; + SDL_Window *window = renderer->window; + SDL_VideoDisplay *display = window->display; + + if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { + SDL_Surface *target = data->screens[data->current_screen]; + void *pixels = + (Uint8 *) target->pixels + dstrect->y * target->pitch + + dstrect->x * target->format->BytesPerPixel; + return SDL_SW_CopyYUVToRGB((SDL_SW_YUVTexture *) texture->driverdata, + srcrect, display->current_mode.format, + dstrect->w, dstrect->h, pixels, + target->pitch); + } else { + SDL_Surface *surface = (SDL_Surface *) texture->driverdata; + SDL_Surface *target = data->screens[data->current_screen]; + SDL_Rect real_srcrect = *srcrect; + SDL_Rect real_dstrect = *dstrect; + + return SDL_LowerBlit(surface, &real_srcrect, target, &real_dstrect); + } +} + +static int +SDL_Wayland_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 format, void * pixels, int pitch) +{ + SDL_Wayland_RenderData *data = + (SDL_Wayland_RenderData *) renderer->driverdata; + SDL_Window *window = renderer->window; + SDL_VideoDisplay *display = window->display; + SDL_Surface *screen = data->screens[data->current_screen]; + Uint32 screen_format = display->current_mode.format; + Uint8 *screen_pixels = (Uint8 *) screen->pixels + + rect->y * screen->pitch + + rect->x * screen->format->BytesPerPixel; + int screen_pitch = screen->pitch; + + return SDL_ConvertPixels(rect->w, rect->h, + screen_format, screen_pixels, screen_pitch, + format, pixels, pitch); +} + +static int +SDL_Wayland_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 format, const void * pixels, int pitch) +{ + SDL_Wayland_RenderData *data = + (SDL_Wayland_RenderData *) renderer->driverdata; + SDL_Window *window = renderer->window; + SDL_VideoDisplay *display = window->display; + SDL_Surface *screen = data->screens[data->current_screen]; + Uint32 screen_format = display->current_mode.format; + Uint8 *screen_pixels = (Uint8 *) screen->pixels + + rect->y * screen->pitch + + rect->x * screen->format->BytesPerPixel; + int screen_pitch = screen->pitch; + + return SDL_ConvertPixels(rect->w, rect->h, + format, pixels, pitch, + screen_format, screen_pixels, screen_pitch); +} + +static void +SDL_Wayland_RenderPresent(SDL_Renderer * renderer) +{ + static int frame_number; + SDL_Wayland_RenderData *data = + (SDL_Wayland_RenderData *) renderer->driverdata; + + /* Send the data to the display */ + if (SDL_getenv("SDL_VIDEO_Wayland_SAVE_FRAMES")) { + char file[128]; + SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp", + renderer->window->id, ++frame_number); + SDL_SaveBMP(data->screens[data->current_screen], file); + } + + /* Update the flipping chain, if any */ + if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP2) { + data->current_screen = (data->current_screen + 1) % 2; + } else if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP3) { + data->current_screen = (data->current_screen + 1) % 3; + } +} + +static int *SDL_Wayland_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ +} + +static void +SDL_Wayland_DestroyRenderer(SDL_Renderer * renderer) +{ + SDL_Wayland_RenderData *data = + (SDL_Wayland_RenderData *) renderer->driverdata; + int i; + + if (data) { + for (i = 0; i < SDL_arraysize(data->screens); ++i) { + if (data->screens[i]) { + SDL_FreeSurface(data->screens[i]); + } + } + SDL_free(data); + } + SDL_free(renderer); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/wayland/SDL_waylandrender_c.h b/src/video/wayland/SDL_waylandrender_c.h new file mode 100644 index 00000000..ca0da53e --- /dev/null +++ b/src/video/wayland/SDL_waylandrender_c.h @@ -0,0 +1,28 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 Sam Lantinga + + 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 + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* SDL surface based renderer implementation */ + +extern SDL_RenderDriver SDL_Wayland_RenderDriver; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c new file mode 100644 index 00000000..bfda5956 --- /dev/null +++ b/src/video/wayland/SDL_waylandvideo.c @@ -0,0 +1,265 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 Sam Lantinga + + 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 + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + + +#include <fcntl.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 "SDL_waylandvideo.h" +#include "SDL_waylandevents_c.h" +#include "SDL_waylandrender_c.h" +#include "SDL_waylandwindow.h" +#include "SDL_waylandgl.h" + + +#define WAYLANDVID_DRIVER_NAME "wayland" + +/* Initialization/Query functions */ +static int Wayland_VideoInit(_THIS); +static int Wayland_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); +static void Wayland_VideoQuit(_THIS); + + +/* Wayland driver bootstrap functions */ + +static int +Wayland_Available(void) +{ + const char *envr = SDL_getenv("SDL_VIDEODRIVER"); + if ((envr) && (SDL_strcmp(envr, WAYLANDVID_DRIVER_NAME) == 0)) { + return (1); + } + + return (0); +} + +static void +Wayland_DeleteDevice(SDL_VideoDevice * device) +{ + SDL_free(device); +} + +static SDL_VideoDevice * +Wayland_CreateDevice(int devindex) +{ + SDL_VideoDevice *device; + + /* Initialize all variables that we clean on shutdown */ + device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (!device) { + SDL_OutOfMemory(); + if (device) { + SDL_free(device); + } + return (0); + } + + /* Set the function pointers */ + device->VideoInit = Wayland_VideoInit; + device->VideoQuit = Wayland_VideoQuit; + device->SetDisplayMode = Wayland_SetDisplayMode; + device->PumpEvents = Wayland_PumpEvents; + + device->GL_SwapWindow = Wayland_GL_SwapWindow; + device->GL_GetSwapInterval = Wayland_GL_GetSwapInterval; + device->GL_SetSwapInterval = Wayland_GL_SetSwapInterval; + device->GL_MakeCurrent = Wayland_GL_MakeCurrent; + device->GL_CreateContext = Wayland_GL_CreateContext; + device->GL_LoadLibrary = Wayland_GL_LoadLibrary; + device->GL_UnloadLibrary = Wayland_GL_UnloadLibrary; + + + + device->CreateWindow = Wayland_CreateWindow; + + + device->free = Wayland_DeleteDevice; + + return device; +} + +VideoBootStrap Wayland_bootstrap = { + WAYLANDVID_DRIVER_NAME, "SDL Wayland video driver", + Wayland_Available, Wayland_CreateDevice +}; + +static void +display_handle_geometry(void *data, + struct wl_output *output, + int32_t width, int32_t height) +{ + SDL_WaylandData *d = data; + + d->screen_allocation.x = 0; + d->screen_allocation.y = 0; + d->screen_allocation.width = width; + d->screen_allocation.height = height; +} + + +static const struct wl_output_listener output_listener = { + display_handle_geometry, +}; + +static void +handle_configure(void *data, struct wl_shell *shell, + uint32_t time, uint32_t edges, + struct wl_surface *surface, + int32_t x, int32_t y, int32_t width, int32_t height) +{ + +} + +static const struct wl_shell_listener shell_listener = { + handle_configure, +}; + + +static void +drm_handle_device(void *data, struct wl_drm *drm, const char *device) +{ + SDL_WaylandData *c = data; + + c->device_name = strdup(device); +} + +static void drm_handle_authenticated(void *data, struct wl_drm *drm) +{ + SDL_WaylandData *c = data; + + c->authenticated = 1; +} + +static const struct wl_drm_listener drm_listener = { + drm_handle_device, + drm_handle_authenticated +}; + + +static void +display_handle_global(struct wl_display *display, uint32_t id, + const char *interface, uint32_t version, void *data) +{ + SDL_WaylandData *d = data; + + if (strcmp(interface, "compositor") == 0) { + d->compositor = wl_compositor_create(display, id); + } else if (strcmp(interface, "output") == 0) { + d->output = wl_output_create(display, id); + wl_output_add_listener(d->output, &output_listener, d); + } else if (strcmp(interface, "input_device") == 0) { + //display_add_input(d, id); + } else if (strcmp(interface, "shell") == 0) { + d->shell = wl_shell_create(display, id); + wl_shell_add_listener(d->shell, &shell_listener, d); + } else if (strcmp(interface, "drm") == 0) { + d->drm = wl_drm_create(display, id); + wl_drm_add_listener(d->drm, &drm_listener, d); + } +} + + + +int +Wayland_VideoInit(_THIS) +{ + SDL_WaylandData *data; + data = malloc(sizeof *data); + if (data == NULL) + return 0; + + _this->driverdata = data; + + data->display = wl_display_connect(NULL); + if (data->display == NULL) { + fprintf(stderr, "failed to create display: %m\n"); + return 0; + } + + wl_display_add_global_listener(data->display, + display_handle_global, data); + + wl_display_iterate(data->display, WL_DISPLAY_READABLE); + + /*if (wayland_compositor_init_egl(c) < 0) + return NULL;*/ + + data->drm_fd = open (data->device_name, O_RDWR); + if (data->drm_fd < 0) + { + fprintf(stderr, "Failed to open drm device\n"); + + return 0; + } + + int magic; + if (drmGetMagic (data->drm_fd, &magic)) + { + fprintf(stderr, "Failed to get drm magic\n"); + + return 0; + } + wl_drm_authenticate (data->drm, magic); + + wl_display_iterate (data->display, WL_DISPLAY_WRITABLE); + while (!data->authenticated) + wl_display_iterate (data->display, WL_DISPLAY_READABLE); + + + + + + SDL_VideoDisplay display; + SDL_DisplayMode mode; + + /* Use a fake 32-bpp desktop mode */ + mode.format = SDL_PIXELFORMAT_RGB888; + mode.w = 1024; + mode.h = 768; + mode.refresh_rate = 0; + mode.driverdata = NULL; + SDL_zero(display); + display.desktop_mode = mode; + display.current_mode = mode; + display.driverdata = NULL; + SDL_AddVideoDisplay(&display); + + return 0; +} + +static int +Wayland_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +{ + return 0; +} + +void +Wayland_VideoQuit(_THIS) +{ +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/wayland/SDL_waylandvideo.h b/src/video/wayland/SDL_waylandvideo.h new file mode 100644 index 00000000..29c747e4 --- /dev/null +++ b/src/video/wayland/SDL_waylandvideo.h @@ -0,0 +1,60 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 Sam Lantinga + + 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 + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#ifndef _SDL_waylandvideo_h +#define _SDL_waylandvideo_h + +#include "../SDL_sysvideo.h" +#include </home/joel/install/include/wayland-client.h> +#include </home/joel/install/include/wayland-client-protocol.h> +#define GL_GLEXT_PROTOTYPES +#define EGL_EGLEXT_PROTOTYPES +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GL/gl.h> + + +typedef struct +{ + struct wl_display *display; + struct wl_compositor *compositor; + struct wl_drm *drm; + struct wl_output *output; + struct wl_shell *shell; + + struct { + int32_t x, y, width, height; + } screen_allocation; + + char *device_name; + int authenticated; + + int drm_fd; + + EGLDisplay edpy; + +} SDL_WaylandData; + +#endif /* _SDL_nullvideo_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c new file mode 100644 index 00000000..3adf7fe5 --- /dev/null +++ b/src/video/wayland/SDL_waylandwindow.c @@ -0,0 +1,70 @@ +#include "SDL_config.h" + +#include "../SDL_sysvideo.h" +#include "SDL_waylandwindow.h" +#include "SDL_waylandvideo.h" + + + +int Wayland_CreateWindow(_THIS, SDL_Window * window) +{ + printf("window create\n"); + SDL_WaylandWindow *data; + data = malloc(sizeof *data); + if (data == NULL) + return 0; + SDL_WaylandData *c; + c = _this->driverdata; + window->driverdata = data; + struct wl_visual *visual; + int i; + EGLint name, stride, attribs[] = { + EGL_WIDTH, 0, + EGL_HEIGHT, 0, + EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA, + EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SCANOUT_MESA, + EGL_NONE + }; + + + data->surface = + wl_compositor_create_surface(c->compositor); + wl_surface_set_user_data(data->surface, data); + + glGenRenderbuffers(2, data->rbo); + visual = wl_display_get_premultiplied_argb_visual(c->display); + for (i = 0; i < 2; i++) { + glBindRenderbuffer(GL_RENDERBUFFER, data->rbo[i]); + + attribs[1] = window->w; + attribs[3] = window->h; + data->image[i] = + eglCreateDRMImageMESA(c->display, attribs); + glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, + data->image[i]); + eglExportDRMImageMESA(c->display, data->image[i], + &name, NULL, &stride); + data->buffer[i] = + wl_drm_create_buffer(c->drm, name, + window->w, window->h, + stride, visual); + } + + data->current = 0; + glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, data->image[0]); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_RENDERBUFFER, + data->rbo[data->current]); + + wl_surface_attach(data->surface, + data->buffer[data->current]); + wl_surface_map(data->surface, + 0, 0, + window->w, window->h); + printf("window %d %d\n", window->w, window->h); + + glClearColor(0, 0, 0, 0.5); + + return 0; +} diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h new file mode 100644 index 00000000..6b8e4f6a --- /dev/null +++ b/src/video/wayland/SDL_waylandwindow.h @@ -0,0 +1,28 @@ +#include "SDL_config.h" + +#ifndef _SDL_waylandwindow_h +#define _SDL_waylandwindow_h + +#include "../SDL_sysvideo.h" + +#include "SDL_waylandvideo.h" + +typedef struct +{ + struct wl_surface *surface; + struct wl_buffer *buffer[2]; + + EGLImageKHR image[2]; + GLuint rbo[2]; + uint32_t fb_id[2]; + uint32_t current; + + EGLContext context; + +} SDL_WaylandWindow; + +extern int Wayland_CreateWindow(_THIS, SDL_Window * window); + +#endif /* _SDL_waylandwindow_h */ + +/* vi: set ts=4 sw=4 expandtab: */ |