implement K4 framebuffer support with shadow blitbuffer

previous implementation make fb.bb has double pitch
compared to other blitbuffer, which leads to segfault
on blitFullFrom method.
pull/2/merge
Qingping Hou 12 years ago
parent 5d8e579b4f
commit 47ec493da1

@ -92,7 +92,7 @@ static int blitFullToBuffer(lua_State *L) {
BlitBuffer *dst = (BlitBuffer*) luaL_checkudata(L, 1, "blitbuffer");
BlitBuffer *src = (BlitBuffer*) luaL_checkudata(L, 2, "blitbuffer");
if(src->w != dst->w || src->h != dst->h) {
if(src->w != dst->w || src->h != dst->h || src->pitch != dst->pitch) {
return luaL_error(L, "blitbuffer size must be framebuffer size!");
}

@ -26,6 +26,7 @@
static int openFrameBuffer(lua_State *L) {
const char *fb_device = luaL_checkstring(L, 1);
FBInfo *fb = (FBInfo*) lua_newuserdata(L, sizeof(FBInfo));
uint8_t *fb_map_address = NULL;
luaL_getmetatable(L, "einkfb");
@ -73,13 +74,38 @@ static int openFrameBuffer(lua_State *L) {
}
/* mmap the framebuffer */
fb->buf->data = mmap(0, fb->finfo.smem_len,
fb->buf->pitch = fb->finfo.line_length;
fb_map_address = mmap(0, fb->finfo.smem_len,
PROT_READ | PROT_WRITE, MAP_SHARED, fb->fd, 0);
if(fb->buf->data == MAP_FAILED) {
return luaL_error(L, "cannot mmap framebuffer");
}
memset(fb->buf->data, 0, fb->finfo.smem_len);
fb->buf->pitch = fb->finfo.line_length;
if (fb->vinfo.bits_per_pixel != 4) {
/* for 8bpp K4, we create a shadow 4bpp blitbuffer
* K4 uses 16 scale 8bpp framebuffer, so we still cheat it as 4bpp */
fb->buf->pitch = fb->buf->pitch / 2;
fb->buf->data = malloc(fb->buf->pitch * fb->vinfo.yres);
if (!fb->buf->data) {
return luaL_error(L, "failed to allocate memory for framebuffer's shadow blitbuffer!");
}
fb->buf->allocated = 1;
fb->real_buf = (BlitBuffer *)malloc(sizeof(BlitBuffer));
if (!fb->buf->data) {
return luaL_error(L, "failed to allocate memory for framebuffer's blitbuffer!");
}
fb->real_buf->pitch = fb->finfo.line_length;
fb->real_buf->w = fb->vinfo.xres;
fb->real_buf->h = fb->vinfo.yres;
fb->real_buf->allocated = 0;
fb->real_buf->data = fb_map_address;
} else {
/* for K2, K3 and DXG, we map framebuffer to fb->buf->data directly */
fb->real_buf = NULL;
fb->buf->data = fb_map_address;
}
memset(fb->buf->data, 0, fb->buf->pitch * fb->buf->h);
#else
if(SDL_Init(SDL_INIT_VIDEO) < 0) {
return luaL_error(L, "cannot initialize SDL.");
@ -118,6 +144,9 @@ static int closeFrameBuffer(lua_State *L) {
close(fb->fd);
#else
free(fb->buf->data);
if (fb->vinfo.bits_per_pixel != 4) {
free(fb->real_buf->data);
}
#endif
fb->buf->data = NULL;
// the blitbuffer in fb->buf should be freed
@ -133,24 +162,25 @@ static int einkUpdate(lua_State *L) {
// for Kindle e-ink display
int fxtype = luaL_optint(L, 2, 0);
#ifndef EMULATE_READER
int i = 0, j = 0, h = 0, w = 0;
int i = 0, j = 0, h = 0, w = 0, pitch = 0;
uint8_t *fb_buf = NULL;
/* dulplicate 4bpp to 8bpp */
/* copy bitmap from 4bpp shadow blitbuffer to framebuffer */
if (fb->vinfo.bits_per_pixel != 4) {
fb_buf = fb->buf->data;
h = fb->buf->h;
w = fb->buf->w;
pitch = fb->buf->pitch;
for (i = (h-1); i > 0; i--) {
for (j = (w-1)/2; j > 0; j--) {
fb_buf[i*w + j*2] = fb_buf[i*w + j];
fb_buf[i*w + j*2] &= 0xF0;
fb_buf[i*w + j*2] |= fb_buf[i*w + j*2]>>4 & 0x0F;
fb->real_buf->data[i*w + j*2] = fb_buf[i*pitch + j];
fb->real_buf->data[i*w + j*2] &= 0xF0;
fb->real_buf->data[i*w + j*2] |= fb_buf[i*pitch + j]>>4 & 0x0F;
fb_buf[i*w + j*2 + 1] = fb_buf[i*w + j];
fb_buf[i*w + j*2 + 1] &= 0x0F;
fb_buf[i*w + j*2 + 1] |= fb_buf[i*w + j*2 + 1]<<4 & 0xF0;
fb->real_buf->data[i*w + j*2 + 1] = fb_buf[i*pitch + j];
fb->real_buf->data[i*w + j*2 + 1] &= 0x0F;
fb->real_buf->data[i*w + j*2 + 1] |= fb_buf[i*pitch + j]<<4 & 0xF0;
}
}
}
@ -163,15 +193,6 @@ static int einkUpdate(lua_State *L) {
myarea.buffer = NULL;
myarea.which_fx = fxtype ? fx_update_partial : fx_update_full;
ioctl(fb->fd, FBIO_EINK_UPDATE_DISPLAY_AREA, &myarea);
/* revert 8bpp to 4bpp */
if (fb->vinfo.bits_per_pixel != 4) {
for (i = 0; i < h; i++) {
for (j = 0; j < w/2; j++) {
fb_buf[i*w + j] = (fb_buf[i*w + j*2] & 0xF0) | (fb_buf[i*w + j*2 + 1] & 0x0F);
}
}
}
#else
// for now, we only do fullscreen blits in emulation mode
if (fxtype == 0) {

@ -38,6 +38,7 @@ struct fb_var_screeninfo {
typedef struct FBInfo {
int fd;
BlitBuffer *buf;
BlitBuffer *real_buf;
#ifdef EMULATE_READER
SDL_Surface *screen;
#else

Loading…
Cancel
Save