From: notaz Date: Tue, 15 Nov 2011 15:29:55 +0000 (+0200) Subject: update common code to latest from PCSX rearmed X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f9b3f440374c61339a12046b226066658e313065;p=sdl_omap.git update common code to latest from PCSX rearmed may give us 24/32 bpp, maybe. --- diff --git a/configure.in b/configure.in index fa56690..f6a708c 100644 --- a/configure.in +++ b/configure.in @@ -1620,7 +1620,7 @@ AC_HELP_STRING([--enable-video-omapdss], [use OMAP DSS2 video driver [[default=y SOURCES="$SOURCES $srcdir/src/video/omapdss/osdl_video.c" SOURCES="$SOURCES $srcdir/src/video/omapdss/config.c" SOURCES="$SOURCES $srcdir/src/video/omapdss/linux/fbdev.c" - SOURCES="$SOURCES $srcdir/src/video/omapdss/linux/oshide.c" + SOURCES="$SOURCES $srcdir/src/video/omapdss/linux/xenv.c" have_video=yes fi } diff --git a/src/video/omapdss/linux/fbdev.c b/src/video/omapdss/linux/fbdev.c index 6ae0c77..9d532a5 100644 --- a/src/video/omapdss/linux/fbdev.c +++ b/src/video/omapdss/linux/fbdev.c @@ -1,7 +1,10 @@ /* * (C) Gražvydas "notaz" Ignotas, 2009-2010 * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * This work is licensed under the terms of any of these licenses + * (at your option): + * - GNU GPL, version 2 or later. + * - GNU LGPL, version 2.1 or later. * See the COPYING file in the top-level directory. */ @@ -19,8 +22,6 @@ #include "fbdev.h" -#define FBDEV_MAX_BUFFERS 3 - struct vout_fbdev { int fd; void *mem; @@ -60,8 +61,9 @@ void vout_fbdev_wait_vsync(struct vout_fbdev *fbdev) ioctl(fbdev->fd, FBIO_WAITFORVSYNC, &arg); } -int vout_fbdev_resize(struct vout_fbdev *fbdev, int w, int h, - int left_border, int right_border, int top_border, int bottom_border, int no_dblbuf) +/* it is recommended to call vout_fbdev_clear() before this */ +void *vout_fbdev_resize(struct vout_fbdev *fbdev, int w, int h, int bpp, + int left_border, int right_border, int top_border, int bottom_border, int buffer_cnt) { int w_total = left_border + w + right_border; int h_total = top_border + h + bottom_border; @@ -71,55 +73,65 @@ int vout_fbdev_resize(struct vout_fbdev *fbdev, int w, int h, // unblank to be sure the mode is really accepted ioctl(fbdev->fd, FBIOBLANK, FB_BLANK_UNBLANK); - if (fbdev->fbvar_new.bits_per_pixel != 16 || - w != fbdev->fbvar_new.xres || - h != fbdev->fbvar_new.yres || - w_total != fbdev->fbvar_new.xres_virtual || - h_total > fbdev->fbvar_new.yres_virtual || - left_border != fbdev->fbvar_new.xoffset) { + if (fbdev->fbvar_new.bits_per_pixel != bpp || + fbdev->fbvar_new.xres != w || + fbdev->fbvar_new.yres != h || + fbdev->fbvar_new.xres_virtual != w_total|| + fbdev->fbvar_new.yres_virtual < h_total || + fbdev->fbvar_new.xoffset != left_border || + fbdev->buffer_count != buffer_cnt) + { + if (fbdev->fbvar_new.bits_per_pixel != bpp || + w != fbdev->fbvar_new.xres || h != fbdev->fbvar_new.yres) + printf(" switching to %dx%d@%d\n", w, h, bpp); + fbdev->fbvar_new.xres = w; fbdev->fbvar_new.yres = h; fbdev->fbvar_new.xres_virtual = w_total; - fbdev->fbvar_new.yres_virtual = h_total; + fbdev->fbvar_new.yres_virtual = h_total * buffer_cnt; fbdev->fbvar_new.xoffset = left_border; - fbdev->fbvar_new.bits_per_pixel = 16; - printf(" switching to %dx%d@16\n", w, h); - ret = ioctl(fbdev->fd, FBIOPUT_VSCREENINFO, &fbdev->fbvar_new); - if (ret == -1) { - perror("FBIOPUT_VSCREENINFO ioctl"); - return -1; - } - } + fbdev->fbvar_new.yoffset = top_border; + fbdev->fbvar_new.bits_per_pixel = bpp; + fbdev->fbvar_new.nonstd = 0; // can set YUV here on omapfb + fbdev->buffer_count = buffer_cnt; + fbdev->buffer_write = 1; - fbdev->buffer_count = FBDEV_MAX_BUFFERS; // be optimistic - if (no_dblbuf) - fbdev->buffer_count = 1; + // seems to help a bit to avoid glitches + vout_fbdev_wait_vsync(fbdev); - if (fbdev->fbvar_new.yres_virtual < h_total * fbdev->buffer_count) { - fbdev->fbvar_new.yres_virtual = h_total * fbdev->buffer_count; ret = ioctl(fbdev->fd, FBIOPUT_VSCREENINFO, &fbdev->fbvar_new); if (ret == -1) { + // retry with no multibuffering + fbdev->fbvar_new.yres_virtual = h_total; + ret = ioctl(fbdev->fd, FBIOPUT_VSCREENINFO, &fbdev->fbvar_new); + if (ret == -1) { + perror("FBIOPUT_VSCREENINFO ioctl"); + return NULL; + } fbdev->buffer_count = 1; + fbdev->buffer_write = 0; fprintf(stderr, "Warning: failed to increase virtual resolution, " - "doublebuffering disabled\n"); + "multibuffering disabled\n"); } + } - fbdev->fb_size = w_total * h_total * 2; + fbdev->fb_size = w_total * h_total * bpp / 8; fbdev->top_border = top_border; fbdev->bottom_border = bottom_border; mem_size = fbdev->fb_size * fbdev->buffer_count; if (fbdev->mem_size >= mem_size) - return 0; + goto out; if (fbdev->mem != NULL) munmap(fbdev->mem, fbdev->mem_size); fbdev->mem = mmap(0, mem_size, PROT_WRITE|PROT_READ, MAP_SHARED, fbdev->fd, 0); if (fbdev->mem == MAP_FAILED && fbdev->buffer_count > 1) { - fprintf(stderr, "Warning: can't map %zd bytes, doublebuffering disabled\n", fbdev->mem_size); + fprintf(stderr, "Warning: can't map %zd bytes, doublebuffering disabled\n", mem_size); fbdev->buffer_count = 1; + fbdev->buffer_write = 0; mem_size = fbdev->fb_size; fbdev->mem = mmap(0, mem_size, PROT_WRITE|PROT_READ, MAP_SHARED, fbdev->fd, 0); } @@ -127,11 +139,13 @@ int vout_fbdev_resize(struct vout_fbdev *fbdev, int w, int h, fbdev->mem = NULL; fbdev->mem_size = 0; perror("mmap framebuffer"); - return -1; + return NULL; } fbdev->mem_size = mem_size; - return 0; + +out: + return (char *)fbdev->mem + fbdev->fb_size * fbdev->buffer_write; } void vout_fbdev_clear(struct vout_fbdev *fbdev) @@ -157,10 +171,11 @@ int vout_fbdev_get_fd(struct vout_fbdev *fbdev) return fbdev->fd; } -struct vout_fbdev *vout_fbdev_init(const char *fbdev_name, int *w, int *h, int no_dblbuf) +struct vout_fbdev *vout_fbdev_init(const char *fbdev_name, int *w, int *h, int bpp, int buffer_cnt) { struct vout_fbdev *fbdev; int req_w, req_h; + void *pret; int ret; fbdev = calloc(1, sizeof(*fbdev)); @@ -189,8 +204,8 @@ struct vout_fbdev *vout_fbdev_init(const char *fbdev_name, int *w, int *h, int n if (*h != 0) req_h = *h; - ret = vout_fbdev_resize(fbdev, req_w, req_h, 0, 0, 0, 0, no_dblbuf); - if (ret != 0) + pret = vout_fbdev_resize(fbdev, req_w, req_h, bpp, 0, 0, 0, 0, buffer_cnt); + if (pret == NULL) goto fail; printf("%s: %ix%i@%d\n", fbdev_name, fbdev->fbvar_new.xres, fbdev->fbvar_new.yres, diff --git a/src/video/omapdss/linux/fbdev.h b/src/video/omapdss/linux/fbdev.h index fa163aa..2db9163 100644 --- a/src/video/omapdss/linux/fbdev.h +++ b/src/video/omapdss/linux/fbdev.h @@ -1,11 +1,11 @@ struct vout_fbdev; -struct vout_fbdev *vout_fbdev_init(const char *fbdev_name, int *w, int *h, int no_dblbuf); +struct vout_fbdev *vout_fbdev_init(const char *fbdev_name, int *w, int *h, int bpp, int buffer_count); void *vout_fbdev_flip(struct vout_fbdev *fbdev); void vout_fbdev_wait_vsync(struct vout_fbdev *fbdev); -int vout_fbdev_resize(struct vout_fbdev *fbdev, int w, int h, +void *vout_fbdev_resize(struct vout_fbdev *fbdev, int w, int h, int bpp, int left_border, int right_border, int top_border, int bottom_border, - int no_dblbuf); + int buffer_count); void vout_fbdev_clear(struct vout_fbdev *fbdev); void vout_fbdev_clear_lines(struct vout_fbdev *fbdev, int y, int count); int vout_fbdev_get_fd(struct vout_fbdev *fbdev); diff --git a/src/video/omapdss/linux/oshide.h b/src/video/omapdss/linux/oshide.h deleted file mode 100644 index f661305..0000000 --- a/src/video/omapdss/linux/oshide.h +++ /dev/null @@ -1,3 +0,0 @@ -int oshide_init(void); -void oshide_finish(void); - diff --git a/src/video/omapdss/linux/oshide.c b/src/video/omapdss/linux/xenv.c similarity index 51% rename from src/video/omapdss/linux/oshide.c rename to src/video/omapdss/linux/xenv.c index 484618d..3de7628 100644 --- a/src/video/omapdss/linux/oshide.c +++ b/src/video/omapdss/linux/xenv.c @@ -1,7 +1,10 @@ /* - * (C) Gražvydas "notaz" Ignotas, 2009-2010 + * (C) Gražvydas "notaz" Ignotas, 2009-2011 * - * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * This work is licensed under the terms of any of these licenses + * (at your option): + * - GNU GPL, version 2 or later. + * - GNU LGPL, version 2.1 or later. * See the COPYING file in the top-level directory. */ @@ -12,6 +15,7 @@ #include #include #include +#include #include #include @@ -21,7 +25,7 @@ #include #include -#define PFX "oshide: " +#define PFX "xenv: " #define FPTR(f) typeof(f) * p##f #define FPTR_LINK(xf, dl, f) { \ @@ -32,25 +36,30 @@ } \ } -struct xfuncs { -FPTR(XCreateBitmapFromData); -FPTR(XCreatePixmapCursor); -FPTR(XFreePixmap); -FPTR(XOpenDisplay); -FPTR(XDisplayName); -FPTR(XCloseDisplay); -FPTR(XCreateSimpleWindow); -FPTR(XChangeWindowAttributes); -FPTR(XSelectInput); -FPTR(XMapWindow); -FPTR(XNextEvent); -FPTR(XCheckTypedEvent); -FPTR(XUnmapWindow); -FPTR(XGrabKeyboard); +struct xstuff { + Display *display; + FPTR(XCreateBitmapFromData); + FPTR(XCreatePixmapCursor); + FPTR(XFreePixmap); + FPTR(XOpenDisplay); + FPTR(XDisplayName); + FPTR(XCloseDisplay); + FPTR(XCreateSimpleWindow); + FPTR(XChangeWindowAttributes); + FPTR(XSelectInput); + FPTR(XMapWindow); + FPTR(XNextEvent); + FPTR(XCheckTypedEvent); + FPTR(XUnmapWindow); + FPTR(XGrabKeyboard); + FPTR(XPending); + FPTR(XLookupKeysym); + FPTR(XkbSetDetectableAutoRepeat); }; +static struct xstuff g_xstuff; -static Cursor transparent_cursor(struct xfuncs *xf, Display *display, Window win) +static Cursor transparent_cursor(struct xstuff *xf, Display *display, Window win) { Cursor cursor; Pixmap pix; @@ -65,46 +74,47 @@ static Cursor transparent_cursor(struct xfuncs *xf, Display *display, Window win return cursor; } -static void *x11h_handler(void *arg) +static int x11h_init(void) { - struct xfuncs xf; unsigned int display_width, display_height; + Display *display; XSetWindowAttributes attributes; Window win; - XEvent report; - Display *display; Visual *visual; void *x11lib; int screen; - memset(&xf, 0, sizeof(xf)); + memset(&g_xstuff, 0, sizeof(g_xstuff)); x11lib = dlopen("libX11.so.6", RTLD_LAZY); if (x11lib == NULL) { fprintf(stderr, "libX11.so load failed:\n%s\n", dlerror()); goto fail; } - FPTR_LINK(xf, x11lib, XCreateBitmapFromData); - FPTR_LINK(xf, x11lib, XCreatePixmapCursor); - FPTR_LINK(xf, x11lib, XFreePixmap); - FPTR_LINK(xf, x11lib, XOpenDisplay); - FPTR_LINK(xf, x11lib, XDisplayName); - FPTR_LINK(xf, x11lib, XCloseDisplay); - FPTR_LINK(xf, x11lib, XCreateSimpleWindow); - FPTR_LINK(xf, x11lib, XChangeWindowAttributes); - FPTR_LINK(xf, x11lib, XSelectInput); - FPTR_LINK(xf, x11lib, XMapWindow); - FPTR_LINK(xf, x11lib, XNextEvent); - FPTR_LINK(xf, x11lib, XCheckTypedEvent); - FPTR_LINK(xf, x11lib, XUnmapWindow); - FPTR_LINK(xf, x11lib, XGrabKeyboard); + FPTR_LINK(g_xstuff, x11lib, XCreateBitmapFromData); + FPTR_LINK(g_xstuff, x11lib, XCreatePixmapCursor); + FPTR_LINK(g_xstuff, x11lib, XFreePixmap); + FPTR_LINK(g_xstuff, x11lib, XOpenDisplay); + FPTR_LINK(g_xstuff, x11lib, XDisplayName); + FPTR_LINK(g_xstuff, x11lib, XCloseDisplay); + FPTR_LINK(g_xstuff, x11lib, XCreateSimpleWindow); + FPTR_LINK(g_xstuff, x11lib, XChangeWindowAttributes); + FPTR_LINK(g_xstuff, x11lib, XSelectInput); + FPTR_LINK(g_xstuff, x11lib, XMapWindow); + FPTR_LINK(g_xstuff, x11lib, XNextEvent); + FPTR_LINK(g_xstuff, x11lib, XCheckTypedEvent); + FPTR_LINK(g_xstuff, x11lib, XUnmapWindow); + FPTR_LINK(g_xstuff, x11lib, XGrabKeyboard); + FPTR_LINK(g_xstuff, x11lib, XPending); + FPTR_LINK(g_xstuff, x11lib, XLookupKeysym); + FPTR_LINK(g_xstuff, x11lib, XkbSetDetectableAutoRepeat); //XInitThreads(); - display = xf.pXOpenDisplay(NULL); + g_xstuff.display = display = g_xstuff.pXOpenDisplay(NULL); if (display == NULL) { fprintf(stderr, "cannot connect to X server %s, X handling disabled.\n", - xf.pXDisplayName(NULL)); + g_xstuff.pXDisplayName(NULL)); goto fail2; } @@ -122,57 +132,63 @@ static void *x11h_handler(void *arg) display_height = DisplayHeight(display, screen); printf(PFX "display is %dx%d\n", display_width, display_height); - win = xf.pXCreateSimpleWindow(display, + win = g_xstuff.pXCreateSimpleWindow(display, RootWindow(display, screen), 0, 0, display_width, display_height, 0, BlackPixel(display, screen), BlackPixel(display, screen)); attributes.override_redirect = True; - attributes.cursor = transparent_cursor(&xf, display, win); - xf.pXChangeWindowAttributes(display, win, CWOverrideRedirect | CWCursor, &attributes); + attributes.cursor = transparent_cursor(&g_xstuff, display, win); + g_xstuff.pXChangeWindowAttributes(display, win, CWOverrideRedirect | CWCursor, &attributes); - xf.pXSelectInput(display, win, ExposureMask | FocusChangeMask | KeyPressMask | KeyReleaseMask); - xf.pXMapWindow(display, win); - xf.pXGrabKeyboard(display, win, False, GrabModeAsync, GrabModeAsync, CurrentTime); + g_xstuff.pXSelectInput(display, win, ExposureMask | FocusChangeMask | KeyPressMask | KeyReleaseMask); + g_xstuff.pXMapWindow(display, win); + g_xstuff.pXGrabKeyboard(display, win, False, GrabModeAsync, GrabModeAsync, CurrentTime); + g_xstuff.pXkbSetDetectableAutoRepeat(display, 1, NULL); // XSetIOErrorHandler - while (1) + return 0; +fail2: + dlclose(x11lib); +fail: + g_xstuff.display = NULL; + fprintf(stderr, "x11 handling disabled.\n"); + return -1; +} + +static int x11h_update(int *is_down) +{ + XEvent evt; + + while (g_xstuff.pXPending(g_xstuff.display)) { - xf.pXNextEvent(display, &report); - switch (report.type) + g_xstuff.pXNextEvent(g_xstuff.display, &evt); + switch (evt.type) { case Expose: - while (xf.pXCheckTypedEvent(display, Expose, &report)) + while (g_xstuff.pXCheckTypedEvent(g_xstuff.display, Expose, &evt)) ; break; - case FocusOut: - // XFocusChangeEvent - // printf("focus out\n"); - // xf.pXUnmapWindow(display, win); - break; - case KeyPress: - // printf("press %d\n", report.xkey.keycode); - break; + *is_down = 1; + return g_xstuff.pXLookupKeysym(&evt.xkey, 0); - default: - break; + case KeyRelease: + *is_down = 0; + return g_xstuff.pXLookupKeysym(&evt.xkey, 0); + // printf("press %d\n", evt.xkey.keycode); } } -fail2: - dlclose(x11lib); -fail: - fprintf(stderr, "x11 handling disabled.\n"); - return NULL; + return NoSymbol; } static struct termios g_kbd_termios_saved; -static int g_kbdfd; +static int g_kbdfd = -1; -static void hidecon_start(void) +static int tty_init(void) { struct termios kbd_termios; int mode; @@ -180,7 +196,7 @@ static void hidecon_start(void) g_kbdfd = open("/dev/tty", O_RDWR); if (g_kbdfd == -1) { perror(PFX "open /dev/tty"); - return; + return -1; } if (ioctl(g_kbdfd, KDGETMODE, &mode) == -1) { @@ -210,14 +226,15 @@ static void hidecon_start(void) goto fail; } - return; + return 0; fail: close(g_kbdfd); g_kbdfd = -1; + return -1; } -static void hidecon_end(void) +static void tty_end(void) { if (g_kbdfd < 0) return; @@ -232,34 +249,33 @@ static void hidecon_end(void) g_kbdfd = -1; } -int oshide_init(void) +int xenv_init(void) { - pthread_t tid; int ret; - ret = pthread_create(&tid, NULL, x11h_handler, NULL); - if (ret != 0) { - fprintf(stderr, PFX "failed to create thread: %d\n", ret); - return ret; - } - pthread_detach(tid); + ret = x11h_init(); + if (ret == 0) + return 0; - hidecon_start(); + ret = tty_init(); + if (ret == 0) + return 0; - return 0; + fprintf(stderr, PFX "error: both x11h_init and tty_init failed\n"); + return -1; } -void oshide_finish(void) +int xenv_update(int *is_down) { - /* XXX: the X thread.. */ + if (g_xstuff.display) + return x11h_update(is_down); - hidecon_end(); + // TODO: read tty? + return -1; } -#if 0 -int main() +void xenv_finish(void) { - x11h_init(); - sleep(5); + // TODO: cleanup X? + tty_end(); } -#endif diff --git a/src/video/omapdss/linux/xenv.h b/src/video/omapdss/linux/xenv.h new file mode 100644 index 0000000..948381e --- /dev/null +++ b/src/video/omapdss/linux/xenv.h @@ -0,0 +1,5 @@ + +int xenv_init(void); +int xenv_update(int *is_down); +void xenv_finish(void); + diff --git a/src/video/omapdss/omapsdl.h b/src/video/omapdss/omapsdl.h index bd5c109..5e73782 100644 --- a/src/video/omapdss/omapsdl.h +++ b/src/video/omapdss/omapsdl.h @@ -29,7 +29,7 @@ struct SDL_PrivateVideoData { struct vout_fbdev *fbdev; void *saved_layer; int screen_w, screen_h; - unsigned int oshide_done:1; + unsigned int xenv_up:1; }; int osdl_video_set_mode(struct SDL_PrivateVideoData *pdata, int width, int height, int bpp); diff --git a/src/video/omapdss/osdl_video.c b/src/video/omapdss/osdl_video.c index bc6d9da..108ef8a 100644 --- a/src/video/omapdss/osdl_video.c +++ b/src/video/omapdss/osdl_video.c @@ -1,5 +1,5 @@ /* - * (C) Gražvydas "notaz" Ignotas, 2010 + * (C) Gražvydas "notaz" Ignotas, 2010-2011 * * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. * See the COPYING file in the top-level directory. @@ -20,7 +20,7 @@ #include "omapsdl.h" #include "omapfb.h" #include "linux/fbdev.h" -#include "linux/oshide.h" +#include "linux/xenv.h" struct omapfb_saved_layer { struct omapfb_plane_info pi; @@ -274,7 +274,7 @@ static int osdl_setup_omap_layer(struct SDL_PrivateVideoData *pdata, x = screen_w / 2 - w / 2; y = screen_h / 2 - h / 2; - ret = osdl_setup_omapfb(fd, 1, x, y, w, h, width * height * ((bpp + 7) / 8) * 3); + ret = osdl_setup_omapfb(fd, 1, x, y, w, h, width * height * ((bpp + 7) / 8) * 2); close(fd); return ret; @@ -285,8 +285,6 @@ int osdl_video_set_mode(struct SDL_PrivateVideoData *pdata, int width, int heigh const char *fbname; int ret; - bpp = 16; // FIXME - fbname = get_fb_device(); if (pdata->fbdev != NULL) { @@ -300,13 +298,14 @@ int osdl_video_set_mode(struct SDL_PrivateVideoData *pdata, int width, int heigh if (ret < 0) return -1; - pdata->fbdev = vout_fbdev_init(fbname, &width, &height, 0); + pdata->fbdev = vout_fbdev_init(fbname, &width, &height, bpp, 2); if (pdata->fbdev == NULL) return -1; - if (!pdata->oshide_done) { - oshide_init(); - pdata->oshide_done = 1; + if (!pdata->xenv_up) { + ret = xenv_init(); + if (ret == 0) + pdata->xenv_up = 1; } return 0; @@ -356,9 +355,9 @@ void osdl_video_finish(struct SDL_PrivateVideoData *pdata) pdata->saved_layer = NULL; } - if (pdata->oshide_done) { - oshide_finish(); - pdata->oshide_done = 0; + if (pdata->xenv_up) { + xenv_finish(); + pdata->xenv_up = 0; } } diff --git a/src/video/omapdss/sdlif.c b/src/video/omapdss/sdlif.c index 4628735..71ea5c0 100644 --- a/src/video/omapdss/sdlif.c +++ b/src/video/omapdss/sdlif.c @@ -11,6 +11,8 @@ #include "../SDL_sysvideo.h" #include "../SDL_pixels_c.h" #include "../../events/SDL_events_c.h" + +#include "linux/xenv.h" #include "omapsdl.h" @@ -190,9 +192,16 @@ static int ts_event_cb(void *cb_arg, int x, int y, unsigned int pressure) static void omap_PumpEvents(SDL_VideoDevice *this) { + struct SDL_PrivateVideoData *pdata = this->hidden; + int dummy; + trace(); omapsdl_input_get_events(0, key_event_cb, ts_event_cb, NULL); + + // XXX: we might want to process some X events too + if (pdata->xenv_up) + xenv_update(&dummy); } static SDL_VideoDevice *omap_create(int devindex)