diff options
Diffstat (limited to 'minui/graphics.c')
-rw-r--r-- | minui/graphics.c | 84 |
1 files changed, 61 insertions, 23 deletions
diff --git a/minui/graphics.c b/minui/graphics.c index 00fbb1eef..8f951756d 100644 --- a/minui/graphics.c +++ b/minui/graphics.c @@ -18,6 +18,7 @@ #include <stdlib.h> #include <unistd.h> +#include <errno.h> #include <fcntl.h> #include <stdio.h> @@ -69,6 +70,15 @@ static int gr_vt_fd = -1; static struct fb_var_screeninfo vi; static struct fb_fix_screeninfo fi; +static bool has_overlay = false; + +bool target_has_overlay(char *version); +int free_ion_mem(void); +int alloc_ion_mem(unsigned int size); +int allocate_overlay(int fd, GGLSurface gr_fb[]); +int free_overlay(int fd); +int overlay_display_frame(int fd, GGLubyte* data, size_t size); + static int get_framebuffer(GGLSurface *fb) { int fd; @@ -127,11 +137,15 @@ static int get_framebuffer(GGLSurface *fb) return -1; } - bits = mmap(0, fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (bits == MAP_FAILED) { - perror("failed to mmap framebuffer"); - close(fd); - return -1; + has_overlay = target_has_overlay(fi.id); + + if (!has_overlay) { + bits = mmap(0, fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (bits == MAP_FAILED) { + perror("failed to mmap framebuffer"); + close(fd); + return -1; + } } overscan_offset_x = vi.xres * overscan_percent / 100; @@ -141,9 +155,11 @@ static int get_framebuffer(GGLSurface *fb) fb->width = vi.xres; fb->height = vi.yres; fb->stride = fi.line_length/PIXEL_SIZE; - fb->data = bits; fb->format = PIXEL_FORMAT; - memset(fb->data, 0, vi.yres * fi.line_length); + if (!has_overlay) { + fb->data = bits; + memset(fb->data, 0, vi.yres * fi.line_length); + } fb++; @@ -157,9 +173,11 @@ static int get_framebuffer(GGLSurface *fb) fb->width = vi.xres; fb->height = vi.yres; fb->stride = fi.line_length/PIXEL_SIZE; - fb->data = (void*) (((unsigned) bits) + vi.yres * fi.line_length); fb->format = PIXEL_FORMAT; - memset(fb->data, 0, vi.yres * fi.line_length); + if (!has_overlay) { + fb->data = (void*) (((unsigned) bits) + vi.yres * fi.line_length); + memset(fb->data, 0, vi.yres * fi.line_length); + } return fd; } @@ -186,19 +204,22 @@ static void set_active_framebuffer(unsigned n) void gr_flip(void) { - GGLContext *gl = gr_context; + if (-EINVAL == overlay_display_frame(gr_fb_fd, gr_mem_surface.data, + (fi.line_length * vi.yres))) { + GGLContext *gl = gr_context; - /* swap front and back buffers */ - if (double_buffering) - gr_active_fb = (gr_active_fb + 1) & 1; + /* swap front and back buffers */ + if (double_buffering) + gr_active_fb = (gr_active_fb + 1) & 1; - /* copy data from the in-memory surface to the buffer we're about - * to make active. */ - memcpy(gr_framebuffer[gr_active_fb].data, gr_mem_surface.data, - fi.line_length * vi.yres); + /* copy data from the in-memory surface to the buffer we're about + * to make active. */ + memcpy(gr_framebuffer[gr_active_fb].data, gr_mem_surface.data, + fi.line_length * vi.yres); - /* inform the display driver */ - set_active_framebuffer(gr_active_fb); + /* inform the display driver */ + set_active_framebuffer(gr_active_fb); + } } void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a) @@ -390,12 +411,13 @@ int gr_init(void) get_memory_surface(&gr_mem_surface); - printf("framebuffer: fd %d (%d x %d)\n", - gr_fb_fd, gr_framebuffer[0].width, gr_framebuffer[0].height); + fprintf(stderr, "framebuffer: fd %d (%d x %d)\n", + gr_fb_fd, gr_framebuffer[0].width, gr_framebuffer[0].height); - /* start with 0 as front (displayed) and 1 as back (drawing) */ + /* start with 0 as front (displayed) and 1 as back (drawing) */ gr_active_fb = 0; - set_active_framebuffer(0); + if (!has_overlay) + set_active_framebuffer(0); gl->colorBuffer(gl, &gr_mem_surface); gl->activeTexture(gl, 0); @@ -405,11 +427,17 @@ int gr_init(void) gr_fb_blank(true); gr_fb_blank(false); + if (!alloc_ion_mem(fi.line_length * vi.yres)) + allocate_overlay(gr_fb_fd, gr_framebuffer); + return 0; } void gr_exit(void) { + free_overlay(gr_fb_fd); + free_ion_mem(); + close(gr_fb_fd); gr_fb_fd = -1; @@ -451,9 +479,19 @@ void gr_fb_blank(bool blank) close(fd); #else int ret; + if (blank) + free_overlay(gr_fb_fd); ret = ioctl(gr_fb_fd, FBIOBLANK, blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK); if (ret < 0) perror("ioctl(): blank"); + + if (!blank) + allocate_overlay(gr_fb_fd, gr_framebuffer); #endif } + +void gr_get_memory_surface(gr_surface surface) +{ + get_memory_surface( (GGLSurface*) surface); +} |