don't force double buffering
authornotaz <notasas@gmail.com>
Tue, 22 Nov 2011 23:00:03 +0000 (01:00 +0200)
committernotaz <notasas@gmail.com>
Tue, 22 Nov 2011 23:04:25 +0000 (01:04 +0200)
honour SDL_DOUBLEBUF insead. Also add an option to force
this flag for old behavior.

README.OMAP
src/video/omapdss/config.c
src/video/omapdss/omapsdl.h
src/video/omapdss/osdl_video.c
src/video/omapdss/sdlif.c

index 0b5bb4c..b39fb33 100644 (file)
@@ -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
index a70cd3c..adedaef 100644 (file)
@@ -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);
 }
 
index 5e73782..3f15bb7 100644 (file)
@@ -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;
index 108ef8a..ee4c95a 100644 (file)
@@ -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;
 
index f7ab47f..fd4925c 100644 (file)
@@ -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)