PDA

View Full Version : Write to Framebuffer directly



mnarkhede
03-07-2008, 12:05 AM
My application needs to draw some primitives using OpenGL and some primitive directly writing to frame buffer on MX31.

Is it possible to write Frame buffer directly while using OpenGl? If yes,
please tell me how to do.

Thanks,
Manohar.

muratmat
03-08-2008, 05:22 AM
My application needs to draw some primitives using OpenGL and some primitive directly writing to frame buffer on MX31.

Is it possible to write Frame buffer directly while using OpenGl? If yes,
please tell me how to do.

Thanks,
Manohar.

You can access to framebuffer doing as follow (standard Linux method):



#include <linux/kd.h>
#include <linux/vt.h>
#include <linux/fb.h>
#include <linux/input.h>
#include <sys/user.h>

#ifndef PAGE_SHIFT
#define PAGE_SHIFT 12
#endif
#ifndef PAGE_SIZE
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#endif
#ifndef PAGE_MASK
#define PAGE_MASK (~(PAGE_SIZE - 1))
#endif

int fb;
struct fb_var_screeninfo fb_var;
struct fb_var_screeninfo fb_screen;
struct fb_fix_screeninfo fb_fix;
unsigned char *fb_mem = NULL;
unsigned char *fb_screenMem = NULL;

int fb_init(char *device) {

int fb_mem_offset;

// get current settings (which we have to restore)
if (-1 == (fb = open(device, O_RDWR))) {
fprintf(stderr, "Open %s: %s.\n", device, strerror(errno));
return 0;
}
if (-1 == ioctl(fb, FBIOGET_VSCREENINFO, &fb_var)) {
fprintf(stderr, "Ioctl FBIOGET_VSCREENINFO error.\n");
return 0;
}
if (-1 == ioctl(fb, FBIOGET_FSCREENINFO, &fb_fix)) {
fprintf(stderr, "Ioctl FBIOGET_FSCREENINFO error.\n");
return 0;
}
if (fb_fix.type != FB_TYPE_PACKED_PIXELS) {
fprintf(stderr, "Can handle only packed pixel frame buffers.\n");
goto err;
}

fb_mem_offset = (unsigned long)(fb_fix.smem_start) & (~PAGE_MASK);
fb_mem = mmap(NULL, fb_fix.smem_len + fb_mem_offset, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0);
if (-1L == (long)fb_mem) {
fprintf(stderr, "Mmap error.\n");
goto err;
}
// move viewport to upper left corner
if (fb_var.xoffset != 0 || fb_var.yoffset != 0) {
fb_var.xoffset = 0;
fb_var.yoffset = 0;
if (-1 == ioctl(fb, FBIOPAN_DISPLAY, &fb_var)) {
fprintf(stderr, "Ioctl FBIOPAN_DISPLAY error.\n");
munmap(fb_mem, fb_fix.smem_len);
goto err;
}
}

fb_screen = fb_var;
fb_screen.xoffset = 0;
fb_screen.yoffset = fb_var.yres - 1;
if (-1 == ioctl(fb, FBIOPAN_DISPLAY, &fb_screen)) {
fprintf(stderr, "Ioctl FBIOPAN_DISPLAY error.\n");
munmap(fb_mem, fb_fix.smem_len);
goto err;
}

fb_screenMem = fb_mem + fb_mem_offset + (fb_var.yres * fb_var.xres * (fb_var.bits_per_pixel / 8));
return 1;

err:
if (-1 == ioctl(fb, FBIOPUT_VSCREENINFO, &fb_var))
fprintf(stderr, "Ioctl FBIOPUT_VSCREENINFO error.\n");
if (-1 == ioctl(fb, FBIOGET_FSCREENINFO, &fb_fix))
fprintf(stderr, "Ioctl FBIOGET_FSCREENINFO.\n");
return 0;
}

void fb_cleanup(void) {

if (-1 == ioctl(fb, FBIOPUT_VSCREENINFO, &fb_var))
fprintf(stderr, "Ioctl FBIOPUT_VSCREENINFO error.\n");
if (-1 == ioctl(fb, FBIOGET_FSCREENINFO, &fb_fix))
fprintf(stderr, "Ioctl FBIOGET_FSCREENINFO.\n");
munmap(fb_mem, fb_fix.smem_len);
close(fb);
}

void main(void) {

if (!fb_init("/dev/fb0"))
exit(1);

<now you can write directly to fb_screenMem>

fb_cleanup();
}


Under Winodws CE, please have a look at the following article: http://www.codeproject.com/KB/mobile/Caleidoscope.aspx

Cheers!

