static sunxi_disp_t *sunxi_disp_init(const char *device)
{
   int tmp, version;
   struct fb_var_screeninfo fb_var;
   struct fb_fix_screeninfo fb_fix;
   sunxi_disp_t *ctx = (sunxi_disp_t*)calloc(1, sizeof(sunxi_disp_t));

   if (!ctx)
      return NULL;

   /* use /dev/fb0 by default */
   if (!device)
      device = "/dev/fb0";

   if (!strcmp(device, "/dev/fb0"))
      ctx->fb_id = 0;
   else if (!strcmp(device, "/dev/fb1"))
      ctx->fb_id = 1;
   else
      goto error;

   ctx->fd_disp = open("/dev/disp", O_RDWR);

   /* maybe it's even not a sunxi hardware */
   if (ctx->fd_disp < 0)
      goto error;

   /* version check */
   tmp     = SUNXI_DISP_VERSION;
   version = ioctl(ctx->fd_disp, DISP_CMD_VERSION, &tmp);
   if (version < 0)
   {
       close(ctx->fd_disp);
       goto error;
   }

   ctx->fd_fb = open(device, O_RDWR);

   if (ctx->fd_fb < 0)
   {
      close(ctx->fd_disp);
      goto error;
   }

   if (ioctl(ctx->fd_fb, FBIOGET_VSCREENINFO, &fb_var) < 0 ||
         ioctl(ctx->fd_fb, FBIOGET_FSCREENINFO, &fb_fix) < 0)
   {
      close(ctx->fd_fb);
      close(ctx->fd_disp);
      goto error;
   }

   ctx->xres               = fb_var.xres;
   ctx->yres               = fb_var.yres;
   ctx->bits_per_pixel     = fb_var.bits_per_pixel;
   ctx->framebuffer_paddr  = fb_fix.smem_start;
   ctx->framebuffer_size   = fb_fix.smem_len;
   ctx->framebuffer_height = ctx->framebuffer_size /
      (ctx->xres * ctx->bits_per_pixel / 8);
   ctx->gfx_layer_size     = ctx->xres * ctx->yres * fb_var.bits_per_pixel / 8;

   if (ctx->framebuffer_size < ctx->gfx_layer_size)
   {
      close(ctx->fd_fb);
      close(ctx->fd_disp);
      goto error;
   }

   /* mmap framebuffer memory */
   ctx->framebuffer_addr = (uint8_t *)mmap(0, ctx->framebuffer_size,
	 PROT_READ | PROT_WRITE,
	 MAP_SHARED, ctx->fd_fb, 0);

   if (ctx->framebuffer_addr == MAP_FAILED)
   {
      close(ctx->fd_fb);
      close(ctx->fd_disp);
      goto error;
   }

   /* Get the id of the screen layer */
   if (ioctl(ctx->fd_fb,
            ctx->fb_id == 0 ? FBIOGET_LAYER_HDL_0 : FBIOGET_LAYER_HDL_1,
            &ctx->gfx_layer_id))
   {
      close(ctx->fd_fb);
      close(ctx->fd_disp);
      goto error;
   }

   if (sunxi_layer_reserve(ctx) < 0)
   {
      close(ctx->fd_fb);
      close(ctx->fd_disp);
      goto error;
   }

   return ctx;

error:
   if (ctx)
      free(ctx);
   return NULL;
}
Exemple #2
0
rpi_disp_t *rpi_disp_init(const char *device, void *xserver_fbmem)
{
    rpi_disp_t *ctx = calloc(sizeof(rpi_disp_t), 1);
    struct fb_var_screeninfo fb_var;
    struct fb_fix_screeninfo fb_fix;

    int tmp, version;
    int gfx_layer_size;
    int ovl_layer_size;

    /* use /dev/fb0 by default */
    if (!device)
        device = "/dev/fb0";

    if (strcmp(device, "/dev/fb0") == 0) {
        ctx->fb_id = 0;
    }
    else if (strcmp(device, "/dev/fb1") == 0) {
        ctx->fb_id = 1;
    }
    else
    {
        free(ctx);
        return NULL;
    }

    /* store the already existing mapping done by xserver */
    ctx->xserver_fbmem = xserver_fbmem;

#if 0
    ctx->fd_disp = open("/dev/disp", O_RDWR);

    /* maybe it's even not a sunxi hardware */
    if (ctx->fd_disp < 0) {
        free(ctx);
        return NULL;
    }

    /* version check */
    tmp = SUNXI_DISP_VERSION;
    version = ioctl(ctx->fd_disp, DISP_CMD_VERSION, &tmp);
    if (version < 0) {
        close(ctx->fd_disp);
        free(ctx);
        return NULL;
    }
#endif

    ctx->fd_fb = open(device, O_RDWR);
    if (ctx->fd_fb < 0) {
        close(ctx->fd_disp);
        free(ctx);
        return NULL;
    }

    if (ioctl(ctx->fd_fb, FBIOGET_VSCREENINFO, &fb_var) < 0 ||
        ioctl(ctx->fd_fb, FBIOGET_FSCREENINFO, &fb_fix) < 0)
    {
        close(ctx->fd_fb);
        close(ctx->fd_disp);
        free(ctx);
        return NULL;
    }

    ctx->xres = fb_var.xres;
    ctx->yres = fb_var.yres;
    ctx->bits_per_pixel = fb_var.bits_per_pixel;
    ctx->framebuffer_paddr = fb_fix.smem_start;
    ctx->framebuffer_size = fb_fix.smem_len;
    ctx->framebuffer_height = ctx->framebuffer_size /
                              (ctx->xres * ctx->bits_per_pixel / 8);
    ctx->gfx_layer_size = ctx->xres * ctx->yres * fb_var.bits_per_pixel / 8;

    if (ctx->framebuffer_size < ctx->gfx_layer_size) {
        close(ctx->fd_fb);
        close(ctx->fd_disp);
        free(ctx);
        return NULL;
    }

    if (ctx->xserver_fbmem) {
        /* use already existing mapping */
        ctx->framebuffer_addr = ctx->xserver_fbmem;
    }
    else {
        /* mmap framebuffer memory */
        ctx->framebuffer_addr = (uint8_t *)mmap(0, ctx->framebuffer_size,
                                                PROT_READ | PROT_WRITE,
                                                MAP_SHARED, ctx->fd_fb, 0);
        if (ctx->framebuffer_addr == MAP_FAILED) {
            close(ctx->fd_fb);
            close(ctx->fd_disp);
            free(ctx);
            return NULL;
        }
    }

    ctx->cursor_enabled = 0;
    ctx->cursor_x = -1;
    ctx->cursor_y = -1;

#if 0
    if (sunxi_layer_reserve(ctx) < 0)
    {
        close(ctx->fd_fb);
        close(ctx->fd_disp);
        free(ctx);
        return NULL;
    }

    ctx->fd_g2d = open("/dev/g2d", O_RDWR);
#endif

    ctx->blt2d.self = ctx;
    ctx->blt2d.overlapped_blt = rpi_blt;
    ctx->blt2d.standard_blt = NULL;
    ctx->blt2d.fill = rpi_fill;

    return ctx;
}