Added framebuffer mapping.
--- a/src/video/fbcon-1.3/SDL_fbmodes.c Sat Nov 07 11:35:19 2009 +0000
+++ b/src/video/fbcon-1.3/SDL_fbmodes.c Thu Nov 12 21:44:14 2009 +0000
@@ -21,110 +21,35 @@
*/
#include "SDL_config.h"
-#include "SDL_ps3video.h"
+#include "SDL_fbvideo.h"
void
-PS3_InitModes(_THIS)
+FB_InitModes(_THIS)
{
- deprintf(1, "+PS3_InitModes()\n");
+ deprintf(1, "+FB_InitModes()\n");
SDL_VideoDisplay display;
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
SDL_DisplayMode mode;
- PS3_DisplayModeData *modedata;
- unsigned long vid = 0;
-
- modedata = (PS3_DisplayModeData *) SDL_malloc(sizeof(*modedata));
- if (!modedata) {
- return;
- }
-
- /* Setting up the DisplayMode based on current settings */
- struct ps3fb_ioctl_res res;
- if (ioctl(data->fbdev, PS3FB_IOCTL_SCREENINFO, &res)) {
- SDL_SetError("Can't get PS3FB_IOCTL_SCREENINFO");
- }
- mode.format = SDL_PIXELFORMAT_RGB888;
- mode.refresh_rate = 0;
- mode.w = res.xres;
- mode.h = res.yres;
-
- /* Setting up driver specific mode data,
- * Get the current ps3 specific videmode number */
- if (ioctl(data->fbdev, PS3FB_IOCTL_GETMODE, (unsigned long)&vid)) {
- SDL_SetError("Can't get PS3FB_IOCTL_GETMODE");
- }
- deprintf(2, "PS3FB_IOCTL_GETMODE = %u\n", vid);
- modedata->mode = vid;
- mode.driverdata = modedata;
-
- /* Set display's videomode and add it */
- SDL_zero(display);
- display.desktop_mode = mode;
- display.current_mode = mode;
-
- SDL_AddVideoDisplay(&display);
- deprintf(1, "-PS3_InitModes()\n");
+ deprintf(1, "-FB_InitModes()\n");
}
-/* DisplayModes available on the PS3 */
-static SDL_DisplayMode ps3fb_modedb[] = {
- /* VESA */
- {SDL_PIXELFORMAT_RGB888, 1280, 768, 0, NULL}, // WXGA
- {SDL_PIXELFORMAT_RGB888, 1280, 1024, 0, NULL}, // SXGA
- {SDL_PIXELFORMAT_RGB888, 1920, 1200, 0, NULL}, // WUXGA
- /* Native resolutions (progressive, "fullscreen") */
- {SDL_PIXELFORMAT_RGB888, 720, 480, 0, NULL}, // 480p
- {SDL_PIXELFORMAT_RGB888, 1280, 720, 0, NULL}, // 720p
- {SDL_PIXELFORMAT_RGB888, 1920, 1080, 0, NULL} // 1080p
-};
-
-/* PS3 videomode number according to ps3fb_modedb */
-static PS3_DisplayModeData ps3fb_data[] = {
- {11}, {12}, {13}, {130}, {131}, {133},
-};
-
void
-PS3_GetDisplayModes(_THIS) {
- deprintf(1, "+PS3_GetDisplayModes()\n");
- SDL_DisplayMode mode;
- unsigned int nummodes;
-
- nummodes = sizeof(ps3fb_modedb) / sizeof(SDL_DisplayMode);
-
- int n;
- for (n=0; n<nummodes; ++n) {
- /* Get driver specific mode data */
- ps3fb_modedb[n].driverdata = &ps3fb_data[n];
-
- /* Add DisplayMode to list */
- deprintf(2, "Adding resolution %u x %u\n", ps3fb_modedb[n].w, ps3fb_modedb[n].h);
- SDL_AddDisplayMode(_this->current_display, &ps3fb_modedb[n]);
- }
- deprintf(1, "-PS3_GetDisplayModes()\n");
+FB_GetDisplayModes(_THIS) {
+ deprintf(1, "+FB_GetDisplayModes()\n");
+ deprintf(1, "-FB_GetDisplayModes()\n");
}
int
-PS3_SetDisplayMode(_THIS, SDL_DisplayMode * mode)
+FB_SetDisplayMode(_THIS, SDL_DisplayMode * mode)
{
- deprintf(1, "+PS3_SetDisplayMode()\n");
- SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
- PS3_DisplayModeData *dispdata = (PS3_DisplayModeData *) mode->driverdata;
-
- /* Set the new DisplayMode */
- deprintf(2, "Setting PS3FB_MODE to %u\n", dispdata->mode);
- if (ioctl(data->fbdev, PS3FB_IOCTL_SETMODE, (unsigned long)&dispdata->mode)) {
- deprintf(2, "Could not set PS3FB_MODE\n");
- SDL_SetError("Could not set PS3FB_MODE\n");
- return -1;
- }
-
- deprintf(1, "-PS3_SetDisplayMode()\n");
+ deprintf(1, "+FB_SetDisplayMode()\n");
+ deprintf(1, "-FB_SetDisplayMode()\n");
return 0;
}
void
-PS3_QuitModes(_THIS) {
- deprintf(1, "+PS3_QuitModes()\n");
+FB_QuitModes(_THIS) {
+ deprintf(1, "+FB_QuitModes()\n");
/* There was no mem allocated for driverdata */
int i, j;
@@ -135,7 +60,7 @@
}
}
- deprintf(1, "-PS3_QuitModes()\n");
+ deprintf(1, "-FB_QuitModes()\n");
}
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/fbcon-1.3/SDL_fbmodes_c.h Sat Nov 07 11:35:19 2009 +0000
+++ b/src/video/fbcon-1.3/SDL_fbmodes_c.h Thu Nov 12 21:44:14 2009 +0000
@@ -21,14 +21,14 @@
*/
#include "SDL_config.h"
-#ifndef _SDL_ps3modes_h
-#define _SDL_ps3modes_h
+#ifndef _SDL_fbmodes_h
+#define _SDL_fbmodes_h
-extern void PS3_InitModes(_THIS);
-extern void PS3_GetDisplayModes(_THIS);
-extern int PS3_SetDisplayMode(_THIS, SDL_DisplayMode * mode);
-extern void PS3_QuitModes(_THIS);
+extern void FB_InitModes(_THIS);
+extern void FB_GetDisplayModes(_THIS);
+extern int FB_SetDisplayMode(_THIS, SDL_DisplayMode * mode);
+extern void FB_QuitModes(_THIS);
-#endif /* SDL_ps3modes_h */
+#endif /* SDL_fbmodes_h */
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/fbcon-1.3/SDL_fbrender.c Sat Nov 07 11:35:19 2009 +0000
+++ b/src/video/fbcon-1.3/SDL_fbrender.c Thu Nov 12 21:44:14 2009 +0000
@@ -232,14 +232,6 @@
SDL_FB_RenderData *data =
(SDL_FB_RenderData *) renderer->driverdata;
- /* Send the data to the display */
- if (SDL_getenv("SDL_VIDEO_FB_SAVE_FRAMES")) {
- char file[128];
- SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp",
- renderer->window, ++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;
--- a/src/video/fbcon-1.3/SDL_fbvideo.c Sat Nov 07 11:35:19 2009 +0000
+++ b/src/video/fbcon-1.3/SDL_fbvideo.c Thu Nov 12 21:44:14 2009 +0000
@@ -54,9 +54,37 @@
/* Initialization/Query functions */
static int FB_VideoInit(_THIS);
-static int FB_SetDisplayMode(_THIS, SDL_DisplayMode * mode);
static void FB_VideoQuit(_THIS);
+static int
+SDL_getpagesize(void)
+{
+#ifdef HAVE_GETPAGESIZE
+ return getpagesize();
+#elif defined(PAGE_SIZE)
+ return PAGE_SIZE;
+#else
+#error Can not determine system page size.
+ /* this is what it USED to be in Linux... */
+ return 4096;
+#endif
+}
+
+
+/* Small wrapper for mmap() so we can play nicely with no-mmu hosts
+ * (non-mmu hosts disallow the MAP_SHARED flag) */
+static void *
+do_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
+{
+ void *ret;
+ ret = mmap(start, length, prot, flags, fd, offset);
+ if (ret == (char *) -1 && (flags & MAP_SHARED)) {
+ ret = mmap(start, length, prot,
+ (flags & ~MAP_SHARED) | MAP_PRIVATE, fd, offset);
+ }
+ return ret;
+}
+
/* bootstrap functions */
static int
FB_Available(void)
@@ -133,7 +161,7 @@
return device;
}
-VideoBootStrap FB_bootstrap = {
+VideoBootStrap FBCON_bootstrap = {
FBVID_DRIVER_NAME, "Linux framebuffer video driver",
FB_Available, FB_CreateDevice
};
@@ -146,12 +174,14 @@
SDL_DisplayMode mode;
struct fb_fix_screeninfo finfo;
const char *SDL_fbdev;
+ const int pagesize = SDL_getpagesize();
/* Initialize the library */
SDL_fbdev = SDL_getenv("SDL_FBDEV");
if (SDL_fbdev == NULL) {
SDL_fbdev = "/dev/fb0";
}
+ /* Open the device */
data->console_fd = open(SDL_fbdev, O_RDWR, 0);
if (data->console_fd < 0) {
SDL_SetError("Unable to open %s", SDL_fbdev);
@@ -174,6 +204,41 @@
return -1;
}
+ switch (finfo.visual) {
+ case FB_VISUAL_TRUECOLOR:
+ case FB_VISUAL_PSEUDOCOLOR:
+ case FB_VISUAL_STATIC_PSEUDOCOLOR:
+ case FB_VISUAL_DIRECTCOLOR:
+ break;
+ default:
+ SDL_SetError("Unsupported console hardware");
+ FB_VideoQuit(_this);
+ return -1;
+ }
+
+ /* Check if the user wants to disable hardware acceleration
+ * FIXME: Maybe better in fbrenderer? */
+ {
+ const char *fb_accel;
+ fb_accel = SDL_getenv("SDL_FBACCEL");
+ if (fb_accel) {
+ finfo.accel = SDL_atoi(fb_accel);
+ }
+ }
+
+ /* Memory map the device, compensating for buggy PPC mmap() */
+ data->mapped_offset = (((long) finfo.smem_start) -
+ (((long) finfo.smem_start) & ~(pagesize - 1)));
+ data->mapped_memlen = finfo.smem_len + data->mapped_offset;
+ data->mapped_mem = (char*) do_mmap(NULL, data->mapped_memlen,
+ PROT_READ | PROT_WRITE, MAP_SHARED, data->console_fd, 0);
+ if (data->mapped_mem == (char *) -1) {
+ SDL_SetError("Unable to memory map the video hardware");
+ data->mapped_mem = NULL;
+ FB_VideoQuit(_this);
+ return -1;
+ }
+
/* Use a fake 32-bpp desktop mode */
mode.format = SDL_PIXELFORMAT_RGB888;
mode.w = 1024;
@@ -191,18 +256,31 @@
return 0;
}
-static int
-FB_SetDisplayMode(_THIS, SDL_DisplayMode * mode)
-{
- deprintf(1, "+FB_SetDisplayMode()\n");
- deprintf(1, "-FB_SetDisplayMode()\n");
- return 0;
-}
-
void
FB_VideoQuit(_THIS)
{
deprintf(1, "+FB_VideoQuit()\n");
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+
+ /* Clear the lock mutex */
+ if (data->hw_lock) {
+ SDL_DestroyMutex(data->hw_lock);
+ data->hw_lock = NULL;
+ }
+
+ /* Close console and input file descriptors */
+ if (data->console_fd > 0) {
+ /* Unmap the video framebuffer and I/O registers */
+ if (data->mapped_mem) {
+ munmap(data->mapped_mem, data->mapped_memlen);
+ data->mapped_mem = NULL;
+ }
+
+ /* We're all done with the framebuffer */
+ close(data->console_fd);
+ data->console_fd = -1;
+ }
+
deprintf(1, "-FB_VideoQuit()\n");
}
--- a/src/video/fbcon-1.3/SDL_fbvideo.h Sat Nov 07 11:35:19 2009 +0000
+++ b/src/video/fbcon-1.3/SDL_fbvideo.h Thu Nov 12 21:44:14 2009 +0000
@@ -58,6 +58,10 @@
int console_fd;
/* hardware surface lock mutex */
SDL_mutex *hw_lock;
+ /* Framebuffer */
+ char *mapped_mem;
+ int mapped_memlen;
+ int mapped_offset;
} SDL_VideoData;
#endif /* _SDL_fbvideo_h */