linux Framebuffer读写
framebuffer模板类
framebuffer类
获取linux Framebuffer信息的类
在公司做一个项目的时候,需要读写Framebuffer,多种色深,这个是直接在linux系统直接操作framebuffer的类,可显示引用的时候设定色深
#ifndef SNAPFRAMEBUFFER_H
#define SNAPFRAMEBUFFER_H
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include "unistd.h"
//lin dbg
//#define Lin_Dbg
#ifdef Lin_Dbg
#define PDBG(fmt, args...) printf(fmt, ## args)
#else
#define PDBG(fmt, args...) /* empty debug slot */
#endif
template <class T>
class SnapFrameBuffer
{
public:
SnapFrameBuffer(const char* devPath);
~SnapFrameBuffer();
public:
T *fbDataPointer;
void* fb_get_raw_data();
void* fb_get_raw_data_rect(int x, int y, int w, int h);
public:
SnapFrameBuffer *instance();//return the instance;
void *fb_mmap(int fb_dev);
void fbSetPoint(int x, int y, T color);
T fbGetPoint(int x, int y);
int fbWidth;
int fbHeight;
int location;
unsigned long long fbScreenSize;
int fbDev;
const char *fbPath;
private:
int GetFrameBufferInfo();
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
static SnapFrameBuffer *self; // sigleton
};
template <class T>
SnapFrameBuffer<T> *SnapFrameBuffer<T>::self = NULL;
template <class T>
SnapFrameBuffer<T>::SnapFrameBuffer(const char* devPath) :
fbScreenSize(0),
fbWidth(0),
fbHeight(0),
fbPath(NULL),
fbDataPointer(NULL)
{
if(self)//sigletion
{
return;
}
self = this;
PDBG("step0 : devPath:%s\n",devPath);
fbPath = devPath;//store dev path
if(fbPath == NULL){
PDBG("Error: framebuffer device path error\n");
return ;
}
PDBG("step1 : open fbdev\n",devPath);
fbDev = open (devPath,O_RDWR);
if(fbDev < 0){
PDBG("Error: Can not open framebuffer device\n");
return ;
}
PDBG("success: fbdev:%d\n", fbDev);
if(GetFrameBufferInfo()<0){
PDBG("Error: Get Info failed!");
}
PDBG("step2 : After GetInof, begin mmap!\n");
fbDataPointer = (T *)fb_mmap(fbDev);
if(fbDataPointer <= 0){
PDBG("Error: fbDataPointer:%p\n", fbDataPointer);
return ;
}
PDBG("success?? fbDataPointer:%p\n", fbDataPointer);
}
template <class T>
/**
* @brief SnapFrameBuffer<T>::~SnapFrameBuffer
*/
SnapFrameBuffer<T>::~SnapFrameBuffer()
{
munmap(fbDataPointer, fbScreenSize);
close(fbDev);
}
template <class T>
/**
* @brief SnapFrameBuffer::fb_get_raw_data, get the display raw data;
* @param fb_dev,linux framebuffer device id;
* @return framebuffer raw pointer;
*/
void *SnapFrameBuffer<T>::fb_get_raw_data()
{
//T *dst = (T*)malloc(fbScreenSize);
//memcpy(dst, fbDataPointer, fbScreenSize);
return (void *)fbDataPointer;
}
template <class T>
/**
* @brief SnapFrameBuffer::fb_get_raw_data_rect
* @param x, region top left coordinate x;
* @param y, region top left coordinate y;
* @param w, the width of region;
* @param h, the heigh of region;
* @return a pointer of the data fo region;
*/
void *SnapFrameBuffer<T>::fb_get_raw_data_rect(int x, int y, int w, int h)
{
void * pRecRawData;
if((x+w) > vinfo.xres || (y+h)>vinfo.yres){
PDBG("ivalide range!\n");
return NULL;
}else{
pRecRawData = malloc(w*h*sizeof(T));
for(int hCnt=0; hCnt<h; hCnt++){
memcpy(pRecRawData, fbDataPointer+((y+hCnt)*vinfo.xres + x), w*sizeof(T));
}
return pRecRawData;
}
}
template <class T>
/**
* @brief SnapFrameBuffer::instance, return the instance of the class;
* @return
*/
SnapFrameBuffer<T> *SnapFrameBuffer<T>::instance()
{
return self;
}
template <class T>
/**
* @brief SnapFrameBuffer<T>::fb_mmap
* @param fb_dev, file id
* @param display_width
* @param display_height
* @return
*/
void *SnapFrameBuffer<T>::fb_mmap(int fb_dev)
{
PDBG("mmap size: %d, fb_dev:%d\n", vinfo.xres * vinfo.yres * vinfo.bits_per_pixel/8, fb_dev);
return mmap(0, vinfo.xres * vinfo.yres * vinfo.bits_per_pixel/8, PROT_READ|PROT_WRITE, MAP_SHARED, fb_dev, 0);
}
template <class T>
/**
* @brief SnapFrameBuffer<T>::fbSetPoint
* @param x
* @param y
* @param color
*/
void SnapFrameBuffer<T>::fbSetPoint(int x, int y, T color)
{
location = x + y * vinfo.xres;
PDBG("step4: localtion:%d, fbDataPointer:%p!\n", location, fbDataPointer);
*(location + fbDataPointer) = color;
}
template <class T>
T SnapFrameBuffer<T>::fbGetPoint(int x, int y)
{
location = x + y * vinfo.xres;
return *(fbDataPointer + location);
}
//获取linux Framebuffer信息,linuxframebuffer信息打印framebuffer信息
template <class T>
int SnapFrameBuffer<T>::GetFrameBufferInfo()
{
if (ioctl(fbDev,FBIOGET_FSCREENINFO,&finfo)){
PDBG("Error reading fixed information\n");
return -1;
}
if (ioctl(fbDev,FBIOGET_VSCREENINFO,&vinfo)){
PDBG("Error reading variable information\n");
return -2;
}
PDBG("xres %d\n",vinfo.xres);//可见解析度 320
PDBG("yres %d\n",vinfo.yres);// 240
PDBG("xres_virturl %d\n",vinfo.xres_virtual);//虚拟解析度 320
PDBG("yres_virtual %d\n",vinfo.yres_virtual);// 240
PDBG("xoffset %d\n",vinfo.xoffset);//虚拟到可见的偏移 0
PDBG("yoffset %d\n",vinfo.yoffset);// 0
PDBG("bits_per_pixel %d\n",vinfo.bits_per_pixel);//每像素位数 bpp 16
PDBG("grayscale %d\n",vinfo.grayscale);//非零时,指灰度
PDBG("fb_bitfield red.offset %d\n",vinfo.red.offset);// 11 偏移11位
PDBG("fb_bitfield red.length %d\n",vinfo.red.length);// 5
PDBG("fb_bitfield red.msb_right %d\n",vinfo.red.msb_right);// 0
PDBG("fb_bitfield green.offset %d\n",vinfo.green.offset);// 5 偏移5位
PDBG("fb_bitfield green.length %d\n",vinfo.green.length);// 6
PDBG("fb_bitfield green.msb_right %d\n",vinfo.green.msb_right);// 0
PDBG("fb_bitfield blue.offset %d\n",vinfo.blue.offset);//
PDBG("fb_bitfield blue.length %d\n",vinfo.blue.length);//
PDBG("fb_bitfield blue.msb_right %d\n",vinfo.blue.msb_right);//
PDBG("fb_bitfield transp.offset %d\n",vinfo.transp.offset);//
PDBG("fb_bitfield transp.length %d\n",vinfo.transp.length);//
PDBG("fb_bitfield transp.msb_right %d\n",vinfo.transp.msb_right);//
PDBG("nonstd %d\n",vinfo.nonstd);//!=0 非标准像素格式
PDBG("activate %d\n",vinfo.activate);
PDBG("height %d\n",vinfo.height);//高度/ 240
PDBG("widht %d\n",vinfo.width);// 320
PDBG("accel_flags %d\n",vinfo.accel_flags);//看 fb_info.flags
//定时,除了 pixclock之外,其他的都以像素时钟为单位
PDBG("pixclock %d\n",vinfo.pixclock);//像素时钟,皮秒 80000
PDBG("left_margin %d\n",vinfo.left_margin);//行切换:从同步到绘图之间的延迟 28
PDBG("right_margin %d\n",vinfo.right_margin);//行切换:从绘图到同步之间的延迟 24
PDBG("upper_margin %d\n",vinfo.upper_margin);//帧切换:从同步到绘图之间的延迟 6
PDBG("lower_margin %d\n",vinfo.lower_margin);//帧切换:从绘图到同步之间的延迟 2
PDBG("width %d\n",vinfo.width);
PDBG("height %d\n",vinfo.height);
PDBG("hsync_len %d\n",vinfo.hsync_len); //hor 水平同步的长度 42
PDBG("vsync_len %d\n",vinfo.vsync_len); //vir 垂直同步的长度 12
PDBG("sync %d\n",vinfo.sync); //
PDBG("vmode %d\n",vinfo.vmode);
PDBG("rotate %d\n",vinfo.rotate);
PDBG("id %s\n",finfo.id);//id
PDBG("smem_start %lu\n",finfo.smem_start); //帧缓冲 内存开始地址,物理地址
PDBG("smem_len %d\n",finfo.smem_len); // 帧缓冲 内存 长度
PDBG("type %d\n",finfo.type);
PDBG("type_aux %d\n",finfo.type_aux);//平面交织交替
PDBG("visual %d\n",finfo.visual); //记录 色彩模式 2
PDBG("xpanstep %d\n",finfo.xpanstep);//如果没有硬件panning,赋0
PDBG("ypanstep %d\n",finfo.ypanstep);//
PDBG("line_length %d\n",finfo.line_length);//line hength;
PDBG("mmio_start %lu\n",finfo.mmio_start);//内存映射IO开始地址 物理地址
PDBG("mmio_len %d\n",finfo.mmio_len);//内存映射IO 长度
PDBG("accel %d\n\n",finfo.accel);
fbWidth = vinfo.xres;
fbHeight = vinfo.yres;
fbScreenSize = vinfo.yres*vinfo.xres*vinfo.bits_per_pixel/8;
return 0;
}
#endif // SNAPFRAMEBUFFER_H
经过实践,亲测实测可用,但是结构有待整理。可以从framebuffer中取得原始数据保存成bmp图片