EGLImage使用记录

1. 需求场景

项目需要实现如下path:

  1. 获取camera数据;
  2. GPU对camera数据做算法处理;
  3. 处理完成后丢给surface显示;

上述过程实现后存在撕裂现象,tearing即显示的buffer被复写导致出现画面撕裂;

2. 实验分析

  • camera getframe数据保存到文件确认数据完整性,此部分数据无异常;
  • APP中将camera获取数据通过memcpy方式提供给到GPU输入,则此部分操作不同buffer,不存在被复写可能性
  • GPU绘制操作完成后使用glFinish接口使得GPU操作与CPU同步;
  • 绘制完成后将fbofd提供给到surface显示

梳理上述环节后确认存在如下问题:

  1. fbofd仅创建了一个,则surface显示的时候进行下一帧数据绘制时一定存在复写;
  2. fix case 1后撕裂现象仍比较明显,且伴随着画面闪烁,由于texture输入使用固定vir_addr,所以怀疑framebuffer 绑定异常;
    1. 梳理此部分过程后确认为这里异常,将相关正常流程整理如下;

3. 输入与输出

当前对于EGLImage的粗浅理解:

3.1 初始化

输入部分:

  • gen texture
  • create bo
  • get bofd
  • create EGLImage
  • bind texture & eglImage
for (int i = 0; i < TEXTURE_NUM; i++) {//1. gen textureGenTextures(1, &textureId[i]);
}/* create input buffers */
for (int i = 0; i < TEXTURE_NUM; i++) {//2. create bobos[i] = bo_create(textureFormat, textureWidth, textureHeight);...//3. get bofd    fds[i] = bo_get_fd(bos[i]);...ret = bo_map(bos[i], &vir_addrs[i]);size = bo_get_size(bos[i]);int stride = bo_get_stride(bos[i]);EGLint eglImageAttrs[] = {EGL_WIDTH, textureWidth,EGL_HEIGHT, textureHeight,EGL_LINUX_DRM_FOURCC_EXT, textureFormat,//4. bofd to eglImageEGL_DMA_BUF_PLANE0_FD_EXT, fds[i],EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,EGL_DMA_BUF_PLANE1_FD_EXT, fds[i],EGL_DMA_BUF_PLANE1_OFFSET_EXT, stride * textureHeight,EGL_DMA_BUF_PLANE1_PITCH_EXT, stride/2,EGL_DMA_BUF_PLANE2_FD_EXT, fds[i],EGL_DMA_BUF_PLANE2_OFFSET_EXT, stride * textureHeight * 5 / 4,EGL_DMA_BUF_PLANE2_PITCH_EXT, stride/2,EGL_NONE};// 5.  create EGLImage CreateEGLImage(eglDisplay, eglImageTarget, eglClientBuffer, eglImageAttrs, &eglImages[i]);CHECK_EGL_ERROR("CreateEGLImage");//6. bind textureglBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId[i]);CHECK_GL_ERROR("glBindTexture");//7. 关联eglImage & TextureglEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, eglImages[i]);CHECK_GL_ERROR("glEGLImageTargetTexture2DOES");//8. 设置纹理参数glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);CHECK_GL_ERROR("glTexParameteri");glBindTexture(GL_TEXTURE_EXTERNAL_OES, EGL_NONE);
}

输出部分,基本与输入一致,添加一个framebuffer的操作:

  • fbo
  • fbofd
  • eglImage
  • framebuffer
  • texture
