1. framebuffer
Framebuffer(帧缓冲区)是用于存储图像数据的一块内存区域。我们可以将我们想要显示的图像数据写到framebuffer中,驱动程序每隔一段时间会自动的去读取Framebuffer中的图像数据,并根据读取到的图像数据在屏幕上显示对应的图像。
2. 颜色的表示
我们知道一幅图像其实是由一个一个的像素点组成的,诸多的不同颜色的像素最终组成了一幅图像,因此上面提到的图像数据指的就是这一幅图像中每个像素点的颜色数据。
在美术中,将红绿蓝三种颜色称为三原色,通过将不同亮度的三元色进行组合,就可以调配出任何一种颜色。在计算机中颜色数据的表示同样利用了这个原理。在计算机中,颜色通常用 RGB(红绿蓝)模型来表示。RGB 模型将颜色描述为三个分量的组合,即红色、绿色和蓝色分量的亮度值。而根据每个分量所占的位数不同,又产生了三种不同的颜色格式,分别为:RGB888 、RGB565、RGB555。
RGB888:
RGB888 格式使用 24 位来表示一个像素的颜色信息,其中 8 位用于红色通道、8 位用于绿色通道、8 位用于蓝色通道。这意味着每个颜色通道可以有 256(2^8)种不同的亮度级别,共同组合形成一个广泛的颜色范围。
RGB565:
RGB565 格式使用 16 位来表示一个像素的颜色信息,其中 5 位用于红色通道、6 位用于绿色通道、5 位用于蓝色通道。这种格式相比 RGB888 来说更加节省存储空间,但同时牺牲了一定的颜色精度。
RGB555:
RGB555 格式也使用 16 位来表示一个像素的颜色信息,其中 5 位用于红色通道、5 位用于绿色通道、5 位用于蓝色通道。与 RGB565 相比,RGB555 在绿色通道上减少了一位,因此在绿色调性上可能会略显不足,但整体颜色表现仍比较均衡。
第(x,y)个像素点地址为 :y*(屏幕x轴最大宽度)+ x
FrameBuffer 开发流程:
1.打开设备(/dev/fd0)
2.获取显示设备相关参数(分辨率,位深度)
3.建立内存映射(映射物理显存到用户虚拟内存空间)
4.写入RGB颜色值
5.解除显存映射
6.关闭设备
void *pmem;
struct fb_var_screeninfo vinf;int init_fb(char *devname)
{//1. 打开显示设备int fd = open(devname, O_RDWR); if (-1 == fd){perror("fail open fb");return -1;}//2、获取显示设备相关参数 分辨率 位深度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;//3, 建立显存和用户空间的映射关系pmem = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);if ((void *)-1 == pmem){perror("fail mmap");return -1;}return fd;
}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 ;
}void uninit_fb(int fd)
{size_t len = vinf.xres_virtual * vinf.yres_virtual * vinf.bits_per_pixel/8;munmap(pmem, len);close(fd);
}