#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;
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));
err_perror("QUERY_MEM");
return -1;
}
+ size_cur = mi.size;
/* must disable when changing stuff */
if (pi.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;
return 0;
}
+static int osdl_setup_omapfb_enable(struct omapfb_state *ostate,
+ int fd, int enabled)
+{
+ int ret;
+
+ ostate->pi.enabled = enabled;
+ ret = ioctl(fd, OMAPFB_SETUP_PLANE, &ostate->pi);
+ if (ret != 0)
+ err_perror("SETUP_PLANE");
+
+ return ret;
+}
+
static int read_sysfs(const char *fname, char *buff, size_t size)
{
FILE *f;
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 */
x = screen_w / 2 - w / 2;
y = screen_h / 2 - h / 2;
- ret = osdl_setup_omapfb(pdata->saved_layer, fd, 1, x, y, w, h,
+ ret = osdl_setup_omapfb(pdata->saved_layer, fd, 0, x, y, w, h,
width * height * ((bpp + 7) / 8), buffer_count);
if (ret == 0) {
pdata->layer_x = x;
}
}
+ ret = osdl_setup_omapfb_enable(pdata->saved_layer,
+ vout_fbdev_get_fd(pdata->fbdev), 1);
+ if (ret != 0) {
+ err("layer enable failed");
+ goto fail;
+ }
+
if (buffers_try != buffers_set) {
log("only %d/%d buffers available, expect tearing\n",
buffers_set, buffers_try);