Toybrick

RK3399Pro入门教程(5)图形加速引擎RGA的使用

 

jefferyzhang

版主

积分
12966
楼主
发表于 2019-4-15 17:48:29    查看: 202013|回复: 99 | [复制链接]    打印 | 显示全部楼层
本帖最后由 jefferyzhang 于 2022-5-27 09:56 编辑


简介

入门教学(1) 中,我们提到了RK自带的RGA核心,可以非常快速的处理二维图像的基本操作,例如
旋转、镜像、缩放、拷贝、剪裁、格式转换等等,那么这篇教学就将详细的说说如何使用。(Android和Linux用法是一致的)


设备节点

RGA的设备节点挂在:
  1. /dev/rga
复制代码


RGA库安装

如果大家不想了解更底层的细节,可以直接安装这个库来使用,我们已经帮大家封装了常用的操作和细节:
  1. sudo apt install rockchip-rga-dev
复制代码


Rockchip封装的LinuxRGA库源码 (new)

  1. https://github.com/rockchip-linux/linux-rga
  2. https://github.com/airockchip/librga
复制代码


如果想进一步了解RGA,可以研究下Android的Hardware/rockchip/librga来查看寄存器的配置等更详细的调用方式,或者使用该代码调用RGA。


示例代码下载地址

本教学的下载地址(已过期):
  1. https://github.com/Jerzha/samples-toybrick-rga.git
复制代码
新RGA教学sample在rga自带目录的sample目录下

注意:
1. sample地址里包含了rockchip_rga目录,该目录的内容就是dnf安装的librockchip_rga内容的源码,如果您不需要修改源码,可以直接dnf安装就好了
2. 如果没有交叉编译环境的话,请放在板子上编译

RGA注意事项

1. 16对齐。所有进入rga的图像的宽高需要进行16对齐,例如1920*1080的图像需要对齐成1920*1088。如果没有显式对齐的话,输出依然会是16对齐的,所以多出几个像素的奇怪的宽高,请不要认为是bug。
2. 可多线程调用来提高利用率
3. 或者设置回调函数的方式提高利用率(库没有提供回调函数注册)
4. RGA自带mmu,可以将虚拟地址转换成物理地址使用(IP核只认识物理地址)。当然如果预先知道物理地址,可以关闭mmu来提升速度。(库没有提供该功能)


