pr无法创建图像缓冲区_kOS(11):SurfaceFlinger(3/3) 处理图像

术语

  • hwc-hal。HAL中的hwcomposer模块。专门命名的目的是为和surfaceflinger中的HWComposer类做区分
  • workList。hwc-hal中的接口函数prepare和set,都须要个“hwc_display_contents_1_t**”类型的参数,称这参数为workList。workList中的一个单元对应一个显示器。一个显示器有多个图层,hwc_layer_1_t表示一个图层,其中buffer_handle_t类型的handle指向了存储该层数据的图形缓冲区。
  • opengl合成。向hwc-hal调用set时,hwc-hal能接受的两种合成方法之一,有的地方称GPU合成、Client合成。其合成方法是,将各个Layer的内容用GPU渲染到暂存缓冲区中,最后将暂存缓冲区传送到显示硬件。这个暂存缓冲区称为fbTarget,每个显示设备有各自的fbTarget。这种合成方法目前使用的是opengles技术。
  • hwc硬件合成。向hwc-hal调用set时,hwc-hal接受的两种合成方法之一。hwc-hal用专门的硬件合成器进行合成,它的合成能力就取决于硬件的实现。其合成方法是将各个Layer的数据全部传给显示硬件,并告知它从不同的缓冲区读取屏幕不同部分的数据。
  • fbTarget。opengl合成时,将各个Layer的内容用GPU渲染到暂存缓冲区中,最后将暂存缓冲区传送到显示硬件,这个暂存缓冲区称为fbTarget,每个显示设备有各自的fbTarget。fbTarget的类型是hwc_layer_1_t。

SurfaceFlinger接收Vsync目的是为处理图像,处理图像可分为两部分,分别对应收到INVALIDATE、REFRESH消息后的行为,一是各图层从各自的Buffer Queue取出新到Buffer,二是合成各图层的图像,形成workList,把它送到hwc-hal。

surfaceflinger如何处理图像,网上不乏函数注解详细的文章,像“Android P图形显示系统(六) SurfaceFlinger合成流程(一)[1]”、“Android P图形显示系统(七) SurfaceFlinger合成流程(二)[2]“、Android P图形显示系统(八) SurfaceFlinger合成流程(三)[3]”。它们是Android P,想看低版本的,像Android 7.1,有“显示HWC合成(hwc_display_contents_1_t,hwc_layer_1_t数据结构关系)[4]”、“Android6.0 图像合成过程详解(二) doComposition函数[5]”。

这里不做具体函数注解了,给出用图描述的图像处理流程。图1分三部分,上半部是函数调用关系。左下角是“图像数据(buffer_handle_t handle)处理流程”,小结要得到各个hwc_layer_1的handle,大概分哪些步骤。右下角是“BufferItem中一些字段的流动过程”。

本文讨论的图像流程从BufferQueueProducer::queueBuffer开始。

a6e61e41e7b5647f5833aca9edf56e10.png
图1 surfacefinger处理图像

注1。Layer::onFrameAvailable

新收到的item放入mQueueItems。放入后mLastFrameNumberReceived指示此item的mFrameNumber。由于mFrameNumber肯定是连续的,所以onFrameAvailable的下一item的mFrameNumber必须是mLastFrameNumberReceived+1。疑问:1)mQueuedFrames,mQueueItems的长度,为什么不用mQueueItems.size()?2)onFrameAvailable到达的item的mFrameNumber可能是乱序的?

注2。SurfaceFlinger::handleMessageInvalidate

如果此次有Layer要显示,并且用latchBuffer成功取出了buffer,返回true。由于有新数据,有Layer极可能要脏了,意味着须重新合成图像,handleMessageInvalidate会紧接调用SurfaceFlinger::signalRefresh。此时不须要下一个Vsync就能让SurfaceFlinger收到REFRESH,从而调用handleMessageRefresh。

注3。SurfaceFlingerConsumer::updateTexImage

输出[OUT]参数queuedBuffer。此值来自于刚从Buffer Queue取出item的mQueuedBuffer字段。一旦是true,调用它的latchBuffer会把相对应的BufferItem从Layer.mQueueItems删除

注4。opengl合成

  1. 创建RenderEngine。RenderEngine 是在SurfaceFlinger初始化时,创建的。
  2. 各DisplayDevice创建私有EGLSurface。在RenderEngine创建时,初始化了EGLDisplay、EGLConfig和EGLContext。这些都是所有DisplayDevice共用的,但是EGLSurface是每个DisplayDevice自己的。在DisplayDevice创建时,创建对应的EGLSurface。通过ANativeWindow,Surface就和DisplayDevice的BufferQueue建立了联系。
  3. 各Layer创建私有texture。Layer创建时,会调用glGenTextures创建一个texture。mTexName是标识该texture的纹理ID。
  4. Layer合成(1/3)切换私有EGLSurface为当前EGL窗口。合成是在SurfaceFlinger的doComposeSurfaces中进行,首先DisplayDevice::makeCurrent。每个DisplayDevice有自己的EGLSurface,所以,每个DisplayDevice做具体合成时,需要给RenderEngine指定EGLSurface,视窗,投影矩阵等,告诉RenderEngine合成到哪个EGLSurface上。切换当前EGL窗口的函数是eglMakeCurrent。
  5. Layer合成(2/3)绑定Texture。合成时,每个DisplayDevice的每个Layer都合为绘制到DisplayDevice对应的EGLSurface上。Layer首先须要把图形缓冲区数据如何绑定到纹理。GLConsumer::bindTextureImageLocked执行和绑定相关的绝大部分工作。1)创建EGLImageKHR类型的mEglImage。在该Layer私有的GLConsumer中,mCurrentTextureImage->createIfNeeded创建出mEglImage。具体用的api是eglCreateImageKHR。调用eglCreateImageKHR时须要个类型“EGLClientBuffer”的参数,它来自于GraphicBuffer的getNativeBuffer()方法。2)加载mEglImage数据到mTexName这个纹理。
  6. Layer合成(3/3)用opengles绘制。主要通过各Layer分别调用drawWithOpenGL函数完成。
  7. 交换Buffer。eglSwapBuffers 将交换GPU处理的Buffer,处理完的Buffer,也就是包含Layer合成数据后的Buffer将被queue到BufferQueue中。
调用eglCreateImageKHR创建mEglImage
------
EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
在这是里参数buffer来自于GraphicBuffer的getNativeBuffer()方法。
EGLClientBuffer cbuf = static_cast<EGLClientBuffer>(graphicBuffer->getNativeBuffer();

加载mEglImage数据到mTexName这个纹理
------
// 把mTexName作为mTextTarget这个纹理目标的纹理
glBindTexture(mTexTarget, mTexName);
// 加载mEglImage数据到mTexName这个纹理,相当于一般情况下的glTexImage2D的效果。
glEGLImageTargetTexture2DOES(texTarget, static_cast<GLeglImageOES>(mEglImage));

参考

  1. ^Android P图形显示系统(六) SurfaceFlinger合成流程(一) https://www.jianshu.com/p/fa115146949f
  2. ^Android P图形显示系统(七) SurfaceFlinger合成流程(二) https://www.jianshu.com/p/fd16dcb4dfb6
  3. ^Android P图形显示系统(八) SurfaceFlinger合成流程(三) https://www.jianshu.com/p/cf4455021fd5
  4. ^显示HWC合成(hwc_display_contents_1_t,hwc_layer_1_t数据结构关系) https://blog.csdn.net/kc58236582/article/details/70146317
  5. ^Android6.0 图像合成过程详解(二) doComposition函数 https://blog.csdn.net/kc58236582/article/details/52868973
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值