for (int k = BUFFER_COUNT-1; 0 <= k; k--) {//1. create fbobos_out[k] = bo_create(eglImageFormat, BUFFER_WIDTH, BUFFER_HEIGHT);//2. get bofdfboFd[k] = bo_get_fd(bos_out[k]);fboStride[k] = bo_get_stride(bos_out[k]);EGLint eglImageAttrs[] = {EGL_WIDTH, eglImageWidth,EGL_HEIGHT, eglImageHeight,EGL_LINUX_DRM_FOURCC_EXT, eglImageFormat,//3. set fbofd to eglImageEGL_DMA_BUF_PLANE0_FD_EXT, fboFd[k],EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, EGL_DMA_BUF_PLANE0_PITCH_EXT, fboStride[k],EGL_NONE};//4. genfbobuffer & gentextureglGenFramebuffers(1, frameBufferId[k]);CHECK_GL_ERROR("glGenFramebuffers");glGenTextures(1, frameBufferTextureId[k]);CHECK_GL_ERROR("glGenTextures");//5. 创建eglImageCreateEGLImage(eglDisplay, eglImageTarget, eglClientBuffer, eglImageAttrs, &outEGLImages[k]);
}

3.2 render调用

  1. 输入部分填充bo关联的buffer
  2. bind texture
  3. bind framebuffer
  4. draw
BindFboBufferIdWithEGLImage(frameBufferId[index], frameBufferTextureId[index], outEGLImages[index]);
DrawAndWaitForFinish(frameBufferId[index], frameBufferTextureId[index], vPosition, textureId, vTexCoor, sTexture);
glBindFramebuffer(GL_FRAMEBUFFER, GL_NONE);GLint BindFboBufferIdWithEGLImage(GLuint frameBufferId, GLuint frameBufferTextureId, GLeglImageOES eglImage)
{//bind textureglBindTexture(GL_TEXTURE_EXTERNAL_OES, frameBufferTextureId);CHECK_GL_ERROR("glBindTexture");//关联 eglImageglEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, eglImage);CHECK_GL_ERROR("glEGLImageTargetTexture2DOES");glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);//bind framebufferglBindFramebuffer(GL_FRAMEBUFFER, frameBufferId);CHECK_GL_ERROR("glBindFramebuffer");// Attach frameBufferTextureId to frame buffer.glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_EXTERNAL_OES,frameBufferTextureId,0);GLint result = GL_NO_ERROR;// Check the frame buffers.GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);...return result;
}GLuint DrawAndWaitForFinish(GLuint frameBufferId, GLuint frameBufferTextureId, GLint vPosition, GLuint *textureId, GLint vTexCoor, GLint sTexture)
{glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);glUniform1i(sTexture, textureId[0]);//1. active textureglActiveTexture(GL_TEXTURE0 + textureId[0]);//2. bind textureglBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId[0]);glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);Draw(vPosition, vTexCoor, sTexture, LEFT);glBindTexture(GL_TEXTURE_EXTERNAL_OES, EGL_NONE);glFinish();return GL_NO_ERROR;
}

整理接口如下:

  • 输入部分

    • glActiveTexture
    • glBindTexture
  • 输出部分
    • glBindTexture
    • glEGLImageTargetTexture2DOES
    • glBindFramebuffer
    • glFramebufferTexture2D
  • draw
    • draw
    • glfinish

4. 附录

本小节简单总结了一次EGLImage的使用过程,用于后续参考

