• 硬件加速绘制基础知识


    目录

    前置知识:

    OPENGL 和OPENGL ELS的关系

    EGLSurface和EGLContext关系

    上下文保存着状态集,什么是状态集?

    Thread和EGLSurface,EGLContext关系

    具体api

    Display和EGL关系

    Surface和EGLSurface的关系

    大致初始化流程

    绘制过程

    参考文章


    前置知识:

    OPENGL 和OPENGL ELS的关系

    OPENGL 是统一不同厂商GPU绘制的接口,通过GPU的计算得到一张图片(内存中的一块Buffer保存着信息)

    openGl是一个操作GPU的接口,但是具体的图片信息需要一块窗口来呈现出来,这个窗口就是OPENGL EGL

    OPENGL EGL是OpenGl 和Native底层之间的视图接口。EGL可以获取手机配置(会根据不同Display屏幕的情况创建EGLConfig)创建出一个surface(默认BufferQuene的大小是屏幕分辨率乘以像素个数)和用于存放OPEGL状态集(OPENGL信息是传入的图元,顶点等信息,OPENGL状态是如何进行测试混合片段阶段的处理)的context。OPENGL生成图片数据(具体流程见图形学的图元处理部分,其完全由GPU处理)后保存到EGL创建的surface的buffer中,通过EGL的接口显示到窗口上

    一句话总结:EGL获取Buffer用于和屏幕打交道,buffer的具体图像数据由OpenGl往里面填充

    EGLSurface和EGLContext关系

    EGLSurface:EGL 是用于在Surface绘制buffer 提供给 OpenGL ES 进行绘制的

    EGLContext: EGL 还会根据格式生成一块 context,context 也是一块 buffer用于保存OpenGl的状态集

    上下文保存着状态集,什么是状态集?

    这些状态变量描述当前OpenGl应该如何运行,比如是绘制线段还是三角形,可以 通过改变上下文状态来改变OpenGl的绘制行为。

    状态设置函数就是用来改变上下文的,而OpenGl是根据上下文进行渲染的。

    surface 需要与 context 进行搭配使用, context 中是可以保存 OpenGL ES 状态集信息的,所以 context 就可以使用自己内部保存的信息往 surface 上进行绘制

    Thread和EGLSurface,EGLContext关系

    由于存在多个EGLSurface和多个Context,但是一个进程同一时间只能启动有相同格式的一块 surface 和一块对应于 OpenGL ES 的 context,一块 context 同时也只能被一个进程启动。,有时候也会设计到多线程操作,每个 thread 可以拥有自己的 surface 和 context,但是也要满足刚才的限制 : 一个 thread 同一时间只能启动有相同格式的 一块 surface 和一块对应于 OpenGL ES 的 context,一块 context 同时也只能被一 个 thread 启动,所以我们需要设置绑定这个Thread对应渲染的surface和context

    具体api

    通过eglMakeCurrent可以切换当前线程绑定的surface和context,接着通过OPENGL的接口设置context的状态,使用context的状态对surface进行绘制, 由于Surface是双缓冲,所以准备好数据之后需要调用egl的swapBuffer置换缓存,让Opengl去渲染,自己在继续生成下一个buffer的数据

    Display和EGL关系

    EGL有很多版本,不同设备也有多个Display通过displayID去区分(典型的场景是车机上的多联屏);不同的Display支持的版本不同其屏幕配置也可能不同这些通过eglgetConfig API 获取该块屏幕的配置信息,所以EGL初始化的过程和使用的过程需要指定对应的Display,初始化过程根据支持的opengl的版本初始化不同版本的opengl。使用过程比如创建EGLSurface和EGLContext需要指定display

    Surface和EGLSurface的关系

    Surface没有直接和OPENGL操作的接口其是一个承载的窗口,需要通过EGLSurface和Opengl对接绘制添加EGL的功能支持

    大致初始化流程

    经过上面的描述,来总结下大致流程:

    • 获取EGLDisplay
    • EGLDisplay初始化,通过Display获取EGLConfig
    • 根据Config信息初始化所支持的OPENGL版本
    • EGL环境初始化结束,接下来通过EGL获取EGLSurface和对应的EGLContext
    • 设置当前线程绑定的EGLSurface和EGLContext(与线程绑定)

    绘制过程

    对这篇文章又有了新的理解,可以翻看,下文过程中也会进行对应颜色区间的补充说明 使用 GPU 渲染模式分析工具进行分析

    • perfromTravle中申请内存,其实就是Surface的BufferQuene(dequeBuffer设计BufferQuene的生命周期)
    • 递归遍历RenderNode获取所有的DrawOp树,也叫DisplayList
    • 同步Cpu的DisplayList到GPU(对应同步上传,等待CPU将数据同步至GPU;不像软件绘制那样直接使用的匿名共享内存,这部分存在一个时间差,)
    • 转换DrawOp树为对应的glXXX函数,将命令同步至GPU,让GPU绘制(对应于向OpenGl发起渲染流程
    • swapBuffer提交缓冲区并申请下一块Buffer(对应于交换缓冲区依赖于GPU提交的数据如果SF对应合成的数据还没有渲染好则会阻塞等待GPU渲染完成),异步请求SF进行合成。

    只有EGL才可以对接屏幕显示,OPENGL只是操作GOU进行绘制图像)

    参考文章

     OPENGL ES 2.0 知识串讲(2)――EGL详解

    OpenGL ES: (3) EGL、EGL绘图的基本步骤、EGLSurface、ANativeWindow 

    创建2个egl

  • 相关阅读:
    在原生HTML页面发起axios请求
    【LeetCode热题100】--148.排序链表
    香港主机免备案吗?为什么不用备案?
    PCA数学原理
    PostgreSQL 如果想知道表中某个条件查询条件在索引中效率 ?
    审计智能合约的成本是多少?如何审计智能合约?
    软件工程 测试二
    PlotNeuralNet绘制卷积神经网络结构图
    配置网卡多队列
    java三层架构/表现层-业务层-持久层
  • 原文地址:https://blog.csdn.net/m0_65909361/article/details/134069024