efl/legacy/evas/src/lib/engines/fb/evas_outbuf.c

403 lines
9.9 KiB
C

#include "evas_common.h"
#include "evas_engine.h"
#include <sys/time.h>
#include <sys/utsname.h>
void
evas_fb_outbuf_fb_init(void)
{
}
void
evas_fb_outbuf_fb_free(Outbuf *buf)
{
/* FIXME: impliment */
printf("destroying fb info.. not implemented!!!! WARNING. LEAK!\n");
if (buf->priv.back_buf)
evas_common_image_free(buf->priv.back_buf);
free(buf);
}
Outbuf *
evas_fb_outbuf_fb_setup_fb(int w, int h, int rot, Outbuf_Depth depth, int vt_no, int dev_no, int refresh)
{
/* create outbuf struct */
/* setup window and/or fb */
/* if (dithered) create backbuf */
Outbuf *buf;
int fb_fd = -1;
int fb_depth;
fb_depth = -1;
if (depth == OUTBUF_DEPTH_RGB_16BPP_565_565_DITHERED) fb_depth = 16;
else if (depth == OUTBUF_DEPTH_RGB_16BPP_555_555_DITHERED) fb_depth = 15;
else if (depth == OUTBUF_DEPTH_RGB_16BPP_565_444_DITHERED) fb_depth = 16;
else if (depth == OUTBUF_DEPTH_RGB_16BPP_444_444_DITHERED) fb_depth = 12;
else if (depth == OUTBUF_DEPTH_RGB_32BPP_888_8888) fb_depth = 32;
else if (depth == OUTBUF_DEPTH_INHERIT) fb_depth = 0;
buf = calloc(1, sizeof(Outbuf));
if (!buf)
return NULL;
fb_init(vt_no, dev_no);
if (rot == 0)
buf->priv.fb.fb = fb_setmode(w, h, fb_depth, refresh);
else if (rot == 270)
buf->priv.fb.fb = fb_setmode(h, w, fb_depth, refresh);
else if (rot == 90)
buf->priv.fb.fb = fb_setmode(h, w, fb_depth, refresh);
if (!buf->priv.fb.fb) buf->priv.fb.fb = fb_getmode();
if (!buf->priv.fb.fb)
{
free(buf);
return NULL;
}
fb_fd = fb_postinit(buf->priv.fb.fb);
if (rot == 0)
{
buf->w = buf->priv.fb.fb->width;
buf->h = buf->priv.fb.fb->height;
}
else if (rot == 270)
{
buf->w = buf->priv.fb.fb->height;
buf->h = buf->priv.fb.fb->width;
}
else if (rot == 90)
{
buf->w = buf->priv.fb.fb->height;
buf->h = buf->priv.fb.fb->width;
}
buf->depth = depth;
buf->rot = rot;
{
Gfx_Func_Convert conv_func;
int i;
buf->priv.mask.r = 0;
for (i = 0; i < (int)buf->priv.fb.fb->fb_var.red.length; i++)
buf->priv.mask.r |= (1 << (buf->priv.fb.fb->fb_var.red.offset + i));
buf->priv.mask.g = 0;
for (i = 0; i < (int)buf->priv.fb.fb->fb_var.green.length; i++)
buf->priv.mask.g |= (1 << (buf->priv.fb.fb->fb_var.green.offset + i));
buf->priv.mask.b = 0;
for (i = 0; i < (int)buf->priv.fb.fb->fb_var.blue.length; i++)
buf->priv.mask.b |= (1 << (buf->priv.fb.fb->fb_var.blue.offset + i));
conv_func = NULL;
if (buf->rot == 0)
conv_func = evas_common_convert_func_get(0, buf->w, buf->h,
buf->priv.fb.fb->fb_var.bits_per_pixel,
buf->priv.mask.r,
buf->priv.mask.g,
buf->priv.mask.b,
PAL_MODE_NONE,
buf->rot);
else if (buf->rot == 270)
conv_func = evas_common_convert_func_get(0, buf->h, buf->w,
buf->priv.fb.fb->fb_var.bits_per_pixel,
buf->priv.mask.r,
buf->priv.mask.g,
buf->priv.mask.b,
PAL_MODE_NONE,
buf->rot);
else if (buf->rot == 90)
conv_func = evas_common_convert_func_get(0, buf->h, buf->w,
buf->priv.fb.fb->fb_var.bits_per_pixel,
buf->priv.mask.r,
buf->priv.mask.g,
buf->priv.mask.b,
PAL_MODE_NONE,
buf->rot);
if (!conv_func)
{
free(buf);
return NULL;
}
}
if (buf->priv.fb.fb->fb_var.bits_per_pixel < 24)
buf->priv.back_buf = evas_common_image_create(buf->w, buf->h);
return buf;
}
void
evas_fb_outbuf_fb_blit(Outbuf *buf, int src_x, int src_y, int w, int h, int dst_x, int dst_y)
{
if (buf->priv.back_buf)
{
evas_common_blit_rectangle(buf->priv.back_buf, buf->priv.back_buf,
src_x, src_y, w, h, dst_x, dst_y);
evas_fb_outbuf_fb_update(buf, dst_x, dst_y, w, h);
}
else
{
if (buf->priv.fb.fb)
{
/* FIXME: need to impliment an fb call for "copy area" */
}
}
}
void
evas_fb_outbuf_fb_update(Outbuf *buf, int x, int y, int w, int h)
{
if (!(buf->priv.back_buf)) return;
if (buf->priv.fb.fb)
{
Gfx_Func_Convert conv_func;
DATA8 *data;
data = NULL;
conv_func = NULL;
if (buf->rot == 0)
{
data = (DATA8 *)buf->priv.fb.fb->mem + buf->priv.fb.fb->mem_offset +
buf->priv.fb.fb->bpp *
(x + (y * buf->priv.fb.fb->width));
conv_func = evas_common_convert_func_get(data, w, h, buf->priv.fb.fb->fb_var.bits_per_pixel,
buf->priv.mask.r, buf->priv.mask.g,
buf->priv.mask.b, PAL_MODE_NONE,
buf->rot);
}
else if (buf->rot == 270)
{
data = (DATA8 *)buf->priv.fb.fb->mem + buf->priv.fb.fb->mem_offset +
buf->priv.fb.fb->bpp *
(buf->h - y - h + (x * buf->priv.fb.fb->width));
conv_func = evas_common_convert_func_get(data, h, w, buf->priv.fb.fb->fb_var.bits_per_pixel,
buf->priv.mask.r, buf->priv.mask.g,
buf->priv.mask.b, PAL_MODE_NONE,
buf->rot);
}
else if (buf->rot == 90)
{
data = (DATA8 *)buf->priv.fb.fb->mem + buf->priv.fb.fb->mem_offset +
buf->priv.fb.fb->bpp *
(y + ((buf->w - x - w) * buf->priv.fb.fb->width));
conv_func = evas_common_convert_func_get(data, h, w, buf->priv.fb.fb->fb_var.bits_per_pixel,
buf->priv.mask.r, buf->priv.mask.g,
buf->priv.mask.b, PAL_MODE_NONE,
buf->rot);
}
if (conv_func)
{
DATA32 *src_data;
src_data = buf->priv.back_buf->image->data + (y * buf->w) + x;
if (buf->rot == 0)
{
conv_func(src_data, data,
buf->w - w,
buf->priv.fb.fb->width - w,
w, h,
x, y, NULL);
}
else if (buf->rot == 270)
{
conv_func(src_data, data,
buf->w - w,
buf->priv.fb.fb->width - h,
h, w,
x, y, NULL);
}
else if (buf->rot == 90)
{
conv_func(src_data, data,
buf->w - w,
buf->priv.fb.fb->width - h,
h, w,
x, y, NULL);
}
}
}
}
RGBA_Image *
evas_fb_outbuf_fb_new_region_for_update(Outbuf *buf, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch)
{
if (buf->priv.back_buf)
{
*cx = x; *cy = y; *cw = w; *ch = h;
return buf->priv.back_buf;
}
else
{
RGBA_Image *im;
*cx = 0; *cy = 0; *cw = w; *ch = h;
im = evas_common_image_create(w, h);
return im;
}
return NULL;
}
void
evas_fb_outbuf_fb_free_region_for_update(Outbuf *buf, RGBA_Image *update)
{
if (update != buf->priv.back_buf) evas_common_image_free(update);
}
void
evas_fb_outbuf_fb_push_updated_region(Outbuf *buf, RGBA_Image *update, int x, int y, int w, int h)
{
if (!buf->priv.fb.fb) return;
if (buf->priv.back_buf)
{
if (update != buf->priv.back_buf)
evas_common_blit_rectangle(update, buf->priv.back_buf,
0, 0, w, h, x, y);
evas_fb_outbuf_fb_update(buf, x, y, w, h);
}
else
{
Gfx_Func_Convert conv_func;
DATA8 *data;
data = NULL;
conv_func = NULL;
if (buf->rot == 0)
{
data = (DATA8 *)buf->priv.fb.fb->mem +
buf->priv.fb.fb->mem_offset +
buf->priv.fb.fb->bpp *
(x + (y * buf->priv.fb.fb->width));
conv_func = evas_common_convert_func_get(data, w, h,
buf->priv.fb.fb->fb_var.bits_per_pixel,
buf->priv.mask.r, buf->priv.mask.g,
buf->priv.mask.b, PAL_MODE_NONE,
buf->rot);
}
else if (buf->rot == 270)
{
data = (DATA8 *)buf->priv.fb.fb->mem +
buf->priv.fb.fb->mem_offset +
buf->priv.fb.fb->bpp *
(buf->h - y - h + (x * buf->priv.fb.fb->width));
conv_func = evas_common_convert_func_get(data, h, w,
buf->priv.fb.fb->fb_var.bits_per_pixel,
buf->priv.mask.r, buf->priv.mask.g,
buf->priv.mask.b, PAL_MODE_NONE,
buf->rot);
}
else if (buf->rot == 90)
{
data = (DATA8 *)buf->priv.fb.fb->mem +
buf->priv.fb.fb->mem_offset +
buf->priv.fb.fb->bpp *
(y + ((buf->w - x - w) * buf->priv.fb.fb->width));
conv_func = evas_common_convert_func_get(data, h, w,
buf->priv.fb.fb->fb_var.bits_per_pixel,
buf->priv.mask.r, buf->priv.mask.g,
buf->priv.mask.b, PAL_MODE_NONE,
buf->rot);
}
if (conv_func)
{
DATA32 *src_data;
src_data = update->image->data;
if (buf->rot == 0)
{
conv_func(src_data, data,
0,
buf->priv.fb.fb->width - w,
w, h,
x, y, NULL);
}
else if (buf->rot == 270)
{
conv_func(src_data, data,
0,
buf->priv.fb.fb->width - h,
h, w,
x, y, NULL);
}
else if (buf->rot == 90)
{
conv_func(src_data, data,
0,
buf->priv.fb.fb->width - h,
h, w,
x, y, NULL);
}
}
}
}
void
evas_fb_outbuf_fb_reconfigure(Outbuf *buf, int w, int h, int rot, Outbuf_Depth depth)
{
if ((w == buf->w) && (h == buf->h) &&
(rot == buf->rot) && (depth == buf->depth))
return;
if (buf->priv.back_buf)
{
evas_common_image_free(buf->priv.back_buf);
buf->priv.back_buf = NULL;
}
if (buf->priv.fb.fb)
{
/* FIXME: impliment this */
}
/* if backbuf delet it */
/* resize window or reset fb mode */
/* if (dithered) create new backbuf */
}
int
evas_fb_outbuf_fb_get_width(Outbuf *buf)
{
return buf->w;
}
int
evas_fb_outbuf_fb_get_height(Outbuf *buf)
{
return buf->h;
}
Outbuf_Depth
evas_fb_outbuf_fb_get_depth(Outbuf *buf)
{
return buf->depth;
}
int
evas_fb_outbuf_fb_get_rot(Outbuf *buf)
{
return buf->rot;
}
int
evas_fb_outbuf_fb_get_have_backbuf(Outbuf *buf)
{
if (buf->priv.back_buf) return 1;
return 0;
}
void
evas_fb_outbuf_fb_set_have_backbuf(Outbuf *buf, int have_backbuf)
{
if (buf->priv.back_buf)
{
if (have_backbuf) return;
evas_common_image_free(buf->priv.back_buf);
buf->priv.back_buf = NULL;
}
else
{
if (!have_backbuf) return;
if (buf->priv.fb.fb)
{
if (buf->priv.fb.fb->fb_var.bits_per_pixel < 24)
{
buf->priv.back_buf = evas_common_image_create(buf->w, buf->h);
}
}
}
}