EGLImage使用记录相关推荐

  1. mysql建立联合索引,mysql建立唯一键,mysql如何解决重复记录联合索引

    在项目中,常常要用到联合唯一   在一些配置表中,一些列的组合成为一条记录.   比如,在游戏中,游戏的分区和用户id会形成一条记录.(比如,一个qq用户可以在艾欧尼亚.德玛西亚创建两个账号) 添加联 ...

  2. 实现 连续15签到记录_MySQL和Redis实现用户签到,你喜欢怎么实现?

    现在的网站和app开发中,签到是一个很常见的功能 如微博签到送积分,签到排行榜 微博签到 如移动app ,签到送流量等活动, 移动app签到 用户签到是提高用户粘性的有效手段,用的好能事半功倍! 下面 ...

  3. 记录一次http请求失败的问题分析

    问题背景 当前我有一个基于Flask编写的Restful服务,由于业务的需求,我需要将该服务打包成docker 镜像进行离线部署,原始服务的端口是在6661端口进行开启,为了区分,在docker中启动 ...

  4. Pytorch学习记录-torchtext和Pytorch的实例( 使用神经网络训练Seq2Seq代码)

    Pytorch学习记录-torchtext和Pytorch的实例1 0. PyTorch Seq2Seq项目介绍 1. 使用神经网络训练Seq2Seq 1.1 简介,对论文中公式的解读 1.2 数据预 ...

  5. LeetCode简单题之学生出勤记录 I

    题目 给你一个字符串 s 表示一个学生的出勤记录,其中的每个字符用来标记当天的出勤情况(缺勤.迟到.到场).记录中只含下面三种字符: 'A':Absent,缺勤 'L':Late,迟到 'P':Pre ...

  6. 关于TVM的点滴记录

    关于TVM的点滴记录

  7. MySql数据库Update批量更新与批量更新多条记录的不同值实现方法

    批量更新 mysql更新语句很简单,更新一条数据的某个字段,一般这样写: UPDATE mytable SET myfield = 'value' WHERE other_field = 'other ...

  8. 记录篇,自己在项目中使用过的。

    图片选择器,6.0已经适配过,类似qq空间上传 点击打开链接_胡小牧记录 下面是效果图: PictureSelector PhotoPicker 类似qq空间发布心情. 点击打开链接 BubbleSe ...

  9. HTML5与CSS3权威指南之CSS3学习记录

    title: HTML5与CSS3权威指南之CSS3学习记录 toc: true date: 2018-10-14 00:06:09 学习资料--<HTML5与CSS3权威指南>(第3版) ...

  10. 生产环境项目问题记录系列(一):一次循环数据库拖垮服务器问题

    心血来潮,决定时不时记录下生产项目中遇到的问题. 今天的问题是这样的,昨天晚上大约7点左右,服务器报警,CPU暴涨.通过监控页面发现某个订阅MQ的服务接口有400多个超过10秒的请求(正常只有100- ...

最新文章

  1. 如何看待179所高校新增 AI 本科专业,研究生扩招也瞄准 AI?
  2. 如何从开发人员走向架构师
  3. SVN不是配置管理系统
  4. Ocrad.js – JS 实现 OCR 光学字符识别
  5. java输入一行_用java编写从标准输入读入一行字符串,打印出其中所有的数字
  6. 程序员必修课--sql思维举重训练
  7. InfoPath基础应用教程-2 表单中的规则(1)
  8. 计算机启动时默认输入法设置,电脑开机输入法设置 开机默认输入法设置教程...
  9. 数据结构实验:数制转换
  10. 6.2 栅格数据矢量化
  11. Python爬虫理论 | (2) 网络请求与响应
  12. php程序员后期发展前景,浅谈php程序员发展前景(一)
  13. 阿里云服务器:配置 Docker 的 镜像加速器
  14. Win10连接NAS网络存储器失败解决方法
  15. 华为笔记本电脑home键和end键快捷方式
  16. Dubbo 线上 Thread pool is EXHAUSTED 问题跟踪
  17. three.js之摄像机
  18. 【黑苹果装机实践】从硬件选择到系统安装
  19. 抢红包算法--四种抢红包算法对比(附源码)
  20. 平安科技寿险金服面试

热门文章

  1. [模板]匈牙利算法(二分图匹配)
  2. 比较有深度的博客收藏
  3. phpcms v9二次开发之模型类的应用(2)
  4. msgpack使用 php_如何使用msgpack进行读写?
  5. python画图代码讲解_python画图例子代码
  6. cloudera search1.0.0环境搭建(2):利用flume-ng的MorphlineSolrSink实现近实时(NRT)搜索
  7. pycharm 快捷键设置为eclipse一样
  8. sh与bash中的export语法的区别
  9. jQuery 选择器 (基础恶补之二)
  10. SQLLDR载数加速,优化参数