Android渲染-AHardwareBuffer

news2024/11/25 23:52:54

本文主要从应用的角度介绍android的native层AHardwareBuffer创建纹理以及保存渲染数据。

HardwareBuffer

要介绍native层的AHardwareBuffer,就需要先从Java层的HardwareBuffer说起。Android官方对于HardwareBuffer介绍如下:

HardwareBuffer wraps a native AHardwareBuffer object, which is a low-level object representing a memory buffer accessible by various hardware units. HardwareBuffer allows sharing buffers across different application processes. In particular, HardwareBuffers may be mappable to memory accessibly to various hardware systems, such as the GPU, a sensor or context hub, or other auxiliary processing units. For more information, see the NDK documentation for AHardwareBuffer.

HardwareBuffer 官方介绍为一种底层的内存 buffer 对象,可在不同进程间共享,可映射到不同硬件系统,如 GPU、传感器等,从构造函数可以看出,其可以指定 format 和 usage,用来让底层选择最合适的实现。

从HardwareBuffer的源码中可以了解到,HardwareBuffer只是 GraphicBuffer 的一个包装。在Android早期版本(API<=25), Java层并没有提供底层的GraphicBuffer API,通常使用底层由GraphicBuffer实现的Surface。因此本质上是 Android 系统开放了更底层的 API,我们才可以有更高效的实现。接下来看具体如何基于HardwareBuffer跨进程传输纹理。

通过 AHardwareBuffer_toHardwareBuffer 函数,可以将native层的AHardwareBuffer 对象转为 Java HardwareBuffer 对象,其本身实现了 Parcelable 接口,可以直接通过 AIDL 传递到另一个进程,其中具体的实现就是 Android 系统 GraphicBuffer 跨进程的方案,底层通过 fd 实现,B进程获取对应的HardwareBuffer后,可以通过AHardwareBuffer_fromHardwareBuffer继续转换为native层的AHardwareBuffer。 

AHardwareBuffer

接下来主要介绍使用AHardwareBuffer创建纹理以及通过AHardwareBuffer读取纹理图像的流程

AHardwareBuffer创建纹理

创建纹理的流程较为简单,创建AHardwareBuffer_Desc句柄,结构体赋值,本文以创建NV21的OES纹理为例,代码如下:

FUN_BEGIN_TIME("RenderContext::CreateOESTexture")
    if(textureID == 0){
        AHardwareBuffer_Desc h_buffer_desc = {0};
        h_buffer_desc.stride = frameData->i32Width;
        h_buffer_desc.height = frameData->i32Height;
        h_buffer_desc.width = frameData->i32Width;
        h_buffer_desc.layers = 1;
        h_buffer_desc.format = 0x11;
        h_buffer_desc.usage = AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN|AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;

        int ret = AHardwareBuffer_allocate(&h_buffer_desc, &inputHWBuffer);
        EGLint attr[] = {EGL_NONE};
        EGLDisplay edp;
        edp = (EGLDisplay)eglGetCurrentDisplay();
        inputEGLImage) = eglCreateImageKHR(edp, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, eglGetNativeClientBufferANDROID(inputHWBuffer), attr);
        glGenTextures(1, &textureID);
        glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureID);
        glTexParameteri(GL_TEXTURE_EXTERNAL_OES , GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_EXTERNAL_OES , GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES , (GLeglImageOES)inputEGLImage);
        GLUtils::CheckGLError("eglCreateImageKHR");
    }
    AHardwareBuffer_Planes planes_info = {0};
    int ret = AHardwareBuffer_lockPlanes(inputHWBuffer,
                                         AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK,
                                         -1,
                                         nullptr,
                                         &planes_info);
    if (ret != 0) {
        LOGI("Failed to AHardwareBuffer_lockPlanes");
    }
    else
    {
        memcpy(planes_info.planes[0].data,frameData->ppu8Plane[0],frameData->i32Width * frameData->i32Height*3/2);
        ret = AHardwareBuffer_unlock(inputHWBuffer, nullptr);
        if (ret != 0) {
            LOGI("Failed to AHardwareBuffer_unlock");
        }
    }
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureID);
FUN_END_TIME("RenderContext::CreateOESTexture")

AHardwareBuffer读取纹理图像数据

读取纹理图像数据的方式和创建纹理的方式类似,通过上述创建纹理的方式,我们实现了AHardwareBuffer 和 EGLImageKHR的绑定,因此,我们可以通过反向思维,将纹理读取出来,代码如下:

