fix vram realloc
[sdl_omap.git] / src / video / omapdss / osdl_video.c
index b6abb93..56c5485 100644 (file)
@@ -22,6 +22,8 @@
 #include "linux/fbdev.h"
 #include "linux/xenv.h"
 
+#define MIN(a, b) ( ((a) < (b)) ? (a) : (b) )
+
 struct omapfb_state {
        struct omapfb_plane_info pi;
        struct omapfb_mem_info mi;
@@ -44,6 +46,7 @@ static int osdl_setup_omapfb(struct omapfb_state *ostate, int fd, int enabled,
        struct omapfb_plane_info pi;
        struct omapfb_mem_info mi;
        int mem_blocks = *buffer_count;
+       unsigned int size_cur;
        int ret;
 
        memset(&pi, 0, sizeof(pi));
@@ -60,6 +63,7 @@ static int osdl_setup_omapfb(struct omapfb_state *ostate, int fd, int enabled,
                err_perror("QUERY_MEM");
                return -1;
        }
+       size_cur = mi.size;
 
        /* must disable when changing stuff */
        if (pi.enabled) {
@@ -69,19 +73,20 @@ static int osdl_setup_omapfb(struct omapfb_state *ostate, int fd, int enabled,
                        err_perror("SETUP_PLANE");
        }
 
-       if (mi.size < mem * mem_blocks) {
-               for (; mem_blocks > 0; mem_blocks--) {
-                       mi.size = mem * mem_blocks;
-                       ret = ioctl(fd, OMAPFB_SETUP_MEM, &mi);
-                       if (ret == 0)
-                               break;
-               }
-               if (ret != 0 || mem_blocks <= 0) {
-                       err("failed to allocate at least %d bytes of vram:\n", mem);
-                       err_perror("SETUP_MEM");
-                       return -1;
-               }
+       /* allocate more mem, if needed */
+       for (; size_cur < mem * mem_blocks && mem_blocks > 0; mem_blocks--) {
+               mi.size = mem * mem_blocks;
+               ret = ioctl(fd, OMAPFB_SETUP_MEM, &mi);
+               if (ret == 0)
+                       break;
+               mi.size = size_cur;
+       }
+       if (mem_blocks <= 0) {
+               err("failed to allocate at least %d bytes of vram:\n", mem);
+               err_perror("SETUP_MEM");
+               return -1;
        }
+
        *buffer_count = mem_blocks;
 
        pi.pos_x = x;
@@ -300,13 +305,28 @@ static int osdl_setup_omap_layer(struct SDL_PrivateVideoData *pdata,
 
        tmp = getenv("SDL_OMAP_LAYER_SIZE");
        if (tmp != NULL) {
-               if (strcasecmp(tmp, "fullscreen") == 0)
+               if (strcasecmp(tmp, "fullscreen") == 0) {
                        w = screen_w, h = screen_h;
-               else if (sscanf(tmp, "%dx%d", &tmp_w, &tmp_h) == 2)
+               }
+               else if (strcasecmp(tmp, "scaled") == 0) {
+                       float factor = MIN(((float)screen_w) / width, ((float)screen_h) / height);
+                       w = (int)(factor*width), h = (int)(factor*height);
+               }
+               else if (strcasecmp(tmp, "pixelperfect") == 0) {
+                       float factor = MIN(((float)screen_w) / width, ((float)screen_h) / height);
+                       w = ((int)factor) * width, h = ((int)factor) * height;
+                       /* factor < 1.f => 0x0 layer, so fall back to 'scaled' */
+                       if (!w || !h) {
+                               w = (int)(factor * width), h = (int)(factor * height);
+                       }
+               }
+               else if (sscanf(tmp, "%dx%d", &tmp_w, &tmp_h) == 2) {
                        w = tmp_w, h = tmp_h;
-               else
+               }
+               else {
                        err("layer size specified incorrectly, "
                                "should be like 800x480");
+               }
        }
 
        /* the layer can't be set larger than screen */