基础使用流程(已过期,请参看新RGA Sample

1. 安装RGA库,详见wiki教学

2. 初始化RGA模块,生成context (多线程需要生成多个context)

  1. RockchipRga *mRga;
  2. if (!mRga) {
  3.     printf("create rga failed !\n");
  4.     abort();
  5. }
  6. mRga->ops->initCtx(mRga);
复制代码

3. 设置源(src)和目标(dst)的图片格式、宽高。(需要注意的是,图片格式我们引用Linux V4L2的标准图片格式定义)

  1. mRga->ops->setSrcFormat(mRga, V4L2_PIX_FMT_ABGR32, BUFFER_WIDTH, BUFFER_HEIGHT);
  2. mRga->ops->setDstFormat(mRga, V4L2_PIX_FMT_ABGR32, BUFFER_WIDTH, BUFFER_HEIGHT);
复制代码

4. 设置源(src)和目标(dst)图片的地址。(需要注意的是设置虚拟地址或者fd的接口是不一样的)

  1. mRga->ops->setSrcBufferPtr(mRga, srcBuffer);
  2. mRga->ops->setDstBufferPtr(mRga, dstBuffer);
复制代码

如果是fd(fd一般存在于通过drm申请的buffer), 当然这篇教学里用不到。

  1. mRga->ops->setSrcBufferFd(mRga, srcFd);
  2. mRga->ops->setDstBufferFd(mRga, dstFd);
复制代码

5. 如果只是拷贝和格式转换的话,那做到第四部就可以了。如果还有旋转剪裁等操作,需要再多设置几个:

旋转:
  1. mRga->ops->setRotate(mRga, RGA_ROTATE_90);  // RGA_ROTATE_180, RGA_ROTATE_270
复制代码

剪裁:
  1. mRga->ops->setSrcCrop(mRga, crop_x, crop_y, crop_w, crop_h);
复制代码

(库里提供的就这些。其他功能有需要的话需要自己新增接口了)

6. 插入rga任务队列,开始执行,同步等待返回。

  1. mRga->ops->go(mRga);
复制代码

该函数单个执行其实用不满RGA,因为在设置和返回结果时候RGA是空闲的。这时候可以通过多线程的调用来让RGA不停的排队工作。
或者还有一种更高级的方法就是设置回调函数,给RGA添加任务的时候立即返回,然后等RGA执行完毕后回调告诉程序已经结束,代价当然是程序复杂度就会变得很高。


结果总结

拷贝一张4096*2160的ARGB图像,如果使用malloc的内存(不连续),RGA拷贝速度是比CPU(有cache情况)慢的,测试代码RGA大概需要60ms。实际使用上RGA作为一个流处理器,并且使用CMA连续内容,速度会快非常多,cpu memcpy需要19ms(因为有cache,所以这个代码测试实际上也不能代表问题)如果是DRM分配的物理地址(连续地址)的话,RGA速度是比CPU快很多的,大概在低于15ms(具体数字还需要写代码测试)就可以完成一次搬运。
本篇教学只关注于如果教会大家用RGA,我们就不在这里写drm地址分配的问题了。


RGA优点:
1. 不占用CPU资源
2. DRM/CMA物理内存拷贝和转换速度很快

RGA缺点:
1. 对malloc的不连续的虚拟内存操作速度很慢


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

jefferyzhang

版主

积分
12966
沙发
 楼主| 发表于 2019-4-18 16:59:32 | 显示全部楼层
hjf515 发表于 2019-4-18 15:38
跑了例程 rga_cpy,发现 checkData 函数中打印出很多dst和src 不一致的数据,这是不是说用 rga copy 有点不 ...

rga其实就是一个ioctl,填下结构体就可以了,建议你看库源码自己实现一个,或者用android写好的librga库来二次开发。那个不一致是库代码的bug,不是大问题。

物理地址请参看android的libgralloc库来分配,rk的drm留了一些第三方接口来分配CMA/DMA内存,或者你看rga的库里注释掉的代码也是有分配drm内存的方法。
回复

使用道具 举报

jefferyzhang

版主

积分
12966
板凳
 楼主| 发表于 2019-7-9 16:10:26 | 显示全部楼层
盗骊_l 发表于 2019-7-8 16:15
您好,请问我在Android平台上应该怎么使用 RGA,头文件从哪里来?需要编译什么源码吗? ...

android rga查看 device/rockchip/librga
用法不太一样
回复

使用道具 举报

jefferyzhang

版主

积分
12966
地板
 楼主| 发表于 2019-7-10 16:39:16 | 显示全部楼层
盗骊_l 发表于 2019-7-9 19:15
啊?上面不是说  Android和Linux一致吗?
https://github.com/Jerzha/samples-toybrick-rga上面的demo, ...

驱动一样,用都可以用。只是android的封装会更高级一点。
你这里的转换代码没有问题,有问题要看看你开的buffer大小是不是对的。
回复

使用道具 举报

jefferyzhang

版主

积分
12966
5#
 楼主| 发表于 2019-9-8 12:10:11 | 显示全部楼层
15992605143 发表于 2019-9-6 22:31
rga可以按比例缩放吗?

当然可以。但是长宽只能是定点数
回复

使用道具 举报

jefferyzhang

版主

积分
12966
6#
 楼主| 发表于 2019-9-9 14:16:53 | 显示全部楼层
盗骊_l 发表于 2019-9-9 13:59
请问,多线程使用的时候需要注意什么?
我现在遇到的问题:
1>.每个线程里,mpp解码后使用RGA进行格式转换,, ...

设备重启请检查你自己的代码,RGA是物理的硬件,对内存溢出、地址越界是无法在CPU层面报错的,给什么搬运什么。越界就会覆盖其他地址,直接崩溃。
长宽都需要size需要16bit对齐。
回复

使用道具 举报

jefferyzhang

版主

积分
12966
7#
 楼主| 发表于 2019-9-17 18:03:47 | 显示全部楼层
shopping 发表于 2019-9-17 17:15
老哥,最近抽时间看了下你发的一些资料,问一句:
1.目前我除了用 opencv 调取摄像头,将视频数据裁剪缩放 ...

所以要问啥呢?我看了半天不知道你问题是啥
回复

使用道具 举报

jefferyzhang

版主

积分
12966
8#
 楼主| 发表于 2019-9-18 11:13:56 | 显示全部楼层
shopping 发表于 2019-9-18 09:45
老哥,我想问的是,现在我想不用opencv库,因为它占用内存较大。所以替代方案就是:
GStreamer/MPP 来调 ...

对的。没问题
回复

使用道具 举报

jefferyzhang

版主

积分
12966
9#
 楼主| 发表于 2019-9-18 14:15:54 | 显示全部楼层
shopping 发表于 2019-9-18 11:22
千头万绪,理不清楚,现在感觉脑子一片混沌。再追问一下:Debian系统下,MPP OpenGL  GStreamer  RGA我都 ...

请自行看wiki,全部都是dnf安装就可以。
当然除了opengl以外都有源码,愿意自己编译安装也行
回复

使用道具 举报

jefferyzhang

版主

积分
12966
10#
 楼主| 发表于 2019-9-20 16:30:19 | 显示全部楼层
shopping 发表于 2019-9-20 14:45
呃,请问 OpenGL 要怎么安装?还有我测试RGA时报了这样的问题,请问我这个RGA是安装好了? ...

rga不需要装,他是硬件的一个设备,挂载在/dev/rga下。
封装的rga库只是方便大家访问这个外设而已
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

产品中心 购买渠道 开源社区 Wiki教程 资料下载 关于Toybrick


快速回复 返回顶部 返回列表