gthm159
04-11-2008, 07:44 AM
Hi muratmat,

I tried the code you gave above, but the ioctl for FBIOPAN_DISPLAY fails in the following section of code:


fb_screen = fb_var;
fb_screen.xoffset = 0;
fb_screen.yoffset = fb_var.yres - 1;
if (-1 == ioctl(fb, FBIOPAN_DISPLAY, &fb_screen)) {
fprintf(stderr, "Ioctl FBIOPAN_DISPLAY error.\n");
munmap(fb_mem, fb_fix.smem_len);
goto err;
}


Do you know what may be the reason?

Also, in the portion "<now you can write directly to fb_screenMem>", I used the following:


unsigned short int arr[1843200]; // 1843200 = 320 * 240 * 24
memset(arr, 0, sizeof(arr));
memcpy(fb_screenMem, arr, sizeof(arr));


Will this display an all black screen?

I'll post the details of my framebuffer in the next post.

Thanks,
G

gthm159
04-11-2008, 07:46 AM
The details of my framebuffer are as follows:


Info from 'fb_var_screeninfo':
xres = 240
yres = 320
xres_virtual = 240
yres_virtual = 320
xoffset = 0
yoffset = 0
bits_per_pixel = 24
grayscale = 0
red:
offset = 12
length = 6
msb_right = 0
green:
offset = 6
length = 6
msb_right = 0
blue:
offset = 0
length = 6
msb_right = 0
transp:
offset = 18
length = 6
msb_right = 0
nonstd = 0
activate = 0
height = 0
width = 0
accel_flags = 0

Info from 'fb_fix_screeninfo':
id = Virtual FB
smem_start = 0x10002000
smem_len = 230400
type = 0
type_aux = 0
visual = 2
xpanstep = 1
ypanstep = 1
ywrapstep = 1
line_length = 720
mmio_start = 0x0
mmio_len = 0
accel = 0


Thanks,
G

gthm159
05-12-2008, 06:59 AM
Hi All,

Looking at my earlier post listing my framebuffer details, is it possible to find out what my framebuffer configuration is?

i.e. which of the following image formats would be best displayed on it (code taken from openvg.h):

typedef enum {
/* RGB{A,X} channel ordering */
VG_sRGBX_8888 = 0,
VG_sRGBA_8888 = 1,
VG_sRGBA_8888_PRE = 2,
VG_sRGB_565 = 3,
VG_sRGBA_5551 = 4,
VG_sRGBA_4444 = 5,
VG_sL_8 = 6,
VG_lRGBX_8888 = 7,
VG_lRGBA_8888 = 8,
VG_lRGBA_8888_PRE = 9,
VG_lL_8 = 10,
VG_A_8 = 11,
VG_BW_1 = 12,

/* {A,X}RGB channel ordering */
VG_sXRGB_8888 = 0 | (1 << 6),
VG_sARGB_8888 = 1 | (1 << 6),
VG_sARGB_8888_PRE = 2 | (1 << 6),
VG_sARGB_1555 = 4 | (1 << 6),
VG_sARGB_4444 = 5 | (1 << 6),
VG_lXRGB_8888 = 7 | (1 << 6),
VG_lARGB_8888 = 8 | (1 << 6),
VG_lARGB_8888_PRE = 9 | (1 << 6),

/* BGR{A,X} channel ordering */
VG_sBGRX_8888 = 0 | (1 << 7),
VG_sBGRA_8888 = 1 | (1 << 7),
VG_sBGRA_8888_PRE = 2 | (1 << 7),
VG_sBGR_565 = 3 | (1 << 7),
VG_sBGRA_5551 = 4 | (1 << 7),
VG_sBGRA_4444 = 5 | (1 << 7),
VG_lBGRX_8888 = 7 | (1 << 7),
VG_lBGRA_8888 = 8 | (1 << 7),
VG_lBGRA_8888_PRE = 9 | (1 << 7),

/* {A,X}BGR channel ordering */
VG_sXBGR_8888 = 0 | (1 << 6) | (1 << 7),
VG_sABGR_8888 = 1 | (1 << 6) | (1 << 7),
VG_sABGR_8888_PRE = 2 | (1 << 6) | (1 << 7),
VG_sABGR_1555 = 4 | (1 << 6) | (1 << 7),
VG_sABGR_4444 = 5 | (1 << 6) | (1 << 7),
VG_lXBGR_8888 = 7 | (1 << 6) | (1 << 7),
VG_lABGR_8888 = 8 | (1 << 6) | (1 << 7),
VG_lABGR_8888_PRE = 9 | (1 << 6) | (1 << 7)
} VGImageFormat;

Thanks,
Gautam