summaryrefslogtreecommitdiffstats
path: root/minui/graphics.c
diff options
context:
space:
mode:
Diffstat (limited to 'minui/graphics.c')
-rw-r--r--minui/graphics.c84
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);
+}