FUN_BEGIN_TIME("RenderContext::ReadOESTexture")
    unsigned char *ptrReader = nullptr;
    ret = AHardwareBuffer_lock(inputHWBuffer, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, -1,     nullptr, (void **) &ptrReader); 
    memcpy(dstBuffer, ptrReader, imgWidth * imgHeight * 3 / 2);
    ret = AHardwareBuffer_unlock(inputHWBuffer, nullptr);
FUN_END_TIME("RenderContext::ReadOESTexture")

至此,我们可以将dstBuffer通过字节,或者其他形式,保存为图像数据。

总结

针对Android侧,我们需要理清GraphicBuffer、AHardwareBuffer、ANativeWindowBuffer之间的关系。从联系上,GraphicBuffer 继承了ANativeWindowBuffer,所以可以直接通过static_cast<>类型转换成ANativeWindowBuffer,不过由于是多继承,所以转完有一个地址偏移(static_cast 自动完成)。而AHardwareBuffer只是一个抽象的概念,没有具体类型,与GraphicBuffer 没有任何继承关系,也没有具体的类型,是个空结构体,类似于void 类型。从源码可以看到,aosp封装的那些AHardwareBuffer_xxx接口,本质上底层都是通过AHardwareBuffer_to_GraphicBuffer,转成GraphicBuffer,依旧用GraphicBuffer的形式做的后续处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1292185.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

中国科技巨头:集体变革中 /华为鸿蒙 4:功能、模型、生态三大升级 |魔法半周报

我有魔法✨为你劈开信息大海❗ 高效获取AIGC的热门事件&#x1f525;&#xff0c;更新AIGC的最新动态&#xff0c;生成相应的魔法简报&#xff0c;节省阅读时间&#x1f47b; &#x1f525;资讯预览 中国科技巨头&#xff1a;集体变革中 华为鸿蒙 4&#xff1a;功能、模型、生…

宁夏一男子吸烟“逼”慢高铁 拘留7天 AI技术如何提升公共安全

最近&#xff0c;宁夏的一位男子杨某在高铁卫生间吸烟&#xff0c;触发了列车的烟雾报警系统&#xff0c;导致列车降速运行&#xff0c;最终被拘留7天。这个事件凸显了公共安全的重要性&#xff0c;特别是在交通工具上的安全管理。如果我们能够及时发现并阻止这种行为&#xff…

0011Java程序设计-ssm药店管理系统微信小程序

文章目录 摘 要目 录系统实现5.2服务端开发环境 编程技术交流、源码分享、模板分享、网课分享 企鹅&#x1f427;裙&#xff1a;776871563 摘 要 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机…

互联网医院|北京互联网医院系统开发功能

打造移动互联网医院&#xff0c;就是&#xff0c;通过移动互联网将医院与患者、医院内部&#xff08;医生、护士、领导层&#xff09;、医院与生态链上的各类组织机构连接起来。以患者为中心&#xff0c;优化医院业务流程&#xff0c;提升医疗服务质量与医院资源能效&#xff0…

SQL Server数据库的备份和还原

6.2 SQL Server备份和还原 数据库管理员最担心的情况就是数据库瘫痪&#xff0c;造成数据丢失&#xff0c;而备份作为数据的副本&#xff0c;可以有 效地保护和恢复数据。本节将介绍数据备份的原因&#xff0c;备份的方式.SOL Server的恢复模式.以及备 份策略和备份设备。 6.2…

KubeSphere Marketpalce 上新!Databend Playground 助力快速启动数据分析环境

12 月 5 日&#xff0c;Databend Labs 旗下 Databend Playground&#xff08;社区尝鲜版&#xff09;成功上架青云科技旗下 KubeSphere Marketplace 云原生应用扩展市场&#xff0c;为用户提供一个快速学习和验证 Databend 解决方案的实验环境。 关于 Databend Playground Dat…

视频集中存储/智能分析融合云平台EasyCVR平台接入rtsp,突然断流是什么原因?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

销售如何开发客户?

在销售过程中&#xff0c;开发客户是至关重要的一环。只有拥有足够的客户群体&#xff0c;才能为公司带来更多的业务机会和收入。 现如今&#xff0c;不管是哪一行竞争都十分激烈&#xff0c;特别是那些本身没有核心竞争力和核心技术的传统 to b企业&#xff0c;正处于十分尴尬…

输入一个月份,告知这个月份属于哪个季节的

