From 0bb19c41766026c798f9c2aa9dc433a9403c8e39 Mon Sep 17 00:00:00 2001 From: notaz Date: Wed, 23 Nov 2011 01:00:03 +0200 Subject: [PATCH] don't force double buffering honour SDL_DOUBLEBUF insead. Also add an option to force this flag for old behavior. --- README.OMAP | 10 ++++++++- src/video/omapdss/config.c | 10 ++++++++- src/video/omapdss/omapsdl.h | 6 ++++-- src/video/omapdss/osdl_video.c | 7 +++--- src/video/omapdss/sdlif.c | 39 +++++++++++++++++++++++----------- 5 files changed, 52 insertions(+), 20 deletions(-) diff --git a/README.OMAP b/README.OMAP index 0b5bb4c..b39fb33 100644 --- a/README.OMAP +++ b/README.OMAP @@ -39,7 +39,7 @@ SDL_OMAP_LAYER_SIZE: Output layer size. Regardless what you set with SDL_SetVideoMode(), output will be scaled to this size using hardware. Valid values: "WxH", for example "640x480" - "fullscreen" for to cover whole screen. + "fullscreen" to cover whole screen. SDL_OMAP_VSYNC: Enables waiting for vertical sync on SDL_Flip() calls. @@ -49,6 +49,11 @@ SDL_OMAP_DEFAULT_MODE: If the app doesn't specify resolution in SDL_SetVideoMode(), then use this. Should be specified in "WxH" format, for example "640x480". +SDL_OMAP_FORCE_DOUBLEBUF: + This can force double buffering to on, which can help to eliminate tearing. + Note that if app isn't updating whole buffer each frame, it will glitch. + This is the same as specifying SDL_DOUBLEBUF to SDL_SetVideoMode. + Config file ----------- @@ -60,6 +65,9 @@ options (only when omapdss driver is active): # same as SDL_OMAP_VSYNC force_vsync = 1/0 +# same as SDL_OMAP_FORCE_DOUBLEBUF +force_doublebuf = 1/0 + # can be used to bind a key to SDL keysym, good for quick ports. # Example: # bind ev_home = sdlk_space diff --git a/src/video/omapdss/config.c b/src/video/omapdss/config.c index a70cd3c..adedaef 100644 --- a/src/video/omapdss/config.c +++ b/src/video/omapdss/config.c @@ -14,6 +14,7 @@ #include "omapsdl.h" int gcfg_force_vsync; +int gcfg_force_doublebuf; static char *sskip(char *p) { @@ -89,6 +90,10 @@ void omapsdl_config(void) gcfg_force_vsync = strtol(p, NULL, 0); continue; } + else if (check_token_eq(&p, "force_doublebuf")) { + gcfg_force_doublebuf = strtol(p, NULL, 0); + continue; + } bad: err("config: failed to parse: %s", line); @@ -102,6 +107,9 @@ void omapsdl_config_from_env(void) tmp = getenv("SDL_OMAP_VSYNC"); if (tmp != NULL) - gcfg_force_vsync = atoi(tmp); + gcfg_force_vsync = strtol(tmp, NULL, 0); + tmp = getenv("SDL_OMAP_FORCE_DOUBLEBUF"); + if (tmp != NULL) + gcfg_force_doublebuf = strtol(tmp, NULL, 0); } diff --git a/src/video/omapdss/omapsdl.h b/src/video/omapdss/omapsdl.h index 5e73782..3f15bb7 100644 --- a/src/video/omapdss/omapsdl.h +++ b/src/video/omapdss/omapsdl.h @@ -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. @@ -32,7 +32,8 @@ struct SDL_PrivateVideoData { unsigned int xenv_up:1; }; -int osdl_video_set_mode(struct SDL_PrivateVideoData *pdata, int width, int height, int bpp); +int osdl_video_set_mode(struct SDL_PrivateVideoData *pdata, + int width, int height, int bpp, int doublebuf); void *osdl_video_flip(struct SDL_PrivateVideoData *pdata); int osdl_video_detect_screen(struct SDL_PrivateVideoData *pdata); void osdl_video_finish(struct SDL_PrivateVideoData *pdata); @@ -53,3 +54,4 @@ void do_clut(void *dest, void *src, unsigned short *pal, int count); /* config */ extern int gcfg_force_vsync; +extern int gcfg_force_doublebuf; diff --git a/src/video/omapdss/osdl_video.c b/src/video/omapdss/osdl_video.c index 108ef8a..ee4c95a 100644 --- a/src/video/omapdss/osdl_video.c +++ b/src/video/omapdss/osdl_video.c @@ -280,7 +280,8 @@ static int osdl_setup_omap_layer(struct SDL_PrivateVideoData *pdata, return ret; } -int osdl_video_set_mode(struct SDL_PrivateVideoData *pdata, int width, int height, int bpp) +int osdl_video_set_mode(struct SDL_PrivateVideoData *pdata, + int width, int height, int bpp, int doublebuf) { const char *fbname; int ret; @@ -292,13 +293,11 @@ int osdl_video_set_mode(struct SDL_PrivateVideoData *pdata, int width, int heigh pdata->fbdev = NULL; } - omapsdl_config_from_env(); - ret = osdl_setup_omap_layer(pdata, fbname, width, height, bpp); if (ret < 0) return -1; - pdata->fbdev = vout_fbdev_init(fbname, &width, &height, bpp, 2); + pdata->fbdev = vout_fbdev_init(fbname, &width, &height, bpp, doublebuf ? 2 : 1); if (pdata->fbdev == NULL) return -1; diff --git a/src/video/omapdss/sdlif.c b/src/video/omapdss/sdlif.c index f7ab47f..fd4925c 100644 --- a/src/video/omapdss/sdlif.c +++ b/src/video/omapdss/sdlif.c @@ -92,9 +92,13 @@ static SDL_Surface *omap_SetVideoMode(SDL_VideoDevice *this, SDL_Surface *curren int height, int bpp, Uint32 flags) { SDL_PixelFormat *format; + Uint32 unhandled_flags; + int ret; trace("%d, %d, %d, %08x", width, height, bpp, flags); + omapsdl_config_from_env(); + switch (bpp) { case 16: format = SDL_ReallocFormat(current, 16, 0xf800, 0x07e0, 0x001f, 0); @@ -106,16 +110,30 @@ static SDL_Surface *omap_SetVideoMode(SDL_VideoDevice *this, SDL_Surface *curren format = SDL_ReallocFormat(current, 32, 0xff0000, 0xff00, 0xff, 0xff000000); break; default: - err("SetVideoMode: bpp %d not supported\n", bpp); + err("SetVideoMode: bpp %d not supported", bpp); return NULL; } if (format == NULL) return NULL; - if (osdl_video_set_mode(this->hidden, width, height, bpp) < 0) + if (!(flags & SDL_DOUBLEBUF) && gcfg_force_doublebuf) { + log("forcing SDL_DOUBLEBUF"); + flags |= SDL_DOUBLEBUF; + } + + ret = osdl_video_set_mode(this->hidden, width, height, bpp, + (flags & SDL_DOUBLEBUF) ? 1 : 0); + if (ret < 0) return NULL; - current->flags = SDL_FULLSCREEN | SDL_DOUBLEBUF | SDL_HWSURFACE; + flags |= SDL_FULLSCREEN | SDL_HWSURFACE; + unhandled_flags = flags & ~(SDL_FULLSCREEN | SDL_HWSURFACE | SDL_DOUBLEBUF); + if (unhandled_flags != 0) { + log("dropping unhandled flags: %08x", unhandled_flags); + flags &= ~unhandled_flags; + } + + current->flags = flags; current->w = width; current->h = height; current->pitch = SDL_CalculatePitch(current); @@ -168,16 +186,13 @@ static void omap_UpdateRects(SDL_VideoDevice *this, int nrects, SDL_Rect *rects) { trace("%d, %p", nrects, rects); - if (nrects != 1 || rects->x != 0 || rects->y != 0 || - rects->w != this->screen->w || rects->h != this->screen->h) { - static int warned = 0; - if (!warned) { - not_supported(); - warned = 1; - } + /* hmh.. */ + if (nrects == 1 && rects->x == 0 && rects->y == 0 && + (this->screen->flags & SDL_DOUBLEBUF) && + rects->w == this->screen->w && rects->h == this->screen->h) + { + this->screen->pixels = osdl_video_flip(this->hidden); } - - this->screen->pixels = osdl_video_flip(this->hidden); } static void omap_InitOSKeymap(SDL_VideoDevice *this) -- 2.39.2