显示与 GPU 加速
AC792N SDK 的显示子系统:多接口 LCD 屏驱框架(MCU/MIPI/RGB/SPI)与硬件 DMA2D/GPU 加速能力的完整实现说明。
Purpose and Scope
本页覆盖 AC792N SDK 中"显示与 GPU 加速"这一能力的全部关键实现:
- LCD 显示驱动框架:屏类型配置宏、驱动抽象结构
lcd_dev_drive、板级配置lcd_board_cfg、驱动注册宏、IOCTL 控制接口、Framebuffer 组件。 - GPU/DMA2D 加速:
gpu_common_api(帧缓冲旋转)、gpu_adapter适配层、LVGL 图形库的 GPU 后端(jl_dma2d与jl_gpu2p5d2.5D GPU 绘制管线)。
本页不涉及以下内容,它们属于其他目录页:LVGL 图形库本身的使用与控件 API(见 LVGL 相关页面)、触摸屏事件处理(touch_event.h 属触摸子系统)、FreeType 字体渲染细节。
Overview
AC792N 是一颗面向带屏应用的蓝牙 SoC,其显示子系统由三部分协同工作:
屏驱框架(lcd_driver):屏蔽底层接口差异,向上提供统一的
init/draw/uninit/bl_ctrl回调模型。通过TCFG_LCD_屏幕类型_屏幕驱动_屏幕尺寸形式的宏来唯一切换屏幕配置——lcd_config.h中明确注释"只能开一个屏幕宏",这是该框架的配置核心。支持 MCU 并口(IMD)、MIPI DSI、RGB 并口、SPI 四种物理接口,且支持"多屏驱动"模式(TCFG_LCD_SUPPORT_MULTI_DRIVER_EN)让同一固件适配多块屏幕。GPU/DMA2D 加速:SoC 内置 DMA2D 引擎与 2.5D GPU。
gpu_common_api对外暴露帧缓冲旋转接口(gpu_rotate_frame_buf),供 UI 在屏显方向与绘制方向不一致时做 90°/180°/270° 旋转;gpu_adapter将硬件驱动能力适配为上层可调用的软件接口。LVGL GPU 后端:LVGL v8 的绘制层通过
src/draw/jl/目录挂接杰理(Jieli)私有 GPU 驱动——jl_dma2d负责 2D 块传输/填充加速,jl_gpu2p5d提供 2.5D GPU 的硬件绘制(圆弧、图片、文字、直线、多边形、矩形),大幅降低 CPU 在 UI 渲染上的负载。
设计意图:将"屏物理差异"与"绘制加速"解耦。应用层(如 LVGL)只面对帧缓冲与绘制接口,具体屏的时序、初始化序列、背光控制全部收敛在屏驱回调中;而所有像素级搬运、旋转、图形填充下沉到硬件 GPU,保证高分辨率屏(最高 1280×1280 级别)的流畅刷新。
Architecture
flowchart TD
subgraph sg_App["应用层"]
LVGL["LVGL v8 图形库"]
App["应用程序 / 场景 lcd_scenes"]
end
subgraph sg_GpuBackend["GPU 后端 (lvgl_v8/src/draw/jl)"]
JlDma2d["lv_gpu_jl_dma2d<br/>2D DMA 加速"]
JlGpu2p5d["lv_gpu_jl_gpu2p5d<br/>2.5D GPU 绘制"]
end
subgraph sg_DisplayCore["显示核心 (apps/common/lcd)"]
LcdDriver["lcd_driver.c<br/>驱动注册与分发"]
LcdTools["lcd_tools.c / lcd_scenes.c"]
FbLcd["fb_lcd.c Framebuffer 组件"]
DevDrive["struct lcd_dev_drive<br/>init/draw/uninit/bl_ctrl"]
end
subgraph sg_GpuCore["GPU 加速核心 (apps/common/dma2d_gpu)"]
GpuApi["gpu_common_api.c<br/>gpu_rotate_frame_buf"]
GpuAdapter["gpu_adapter.c"]
end
subgraph sg_Hw["硬件层 (include_lib)"]
HwGpu["asm/jlgpu_driver.h<br/>硬件 GPU 驱动"]
Panels["屏驱实现<br/>mcu_lcd / mipi_lcd / spi / rgb"]
end
App --> LVGL
LVGL --> JlDma2d
LVGL --> JlGpu2p5d
JlDma2d --> GpuAdapter
JlGpu2p5d --> GpuAdapter
GpuAdapter --> HwGpu
GpuApi --> GpuAdapter
LVGL --> FbLcd
LcdDriver --> DevDrive
DevDrive --> Panels
LcdTools --> LcdDriver
FbLcd --> LcdDriver
架构分层说明:
- 应用/场景层:
lcd_scenes.c管理不同 UI 场景的切换与绘制入口;LVGL 提供控件与布局。 - GPU 后端层:LVGL 的
draw/jl目录将绘制回调指向杰理 GPU 实现,lv_gpu_jl.c作为总入口把 LVGL 的绘制请求分发到 DMA2D 或 2.5D GPU。 - 显示核心层:
lcd_driver.c维护驱动注册表,按lcd_name与板级配置匹配屏驱;fb_lcd.c提供 Framebuffer 抽象,负责多缓冲交换与刷新同步。 - GPU 核心层:
gpu_common_api.c封装帧旋转等通用操作;gpu_adapter.c把硬件寄存器操作适配成软件 API。 - 硬件层:
jlgpu_driver.h定义 GPU 寄存器级驱动;mcu_lcd/、mipi_lcd/等目录存放各型号屏的初始化序列与推屏函数。
LCD 显示框架
屏配置宏与分辨率映射
lcd_config.h 是整个显示子系统的配置入口。其核心规则是:通过 TCFG_LCD_屏幕类型_屏幕驱动_屏幕尺寸 宏唯一定义当前使用的屏幕,且同一时间只能开启一个屏宏。每个屏宏同时定义全局分辨率 LCD_W/LCD_H:
//MCU LCD
#if TCFG_LCD_MCU_ILI9488_320X480
#define LCD_W 320
#define LCD_H 480
#endif
//MIPI LCD
#if TCFG_LCD_MIPI_ILI9881C_800x1280
#define LCD_W 800
#define LCD_H 1280
#endif
//RGB_LCD
#if TCFG_LCD_RGB_HX8264_800x480
#define LCD_W 800
#define LCD_H 480
#endif
//SPI LCD
#if TCFG_LCD_SPI_GC9307_240X296
#define LCD_W 240
#define LCD_H 296
#endif
Source: lcd_config.h
该文件还区分了单屏驱动与多屏驱动两种模式:当 TCFG_LCD_SUPPORT_MULTI_DRIVER_EN == 0 时,所有屏宏互斥,编译期即确定唯一的 LCD_W/LCD_H;开启多屏驱动后,同一固件可携带多块屏的驱动,由板级配置在运行时匹配(见下文 lcd_dev_drive 的 logo/id 匹配机制)。设计上,把分辨率映射放进配置头而非驱动实现,是为了让上层 UI 逻辑在编译期就能拿到画布尺寸,避免运行时查询。
驱动抽象:struct lcd_dev_drive
屏驱的统一接口由 struct lcd_dev_drive 定义,所有 MCU/MIPI/RGB/SPI 屏驱都必须实现这组回调:
struct lcd_dev_drive {
const char *logo;
unsigned int id;
enum LCD_IF type;
int (*init)(struct lcd_board_cfg *bd_cfg);
int (*draw)(void *data);
int (*uninit)(struct lcd_board_cfg *bd_cfg);
void (*bl_ctrl)(struct lcd_board_cfg *bd_cfg, u8 onoff);
...
};
Source: lcd_driver.h
各字段职责:
logo:屏驱名称字符串,与板级配置lcd_board_cfg.lcd_name匹配,实现"驱动与板子"的运行时配对。id/type:驱动 ID 与接口类型(enum LCD_IF,取自asm/dpi.h、asm/pap.h、asm/dsi.h等硬件头文件)。init(bd_cfg):屏初始化入口,负责拉复位脚、发初始化序列(各屏驱文件里的初始化数组)、配置接口时序;bd_cfg提供背光/复位/片选/命令-数据脚的 GPIO 与电平。draw(data):推屏入口,把帧缓冲数据按屏接口协议送到面板。uninit(bd_cfg):反初始化,进入低功耗前关闭屏。bl_ctrl(bd_cfg, onoff):背光开关控制。
lcd_driver.c 负责把这些驱动登记成设备并通过 dev_* 设备模型暴露给上层,上层用 dev_open("lcd", ...) 打开后即可用 IOCTL 控制。这种"回调表 + 设备模型"的设计让新增一款屏只需写一个 lcd_dev_drive 实现并放到 .lcd_device 段,主框架零改动。
板级配置与驱动注册
板级差异(引脚、背光极性、TE 脚)由 struct lcd_board_cfg 承载:
struct lcd_board_cfg {
char *lcd_name; ///< 屏驱配置名(用于与屏驱配置匹配)
struct {
u8 backlight_value; ///< 背光控制使能电平
int backlight; ///< 背光控制IO
int lcd_reset; ///< 复位脚
int lcd_cs; ///< 片选脚
int lcd_rs; ///< 屏幕命令/数据脚
} lcd_io;
struct te_mode_ctrl te_mode; ///< TE功能配置(仅MCU/SPI类型的屏需要)
char *spi_lcd_interface; ///< spi屏的推屏接口(仅SPI屏需要)
};
Source: lcd_driver.h
配套的 LCD_PLATFORM_DATA_BEGIN/ADD/END 宏用于在 .lcd_board_cfg 段声明多组板级配置,配合多屏驱动模式实现"一套固件、多块板卡"。te_mode 是 TE(Tearing Effect)同步配置,仅 MCU/SPI 屏需要——它通过 te_mode_en/edge/gpio 三个字段使能并配置 TE 中断,防止推屏与面板刷新撕裂。
驱动注册使用段放置宏,把屏驱实例放入链接脚本的 .lcd_device 段,由框架统一扫描:
#define REGISTER_IMD_DEVICE_BEGIN(info) \
static union lcd_dev_info info SEC_USED(.lcd_device) = { \
.imd
#define REGISTER_IMD_DEVICE_END() \
};
#define REGISTER_MIPI_DEVICE_BEGIN(info) \
static union lcd_dev_info info SEC_USED(.lcd_device) = { \
.mipi
#define REGISTER_MIPI_DEVICE_END() \
};
#define REGISTER_LCD_SPI_DEVICE_BEGIN(info) \
static union lcd_dev_info info SEC_USED(.lcd_device) = { \
.spi
#define REGISTER_LCD_SPI_DEVICE_END() \
};
Source: lcd_driver.h
union lcd_dev_info 将 imd(MCU 并口)、mipi(DSI)、spi 三种设备描述联合存放,不同接口的屏驱通过不同 BEGIN 宏注册,统一落在 .lcd_device 段——这是典型的"编译期收集 + 运行时遍历"注册表模式,避免每个屏驱文件都要手动挂到初始化链表。
IOCTL 控制接口
上层通过设备 IOCTL 命令控制 RGB 屏的刷新流程,这些命令定义了帧缓冲交换与行中断同步的语义:
#define IOCTL_LCD_RGB_SET_ISR_CB _IOW('F', 1, sizeof(void *(*)(void)))
#define IOCTL_LCD_RGB_WAIT_FB_SWAP_FINISH _IOW('F', 2, sizeof(int))
#define IOCTL_LCD_RGB_START_DISPLAY _IOW('F', 3, sizeof(void *))
#define IOCTL_LCD_RGB_GET_LCD_HANDLE _IOR('F', 4, sizeof(struct lcd_dev_drive **))
#define IOCTL_LCD_RGB_SET_LINE_ISR_CB _IOW('F', 5, sizeof(int (*)(int)))
#define IOCTL_LCD_RGB_WAIT_LINE_FINISH _IOW('F', 6, sizeof(int))
Source: lcd_driver.h
IOCTL_LCD_RGB_SET_ISR_CB:注册刷新完成中断回调——应用在回调里切换绘制缓冲,避免在帧刷新中途写屏造成撕裂。IOCTL_LCD_RGB_WAIT_FB_SWAP_FINISH:阻塞等待帧缓冲交换完成,是"双缓冲 + 垂直同步"的关键同步原语。IOCTL_LCD_RGB_START_DISPLAY:启动显示(传入帧缓冲地址),触发硬件 DMA 持续向面板送数据。IOCTL_LCD_RGB_GET_LCD_HANDLE:获取底层lcd_dev_drive句柄,供需要绕过设备层直接调屏驱回调的场景使用。IOCTL_LCD_RGB_SET_LINE_ISR_CB/WAIT_LINE_FINISH:行级中断回调与等待,用于逐行刷新特效(如水波纹、卷帘)或精确的局部刷新控制。
颜色与基础绘制工具
lcd_driver.h 顶部定义了标准 RGB565 颜色常量(BLACK 0x0000 … WHITE 0xFFFF),lcd_tools.c 提供画点、画线、填充、字符等基础软件绘制函数。这些工具在无 GPU 或 GPU 不可用的小屏场景(如 SPI 屏)作为兜底绘制路径,与 GPU 加速路径通过 lcd_config.h 的宏开关二选一编译。
GPU / DMA2D 加速
通用 GPU API:帧缓冲旋转
gpu_common_api.h 是上层(UI 引擎、摄像头预览等)直接调用的 GPU 抽象层入口:
int gpu_rotate_frame_buf(uint8_t *src_buf, uint8_t *dst_buf,
int src_width, int src_height,
int dst_width, int dst_height,
int degree, int format);
Source: gpu_common_api.h
该接口解决一个典型问题:摄像头传感器或 UI 绘制方向与屏幕物理方向不一致时,需要把整帧旋转 90°/180°/270° 再上屏。gpu_rotate_frame_buf 接收源/目标缓冲与尺寸、旋转角度 degree、像素格式 format,由 gpu_common_api.c 按格式(RGB565/RGB888 等)分派到 DMA2D 硬件搬运。相比 CPU 逐像素旋转,硬件旋转在 800×1280 级别帧上可省下大量 MIPS,这正是 GPU 加速在带屏 SoC 上的首要价值。
适配层 gpu_adapter
gpu_adapter.c/h 是硬件寄存器驱动与软件 API 之间的薄适配层。gpu_adapter.h 仅包含 asm/cpu.h,适配实现依赖 CPU 头文件中的硬件描述,其职责是把 jlgpu_driver.h(sdk/include_lib/driver/cpu/wl83/asm/)暴露的寄存器级操作封装成上层友好的函数,并处理 DMA 完成中断、忙等待等同步细节。设计上独立成层的原因:同一套软件 API 可映射到不同 CPU 型号的 GPU 寄存器(当前为 wl83 内核),芯片换代时只需替换适配层。
LVGL GPU 后端(draw/jl)
LVGL v8 的绘制后端位于 sdk/apps/common/lvgl_v8/src/draw/jl/,包含两条加速管线:
lv_gpu_jl_dma2d(jl_dma2d):把 LVGL 的blend/fill(块传输与填充)绘制回调重定向到 DMA2D 硬件,lv_gpu_jl_dma2d.c注册为 LVGL 的 GPU draw unit。lv_gpu_jl_gpu2p5d(jl_gpu2p5d):2.5D GPU 绘制管线,按图元拆分模块:lv_gpu_jl_gpu2p5d_arc.c—— 圆弧/圆环硬件绘制lv_gpu_jl_gpu2p5d_img.c—— 图像缩放/旋转/混合lv_gpu_jl_gpu2p5d_letter.c—— 文字字形硬件渲染lv_gpu_jl_gpu2p5d_line.c—— 直线/描边lv_gpu_jl_gpu2p5d_polygon.c—— 多边形填充lv_gpu_jl_gpu2p5d_rect.c—— 矩形/圆角矩形填充lv_gpu_jl_gpu2p5d_comm.c/.c—— 公共上下文与入口
lv_gpu_jl.c 作为统一入口,根据 LVGL 传入的绘制描述符(lv_draw_ctx_t)分发到上述各模块。这套后端让 LVGL 控件的阴影、圆角、图片旋转等重活全部卸载到硬件 GPU,是带屏设备流畅 UI 的核心加速路径;gpu_demo.c(FreeType 示例)演示了文字渲染与 GPU 的配合用法。
Core Flow:一帧画面的完整生命周期
从应用提交绘制到像素上屏,一条典型的带 GPU 加速路径如下:
sequenceDiagram
participant App as 应用/场景 (lcd_scenes)
participant LVGL as LVGL 绘制上下文
participant GPU as GPU 后端 (jl_dma2d / jl_gpu2p5d)
participant HW as 硬件 GPU (jlgpu_driver)
participant DRV as lcd_driver / 屏驱 draw()
participant PANEL as 面板 (MCU/MIPI/RGB/SPI)
App->>LVGL: 提交控件重绘请求
LVGL->>GPU: 下发绘制描述符 (blend/fill/arc/img/letter)
GPU->>HW: 配置 DMA2D/2.5D 寄存器并启动
HW-->>GPU: 绘制完成中断
GPU-->>LVGL: 返回绘制完成,帧缓冲就绪
LVGL->>DRV: 请求显示交换 (WAIT_FB_SWAP_FINISH)
DRV->>DRV: 等待 TE 同步 / 行中断,避免撕裂
DRV->>PANEL: 调用屏驱 draw() 推帧
PANEL-->>DRV: 刷新完成 (ISR_CB)
DRV-->>App: 通知缓冲可复用,开始渲染下一帧
各步骤的关键点:
- 绘制提交:LVGL 在
lv_refr刷新周期内收集脏区,生成绘制任务。 - GPU 分发:
lv_gpu_jl.c判断图元类型——纯色/图片块用 DMA2D,复杂图元(弧/多边形/文字)走 2.5D GPU;无 GPU 覆盖的绘制回落软件绘制。 - 硬件执行:GPU 适配层配置寄存器、等待中断,完成后回调 LVGL 释放绘制上下文。
- 帧同步:RGB 屏使用
IOCTL_LCD_RGB_WAIT_FB_SWAP_FINISH阻塞到上一帧送完才交换缓冲;MCU/SPI 屏则依赖te_mode的 TE 中断对齐面板刷新,避免撕裂。 - 推屏:
draw()按屏接口协议(IMD 并口、DSI 命令/视频模式、SPI 或 RGB 并口)把帧缓冲搬运到面板;RGB 屏由 DMA 持续送显。 - 双缓冲轮转:刷新完成中断(
ISR_CB)通知应用切换绘制缓冲,形成"绘制一帧、显示一帧"的流水线。
使用示例
示例 1:屏配置宏选择(lcd_driver_test 场景的编译期配置)
lcd_config.h 是唯一需要修改的屏配置入口,下面的示例展示了 SPI 屏与 MIPI 屏的选择方式(实际工程在 app_config.h 中打开对应宏):
#if TCFG_LCD_SPI_GC9307_240X296
#define LCD_W 240
#define LCD_H 296
#endif
#if TCFG_LCD_MIPI_ILI9881C_800x1280
#define LCD_W 800
#define LCD_H 1280
#endif
Source: lcd_config.h
示例 2:屏驱回调结构与 IOCTL 使用
屏驱实现必须填写的回调表以及上层控制显示的命令,来自 lcd_driver.h:
struct lcd_dev_drive {
const char *logo;
unsigned int id;
enum LCD_IF type;
int (*init)(struct lcd_board_cfg *bd_cfg);
int (*draw)(void *data);
int (*uninit)(struct lcd_board_cfg *bd_cfg);
void (*bl_ctrl)(struct lcd_board_cfg *bd_cfg, u8 onoff);
};
#define IOCTL_LCD_RGB_SET_ISR_CB _IOW('F', 1, sizeof(void *(*)(void)))
#define IOCTL_LCD_RGB_START_DISPLAY _IOW('F', 3, sizeof(void *))
Source: lcd_driver.h
示例 3:GPU 帧旋转调用
需要把源帧旋转后送显时(如摄像头预览方向矫正),直接调用通用 GPU 接口:
int gpu_rotate_frame_buf(uint8_t *src_buf, uint8_t *dst_buf,
int src_width, int src_height,
int dst_width, int dst_height,
int degree, int format);
Source: gpu_common_api.h
调用方需自行保证 src_buf/dst_buf 容量与 format 匹配,degree 取 0/90/180/270,dst_width/dst_height 为旋转后的目标尺寸。
Configuration Options
屏类型选择宏(app_config.h 中定义,lcd_config.h 消费)
| 宏 | 类型 | 默认值 | 说明 |
|---|---|---|---|
TCFG_LCD_ENABLE | bool | 0 | 总开关,关闭则整个 LCD 子系统不编译 |
TCFG_LCD_SUPPORT_MULTI_DRIVER_EN | int | 0 | 多屏驱动支持;0=单屏互斥,1=运行时可匹配多块屏 |
TCFG_LCD_MCU_ILI9488_320X480 | bool | 0 | MCU 并口屏 ILI9488 320×480 |
TCFG_LCD_MCU_ILI9481_320X480 | bool | 0 | MCU 并口屏 ILI9481 320×480 |
TCFG_LCD_MCU_ST7789V_240x320 | bool | 0 | MCU 并口屏 ST7789V 240×320 |
TCFG_LCD_MIPI_FL7707_480x1280 | bool | 0 | MIPI 屏 FL7707 480×1280 |
TCFG_LCD_MIPI_ST7701S_480x800 | bool | 0 | MIPI 屏 ST7701S 480×800 |
TCFG_LCD_MIPI_ST7703_720x720 | bool | 0 | MIPI 屏 ST7703 720×720 |
TCFG_LCD_MIPI_ST7701S_480x800_ROTATE_90 | bool | 0 | MIPI 屏 ST7701S 旋转 90°(800×480) |
TCFG_LCD_MIPI_ST77922_480x480 | bool | 0 | MIPI 屏 ST77922 480×480 |
TCFG_LCD_MIPI_ILI9881C_800x1280 | bool | 0 | MIPI 屏 ILI9881C 800×1280 |
TCFG_LCD_MIPI_JD9165BA_1024x600 | bool | 0 | MIPI 屏 JD9165BA 1024×600 |
TCFG_LCD_RGB_XXXX_480x272 等 RGB 宏 | bool | 0 | RGB 并口屏系列(480×272 / 720×1280 / 1280×800 / ST7701S / HX8264 / FL58202) |
TCFG_LCD_SPI_GC9307_240X296 等 SPI 宏 | bool | 0 | SPI 屏系列(GC9307 / NV3006A 等) |
所有宏均为编译期开关,开启后由 lcd_config.h 自动生成对应的 LCD_W/LCD_H 分辨率宏供全局使用。规则:单屏模式下只能开一个屏宏,多屏模式下可开多个并在板级配置中区分。
板级配置(lcd_board_cfg)
| 字段 | 类型 | 说明 |
|---|---|---|
lcd_name | char* | 屏驱名,与 lcd_dev_drive.logo 匹配 |
lcd_io.backlight_value | u8 | 背光使能电平 |
lcd_io.backlight / lcd_reset / lcd_cs / lcd_rs | int | 背光/复位/片选/命令-数据 GPIO |
te_mode.te_mode_en / edge / gpio | u8/u8/int | TE 同步使能、触发边沿、TE 脚(MCU/SPI 屏) |
spi_lcd_interface | char* | SPI 屏推屏接口名(仅 SPI 屏) |
API Reference
struct lcd_dev_drive
屏驱统一抽象,所有屏幕驱动必须实现。
字段:
logo(const char*):屏驱名称,与板级lcd_name匹配id(unsigned int):驱动 IDtype(enum LCD_IF):接口类型(MCU/MIPI/SPI/RGB)init(struct lcd_board_cfg *bd_cfg):初始化,返回 0 成功draw(void *data):推屏uninit(struct lcd_board_cfg *bd_cfg):反初始化bl_ctrl(struct lcd_board_cfg *bd_cfg, u8 onoff):背光控制
Source: lcd_driver.h
struct lcd_board_cfg
板级引脚与同步配置(字段见上文"板级配置"表格)。
Source: lcd_driver.h
IOCTL 命令(RGB 屏刷新控制)
| 命令 | 方向 | 说明 |
|---|---|---|
IOCTL_LCD_RGB_SET_ISR_CB | 写 | 注册刷新完成回调 void (*)(void) |
IOCTL_LCD_RGB_WAIT_FB_SWAP_FINISH | 写 | 阻塞等待帧缓冲交换完成 |
IOCTL_LCD_RGB_START_DISPLAY | 写 | 启动显示,传入帧缓冲地址 |
IOCTL_LCD_RGB_GET_LCD_HANDLE | 读 | 获取 struct lcd_dev_drive ** 句柄 |
IOCTL_LCD_RGB_SET_LINE_ISR_CB | 写 | 注册行中断回调 int (*)(int) |
IOCTL_LCD_RGB_WAIT_LINE_FINISH | 写 | 等待指定行刷新完成 |
Source: lcd_driver.h
gpu_rotate_frame_buf(src_buf, dst_buf, src_width, src_height, dst_width, dst_height, degree, format)
硬件加速帧旋转。
参数:
src_buf(uint8_t*):源帧缓冲dst_buf(uint8_t*):目标帧缓冲src_width/src_height(int):源帧尺寸dst_width/dst_height(int):旋转后目标尺寸degree(int):旋转角度(0/90/180/270)format(int):像素格式(RGB565 等)
返回: 0 成功,非 0 失败。
Source: gpu_common_api.h
失败模式、边界情况与并发
- 多屏宏误开:单屏模式(
TCFG_LCD_SUPPORT_MULTI_DRIVER_EN == 0)下若同时开启多个屏宏,LCD_W/LCD_H会按文件内顺序被后定义者覆盖,导致分辨率与实际面板不符——lcd_config.h的注释"只能开一个屏幕宏"即是对此的硬约束。排查显示错位问题时应首先核对屏宏。 - 帧撕裂(Tearing):RGB 屏若不在
WAIT_FB_SWAP_FINISH后交换缓冲,面板刷新与缓冲写入并发会撕裂画面;MCU/SPI 屏依赖te_mode的 TE 中断对齐。te_mode_en未开启且接口无硬件同步时,只能靠降低帧率规避。 - TE 脚配置错误:
te_mode.gpio配错或edge边沿反相,会导致推屏时序错乱、花屏;调试时可用逻辑分析仪抓 TE 波形比对。 - GPU 旋转方向/尺寸不匹配:
gpu_rotate_frame_buf的degree与dst_width/dst_height必须自洽(如 90° 时宽高互换),否则硬件越界写dst_buf,属于未定义行为;调用方需对缓冲容量负责。 - 背光电平极性:
backlight_value定义了使能电平,接反会导致"亮屏变灭屏";这在多板共用一版固件时是常见配置错误,多屏驱动模式下尤其要检查每组的lcd_io。 - 并发与中断上下文:刷新完成回调(ISR_CB)在中断上下文执行,回调内不得调用阻塞 API 或直接操作屏驱未保护的共享状态;帧缓冲轮转应遵循"中断里只翻转标志,主循环里换缓冲"的惯例,避免缓冲指针竞争。
- 分辨率上限:RGB 屏最高 1280×1280(
TCFG_LCD_RGB_XXXX_1280x800档位)级别,帧缓冲与 GPU 带宽成为瓶颈;高分辨率下建议开启 DMA2D 绘制并保持双缓冲,避免 CPU 逐像素填充。
性能与运维注意事项
- 硬件加速优先:UI 重绘应尽量走
jl_dma2d/jl_gpu2p5d,软件绘制(lcd_tools.c)仅在低分辨率 SPI 屏或调试时兜底。 - 帧缓冲内存:RGB565 在 800×1280 下单帧约 2 MB,双缓冲需 4 MB 以上连续内存;配置
lcd_config.h时需同步核对 RAM 规划。 - 刷新率与功耗:背光
bl_ctrl与 TE 同步影响功耗;无刷新内容时建议关闭START_DISPLAY或降低帧率,屏驱uninit用于低功耗挂起。 - GPU 中断:硬件 GPU 完成依赖中断驱动,中断延迟直接决定绘制吞吐;避免在高优先级中断里长时间占用 GPU 寄存器。
Extension Points(扩展点)
- 新增屏驱:仿照
mcu_lcd/lcd_mcu_ili9488_320x480.c或mipi_lcd/lcd_mipi_ili9881c_800x1280.c,实现struct lcd_dev_drive回调,用REGISTER_IMD/MIPI/SPI_DEVICE_BEGIN/END宏放入.lcd_device段,并在lcd_config.h增加对应TCFG_LCD_*宏——框架零改动即可支持新面板。 - 多屏适配:开启
TCFG_LCD_SUPPORT_MULTI_DRIVER_EN,用LCD_PLATFORM_DATA_BEGIN/ADD/END声明多组lcd_board_cfg,运行时按lcd_name匹配屏驱。 - GPU 新图元:在
lvgl_v8/src/draw/jl/下按jl_gpu2p5d_*模块的模式新增图元实现,并在lv_gpu_jl.c的分发逻辑中注册。 - 芯片换代:替换
gpu_adapter.c内部实现以适配新 CPU 的 GPU 寄存器,gpu_common_api.h对外接口保持不变。
Related Links
- LCD 配置头文件 —— 屏宏与分辨率定义
- LCD 驱动接口 —— 驱动抽象、IOCTL、颜色定义
- LCD 驱动实现 —— 注册表与设备模型
- GPU 通用 API —— 帧旋转接口
- LVGL GPU 后端 —— LVGL 绘制分发入口
- 硬件 GPU 驱动 —— 寄存器级驱动
- LCD 驱动测试示例 —— 屏驱功能验证程序
- 相关目录页:LVGL 图形库使用、触摸屏事件处理、FreeType 字体渲染