目录
[2.1 基本工作原理](#2.1 基本工作原理)
[2.2 应用编程实例](#2.2 应用编程实例)
[2.3 优缺点](#2.3 优缺点)
[三.X Server架构](#三.X Server架构)
[3.1 基本原理](#3.1 基本原理)
[3.1.1 无GPU的平台](#3.1.1 无GPU的平台)
[3.1.2 有GPU的平台](#3.1.2 有GPU的平台)
[3.2 DDX驱动实例](#3.2 DDX驱动实例)
[3.2.1 无GPU的平台](#3.2.1 无GPU的平台)
[3.2.2 有GPU的平台](#3.2.2 有GPU的平台)
[3.3 优缺点](#3.3 优缺点)
一.显示架构演进历程
Linux显示架构大致经历了以下几个时期。这一演进历程的主要推动力在于:
1.性能需求
特别是 3D 图形应用对低延迟和高吞吐量的不懈追求。
2.功能需求
多窗口、桌面合成、视觉特效等需要更精细的图形资源管理和调度。
3.安全与稳定性需求
需要将高权限的硬件访问置于内核的严格控制之下。

二.Framebuffer架构
2.1 基本工作原理
Framebuffer,即帧缓冲区,简称FB。
帧缓冲区是一块内存,这块内存的每一个单元,都直接对应着屏幕上的一个像素。这是一种基于内存映射的直接写屏机制。
应用程序想要改变屏幕显示,只需像在白纸上写字、绘图一样,修改对应像素的数据即可。
应用程序写入数据后,并不需要通知内核。显示控制器会以固定的频率自动扫描整个帧缓冲区,并将数据转换成视频信号发送给显示器,图像便呈现出来。
显示架构如下图所示:

CPU直接在显存绘制字符或图形,如下图所示。

2.2 应用编程实例
cpp
/*1.打开帧缓冲区设备*/
int fd = open("/dev/fb0", O_RDWR);
/*2.获取屏幕信息*/
struct fb_var_screeninfo vinfo;
ioctl(fd, FBIOGET_VSCREENINFO, &vinfo);
/*3.内存映射帧缓冲区*/
char *fbuffer = mmap(0, vinfo.yres_virtual * vinfo.xres_virtual * 2,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
/*4.直接写入像素*/
int x = 100, y = 100;
int pixel_offset = y * vinfo.xres_virtual + x;
*((unsigned short*)(fbuffer + pixel_offset * 2)) = 0xF800;
2.3 优缺点
1.优点
FB 的巨大优势在于其简单性。它提供了一个统一接口,屏蔽了不同显示硬件的差异,使得开发图形应用变得简单直接。同时,由于避免了不必要的数据拷贝,在简单场景下效率较高,非常适合早期的嵌入式系统和文本控制台。
2.缺点

三.X Server架构
3.1 基本原理
X Server 采用独特的"客户端-服务器"架构,但这与通常的网页浏览的C/S模型角色相反。
服务端 是 X Server 本身,运行在本地有显示设备的计算机上。它的职责是直接驱动显示硬件,负责基本的图形绘制。
客户端则是应用程序,被称为 X Client。一个文本编辑器、一个浏览器,甚至桌面环境本身,都是 X Client。它们可以运行在本地,也可以运行在网络上的任何一台计算机上。
X Client 并不直接操作屏幕来显示窗口或文字。当它需要显示内容时,会通过 X 协议 向 X Server 发送一个"绘图请求"。
3.1.1 无GPU的平台
DDX(Device-Dependent X)驱动是用户空间的X Server组件,它通过/dev/fbx和直接内存映射(mmap) 的方式控制显卡。
先打开/dev/fbx,获得屏幕相关信息;然后通过mmap映射显示控制器的寄存器和显存到X Server进程空间。这样,X Server就可直接对显卡控制。

3.1.2 有GPU的平台
DDX驱动会打开GPU特定的设备文件,而不是通用的/dev/fb0。
然后直接映射GPU寄存器和显存,通过向GPU提交加速命令来利用硬件加速功能,完全绕过内核的帧缓冲区框架。

3.2 DDX驱动实例
3.2.1 无GPU的平台
cpp
/*1.打开设备节点*/
int fbfd = open("/dev/fb0", O_RDWR);
/*2.查询显示设备信息*/
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
//获取可变信息(分辨率、色深等)
ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)
//获取固定信息(帧缓冲区物理地址等)
ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)
/*3.内存映射显存*/
size_t fb_size = vinfo.yres_virtual * finfo.line_length;
char *fb_buffer = mmap(NULL, fb_size, PROT_READ | PROT_WRITE,
MAP_SHARED, fbfd, 0);
/*4.绘图操作*/
//简单的绘图示例:在位置(x,y)绘制一个像素
void fbdev_draw_pixel(int x, int y, uint32_t color)
{
// 计算像素在映射内存中的位置
size_t offset = y * finfo.line_length + x * (vinfo.bits_per_pixel / 8);
// 直接写入内存 - 立即反映在屏幕上!
*((uint32_t*)(fb_buffer + offset)) = color;
}
3.2.2 有GPU的平台
cpp
/*1.打开GPU专用设备节点*/
//对于早期的Intel显卡,可能是:
int gpu_fd = open("/dev/intel_gpu", O_RDWR);
//或者通过PCI设备直接访问:
int gpu_fd = open("/dev/pci/01:00.0", O_RDWR);
//现代系统可能是DRI设备:
int gpu_fd = open("/dev/dri/card0", O_RDWR);
/*2.映射GPU硬件资源*/
volatile uint32_t *gpu_regs = mmap(...);
void *gpu_fb = mmap(...);
/*3.使用GPU加速功能*/
//启用2D加速引擎
gpu_regs[BLT_ENGINE_CONTROL] = BLT_ENGINE_ENABLE;
//设置位块传输操作
gpu_regs[BLT_SOURCE_ADDR] = source_buffer_addr;
gpu_regs[BLT_DEST_ADDR] = dest_buffer_addr;
gpu_regs[BLT_WIDTH] = width;
gpu_regs[BLT_HEIGHT] = height;
gpu_regs[BLT_ROP] = ROP_SRC_COPY;
// 执行传输命令
gpu_regs[BLT_COMMAND] = BLT_EXECUTE;
3.3 优缺点
1.优点

2.缺点
