一、PXP介绍
在图像显示在显示器之前,i.MX RT1170 可以通过 2D矢量图形、PXP 或者 LCDIF 等图形加速器来生成、合成和混合图形的内容,本文将介绍其中 PXP 图形加速器。
PXP (Pixel Processing Pipeline) 是 NXP 设计的一种高性能的 2D 图形处理微构架,用于在 LCD 显示之前对图像数据进行数据处理,处理操作例如图像缩放、旋转、色彩空间转换等,为无 SDRAM 和基于 SRAM 的系统,提供占用内存最小的图像数据优化和性能,PXP 将几个独立的处理阶段集成到一个内聚策略中,以创建灵活的像素管道。
1.1 PXP 功能描述
PXP 由多个管线式模块组成,执行视频源帧缩放、颜色空间转换、阿尔法混合/颜色键算法、次级 CSC、像素校正等,本文将介绍其中的旋转功能。
1.2 PXP 特性
- 位块传输
- 灵活的图像合成的
- Porter-Duff 颜色渲染操作
- 图像旋转 (90°、180°、270°)
- 图像调整大小
- 颜色空间转换
- 多像素格式支持(RGB, YUV444, YUV422, YUV420, YUV400)
- 标准 2D-RAM 操作
二、PXP的旋转功能
PXP 中集成了一个单独的旋转资源,该资源在PXP数据路径中的位置是可编程的,旋转在输出阶段合成 AS 和 PS 缓冲区后。 作为替代配置,PS 缓冲区可以旋转,然后与未旋转的 AS 面合成,有一个配置位提供在 PXP 中执行旋转的位置配置。 要旋转图形,硬件必须在帧缓冲区的同一个方向上读取像素,并在另一个方向上写入像素,对于 90 度和 270 度的情况,这意味着在帧缓冲区中读取或写入像素行必须垂直,如下图所示。
为了更有效地旋转,就必须旋转多个列,以使引擎能够获取和存储像素,从而提高内存性能。最简单的方法是对像素进行块操作,要旋转图像,就必须按所需的每个像素块进行旋转,如下图所示。
为了管理旋转过程,可以将源图像分解为具有下图所示坐标的子块网格,除了旋转块外,每个块都必须转换到新的坐标位置,对于每种旋转角度(0、90、180、270),可以定义用于计算新转换的网格地址的简单算法,然后硬件必须简单地从加载和存储操作的基本网格地址来计算内存地址。
为了平衡对内存控制器的合理突发大小要求,并将硬件存储要求保持在最低水平,混合/旋转引擎将在 8x8 或 16x16 像素块上运行处理,将旋转引擎与输入提取引擎一起使用时,所以需要对输入提取引擎进行编程,使其在 8x8 块模式下工作。
三、PXP 旋转功能 DEMO
3.1 介绍
本文采用 NXP i.MX RT1170 开发板套件,套件所配套的屏幕为 720x1280 的 LCD 竖向屏幕如下图所示,遇到需要横向显示的情景时,就可用到 PXP 加速图像引擎旋转图像了。
3.2 导入 SDK 例程
使用 MCUXpressoIDE 导入NXP i.MX RT1170 SDK PXP rorate 例程如下图所示。
3.3 旋转程序
3.3.1 初始化输入图像缓冲区
绘制 1280x720 大小的缓冲区数组,分别用蓝、红、白、绿色,标记四块大小相同的区域,如下图所示。
static void APP_InitInputBuffer(void)
{
uint32_t i, j;
for (i = 0; i < (360); i++)
{
for (j = 0; j < 640; j++)
{
s_psBufferPxp[i][j] = APP_BLUE;
}
for (; j < 1280; j++)
{
s_psBufferPxp[i][j] = APP_RED;
}
}
for (; i < 720; i++)
{
for (j = 0; j < 640; j++)
{
s_psBufferPxp[i][j] = APP_GREEN;
}
for (; j < 1280; j++)
{
s_psBufferPxp[i][j] = APP_WHITE;
}
}
memset(s_BufferLcd, 0x0U, sizeof(s_BufferLcd));
}
3.3.2 PXP 初始化
pxp_rotate.c -> int main(void) -> APP_InitPxp(); 中初始化 PS 面以及设置输出图像的配置,将 PXP 配置为处理 16x16 的像素块。
// 初始化 PXP
APP_InitPxp();
PXP 使用 REG_CTRL[BLOCK_SIZE] 控制位,处理像素块可以配置为 8x8 像素块或 16x16 像素块,当优化系统的内存带宽和图像处理时间时,可以选择 16x16 像素的块大小时,获取 AS 和 PS 面以及写入最后帧缓冲区的访问效率更高,因为每个内存请求和处理的数据是原来的两倍。
// PXP 配置 为处理 16x16 的像素块
PXP_SetProcessBlockSize(PXP, kPXP_BlockSize16);
3.3.3 旋转函数
pxp_rotate.c -> int main(void) -> APP_Rotate() -> PXP_SetRotateConfig() API 设置 PXP 旋转处理角度。
static const pxp_rotate_degree_t degrees[] = {
kPXP_Rotate0,
kPXP_Rotate90,
kPXP_Rotate180,
kPXP_Rotate270,
};
/* Prepare next buffer for LCD. */
PXP_SetRotateConfig(APP_PXP, kPXP_RotateProcessSurface, degrees[i], kPXP_FlipDisable);
3.4 例程演示效果
例程效果为每秒进行顺时针 90° 的旋转。
四、参考资料
【i.MX RT1170 异构图形管线】
https://www.nxpic.org.cn/module/forum/thread-621465-1-1.html
【AN13075: i.MX RT1170 Heterogeneous Graphics Pipeline – Application Note】
https://www.nxp.com.cn/docs/en/application-note/AN13075.pdf
评论