Write to Framebuffer directly

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.
", device, strerror(errno));
		return 0;
	}
	if (-1 == ioctl(fb, FBIOGET_VSCREENINFO, &fb_var)) {
		fprintf(stderr, "Ioctl FBIOGET_VSCREENINFO error.
");
		return 0;
	}
	if (-1 == ioctl(fb, FBIOGET_FSCREENINFO, &fb_fix)) {
		fprintf(stderr, "Ioctl FBIOGET_FSCREENINFO error.
");
		return 0;
	}
	if (fb_fix.type != FB_TYPE_PACKED_PIXELS) {
		fprintf(stderr, "Can handle only packed pixel frame buffers.
");
		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.
");
		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.
");
			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.
");
		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.
");
	if (-1 == ioctl(fb, FBIOGET_FSCREENINFO, &fb_fix))
		fprintf(stderr, "Ioctl FBIOGET_FSCREENINFO.
");
	return 0;
}

void fb_cleanup(void) {

	if (-1 == ioctl(fb, FBIOPUT_VSCREENINFO, &fb_var))
		fprintf(stderr, "Ioctl FBIOPUT_VSCREENINFO error.
");
	if (-1 == ioctl(fb, FBIOGET_FSCREENINFO, &fb_fix))
		fprintf(stderr, "Ioctl FBIOGET_FSCREENINFO.
");
	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!

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.
");
      munmap(fb_mem, fb_fix.smem_len);
      goto err;
   }

Do you know what may be the reason?

Also, in the portion “”, 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

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

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