一、输入特点 使用switch语句&#xff0c;属于月份的数字&#xff1b;如果和月份的数字没有关系则会显示【你的输入有错误&#xff01;】。 二、输入代码 import java.util.Scanner; public class judgeSeasonDemo {public static void main(String[] args){try (Scanner s…

Linux | tar,bc,uname指令

Linux | tar&#xff0c;bc&#xff0c; 文章目录 Linux | tar&#xff0c;bc&#xff0c;tar指令【重要】bc指令uname –r指令 tar指令【重要】 tar [-cxtzjvf] 文件与目录 … 参数&#xff1a; -c &#xff1a;建立一个压缩文件的参数指令(create 的意思)&#xff1b;-x &am…

网站测试都要测试哪些?如何进行测试?

1 UI测试 看页面是否美观养眼(包括页面的布局是否合理&#xff0c;策划是否舒服美观&#xff0c;页面长度是否合理&#xff0c;前景色与背景色是否搭配&#xff0c;页面风格是否统一&#xff0c;色调是否适合人眼&#xff0c;会不会太刺眼&#xff0c;字体大小是否合适&#x…

科技云报道:AI+PaaS,中国云计算市场迎来新“变量”?

科技云报道原创。 没有小的市场&#xff0c;只有还没有被发现的大生意。 随着企业数字化转型的逐级深入&#xff0c;市场需求进一步向PaaS和SaaS层进发&#xff0c;使之成为公有云服务市场增长的主要动力。 根据IDC最新发布的报告显示&#xff0c;2022-2027五年间中国公有云…

HarmonyOS开发工具DevEco Studio的下载和安装

一、DevEco Studio概述 一、下载安装鸿蒙应用开发工具DevEco Studio 开发鸿蒙应用可以从鸿蒙系统上运行第一个程序Hello World开始。 为了得到这个Hello World&#xff0c;你需要得到这个Hello World的源代码&#xff0c;源代码是用人比较容易看得懂的计算机编程语言规范写的…

私域最全养号攻略---微信

微信号的使用规则&#xff1a; 注册新微信、微信实名认证、主动添加好友、面对面建群、被动添加好友、进群限制、朋友圈限制、好友上限 微信权重加分规则&#xff1a; 基础信息是否完整、注册时间、微信使用行为、 微信权重扣分规则&#xff1a; 使用的环境是否正常、部分行为会…

simulink merge模块使用案例分析

作用&#xff1a;汇总多个信号分支&#xff0c;但最终可根据用户设定条件选择某路分支输出 Enabled Subsystem3 Enabled Subsystem2 分析&#xff1a;可以看到&#xff0c;在1s时刻输出 Enabled Subsystem2的1&#xff0c;在2s时刻输出 Enabled Subsystem3的2。 为方便理解&a…

ComplexHeatmap热图专栏 | 6. 3D热图绘制教程

本期教程 原文链接https://mp.weixin.qq.com/s/EyBs6jn78zOomcTv1aP52g 6 3D热图的绘制教程 基于《热图绘制教程》专栏&#xff0c;本教程已更新了5个章节&#xff0c;不知道大家是否有所收获。对于小杜个人来说&#xff0c;真的需要不断的复习和练习才可以记住&#xff0c;但…

【数据结构】手撕排序

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《Linux》《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 文章目录 一、排序的概念及其运用1.1 排序的概念1.2 常见的算法排序 二、 冒泡排序三、直接插入排…

【C语言】程序设计加密解密

&#x1f6a9;write in front&#x1f6a9; &#x1f50e; 介绍&#xff1a;"謓泽"正在路上朝着"攻城狮"方向"前进四" &#x1f50e;&#x1f3c5; 荣誉&#xff1a;2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2222年获评百大博…

系列学习前端之第 3 章:一文精通 css

全套学习 HTMLCSSJavaScript 代码和笔记请下载网盘的资料&#xff1a; 链接: 百度网盘 请输入提取码 提取码: 6666 一、CSS基础 1. CSS简介 CSS 的全称为&#xff1a;层叠样式表 ( Cascading Style Sheets ) 。 CSS 也是一种标记语言&#xff0c;用于给 HTML 结构设…

电脑搜不自己的手机热点,其余热点均可!

一、现象&#xff1a; 之前可正常连接&#xff0c;突然间发现收不到自己的WiFi信号&#xff0c;其余人均可收到。通过重复手机电脑关机、改变热点设置中的频段等方式均没解决&#xff0c;同事电脑和手机可搜索到我的WiFi。 二、问题&#xff1a; WiF驱动程序更新 三&#x…