framebuffer帧缓存

framebuffer:帧缓冲,帧缓存

Linux内核为显示提供的一套应用程序接口。(驱动内核支持)

framebuffer本质上是一块显示缓存,往显示缓存中写入特定格式的数据就意味着向屏幕输出内容。framebuffer驱动程序控制LCD显示设备,通过映射framebuffer设备到用户空间,应用程序可以直接对显存进行操作,从而控制LCD显示内容

framebuffer使用

显示屏:800*600(横向有800个像素点,纵向有600个像素点)

显卡(显存(保存像素点的值))

RGB

888(R,G,B各占八个比特)

PC,4412:RGB888

S3C2440:RGB565

显存空间不允许用户直接访问

所以可以采用内存映射,将用户空间与显存空间建立起一一对应的关系

根据显存的大小的多少,来申请空间

1.打开显示设备(/dev/fb0)

2.获取显示设备相关参数(分辨率、位深度)

3.建立内存映射

4.写入RGB颜色值

5.解除映射

6.关闭显示设备

和硬件有关的接口都只能用open打开

获取显示设备相关文件

/usr/include/linux/fb.h

偏移量:从什么位置开始映射

framebuffer使用:

1.获取显示设备相关参数

cs 复制代码
int init_fb(char *devname)
{
	int fd = open(devname, O_RDWR);	
	if (-1 == fd)
	{
		perror("fail open fb");
		return -1;
	}
	
	int ret = ioctl(fd, FBIOGET_VSCREENINFO, &vinf);
	if (-1 ==ret)
	{
		perror("fail ioctl");
		return -1;
	}
	
	printf("xres = %d, yres = %d\n", vinf.xres, vinf.yres);
	printf("xres_virtual = %d, yres_virtual = %d\n", vinf.xres_virtual, vinf.yres_virtual);
	printf("bits_per_pixel : %d\n", vinf.bits_per_pixel);

	size_t len = vinf.xres_virtual * vinf.yres_virtual * vinf.bits_per_pixel/8;
	pmem = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
	if ((void *)-1 == pmem)
	{
		perror("fail mmap");
		return -1;
	}
	

	return fd;
}

2.画点

cs 复制代码
void draw_point(int x, int y, unsigned int col)
{
	if (x >= vinf.xres || y >= vinf.yres)
	{
		return ;
	}
	if (vinf.bits_per_pixel == RGB888_FMT)
	{
		unsigned int *p = pmem;
		*(p + y * vinf.xres_virtual + x) = col;
	}
	else if (vinf.bits_per_pixel == RGB565_FMT)
	{
		unsigned short *p  = pmem;	
		*(p + y * vinf.xres_virtual + x) = col;
	}
	return ;
}

3.清屏

cs 复制代码
void screen_clear(int color)
{
    int i = 0;
    int j = 0;
    for(i = 0;i < vinf.xres;++i)
    {
        for(j = 0;j < vinf.yres;++j)
        {
            draw_point(i,j,color);
        }
    }
}

4.划线

cs 复制代码
void draw_line(int x1,int x2,int y1,int y2,int color)
{
    if(x1 > 0 && x1 < vinf.xres_virtual && x2 > 0 && x2 < vinf.xres_virtual && y1 > 0 && y1 < vinf.yres_virtual && y2 > 0 && y2 < vinf.yres_virtual)
    {
        int xmax = x1 > x2 ? x1 : x2;
        int xmin = x1 > x2 ? x2 : x1;
        int x = 0;
        int y = 0;
        if(x1 == x2)
        {
            int ymax = y1 > y2 ? y1 : y2;
            int ymin = y1 > y2 ? y2 : y1;
            for(y = ymin;y < ymax;++y)
            {
                draw_point(x1,y,color);
            }
        }

        for(x = xmin;x < xmax;x++)
        {
            y = (x - x1)*(y2 - y1) / (x1 - x2) + y1;
            draw_point(x,y,color);
        }
    }
}

5.画圆

cs 复制代码
void draw_circle(int a,int b,int r,int color)
{
    int x = 0;
    int y = 0;
    int tmp;
    for(x = a -r;x < a + r;++x)
    {
        tmp = sqrt(r*r - (x-a)*(x-a));
        int ymax = b + tmp;
        int ymin = b - tmp;
        for(y = ymin;y < ymax;++y)
        {
            draw_point(x,y,color);
        }
    }
}
相关推荐
YOU OU9 小时前
Redis基础常识与命令
数据库·redis·缓存
吳所畏惧13 小时前
宝塔面板Redis密码修改指南:SSH命令修改 vs 面板UI界面修改,哪个更靠谱?
运维·服务器·数据库·redis·缓存·ssh
Y38153266219 小时前
SERP API + Redis 缓存层:4 种方案对比与选型
数据库·redis·缓存
海兰21 小时前
【高速缓存】RedisVL 高级查询(全文搜索、混合搜索和 多向量搜索)
数据库·人工智能·redis·缓存
流星白龙1 天前
【Redis】4.基本全局命令
数据库·redis·缓存
流星白龙2 天前
【Redis】3.Redis安装与命令行客户端
数据库·redis·缓存
我不想名字重复2 天前
redis缓存和数据库数据保持一致
数据库·redis·缓存
时空无限2 天前
vllm 大模型启动缓存相关环境变量 export
linux·缓存·vllm
流星白龙2 天前
【Redis】6.计数其他命令
数据库·redis·缓存
正儿八经的少年2 天前
redis 的大 key 和热 key 详解
数据库·redis·缓存