Android显示系统(13)- 向SurfaceFlinger提交Buffer

Android显示系统(01)- 架构分析
Android显示系统(02)- OpenGL ES - 概述
Android显示系统(03)- OpenGL ES - GLSurfaceView的使用
Android显示系统(04)- OpenGL ES - Shader绘制三角形
Android显示系统(05)- OpenGL ES - Shader绘制三角形(使用glsl文件)
Android显示系统(06)- OpenGL ES - VBO和EBO和VAO
Android显示系统(07)- OpenGL ES - 纹理Texture
Android显示系统(08)- OpenGL ES - 图片拉伸
Android显示系统(09)- SurfaceFlinger的使用
Android显示系统(10)- SurfaceFlinger内部结构
Android显示系统(11)- 向SurfaceFlinger申请Surface
Android显示系统(12)- 向SurfaceFlinger申请Buffer
Android显示系统(13)- 向SurfaceFlinger提交Buffer

一、前言:

前面获取了Surface,并且为Surface申请了Buffer,然后通过EGL的往这Buffer里头渲染数据,完成之后,我们就需要去提交这个Buffer。

二、回顾流程图:

在这里插入图片描述

  1. 首先,SF会创建一个Client代表着App;
  2. App调用createSurface 得到一个SurfaceControl,同时,SF会创建一个Layer,代表APP端的SurfaceControl
  3. 同时,SF端的Layer会有生产者和消费者,两者都有成员变量mCore(代表BufferQueueCore)和mSlots数组,而App端会有一个生产者代理,代表SF那边的Layer中的生产者。(中间通过binder通信)
  4. App端的SurfaceControl可以通过getSurface获得Surface,Surface当中也有mSlots和生产者代理。
  5. App端想要往Surface里面填充数据,首先得通过lock申请buffer,通过dequeueBuffer返回一个buffer,如果SF侧分配的buffer已经用完了,就通过Gralloc模块向匿名内存Ashmem申请一个buffer,并且填入自己的mSlots当中,同时返回给APP,需要重新分配Buffer,APP侧会重新调用requestBuffer让SF侧重新关联这个Buffer,然后进行mmap,并且将fd返回给APP;
  6. App收到binder过来的fd之后(其实binder转换成fd’了),进行mmap(fd')得到虚拟地址vaddr,然后填入自己的mSlots当中;
  7. 最后App填充数据到vaddr当中之后,通过unlockAndPost提交给SF。

三、unlockAndPost:

3.1、总体思路:

  • Surface->lock被调用获取Buffer之后,生产者的dequeueBuffer调用。
  • 获得buffer之后,App侧通过Surface->unlockAndPost提交填充数据的Buffer,也就是调用queueBuffer。
  • 那么queueBuffer调用之后,主要做两件事入队列,并且通知消费者取数据,通知顺序是:
    • 通知Layer的消费者;
    • 通知SurfaceFlinger;

3.2、代码走读:

入口在这儿:

status_t Surface::unlockAndPost()
{
   
   
    if (mLockedBuffer == nullptr) {
   
   
        ALOGE("Surface::unlockAndPost failed, no locked buffer");
        return INVALID_OPERATION;
    }

    int fd = -1;
    // 解锁当前被锁的缓冲区(异步)
    status_t err = mLockedBuffer->unlockAsync(&fd);
    ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
    // 提交缓冲区
    err = queueBuffer(mLockedBuffer.get(), fd);
    ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)",
            mLockedBuffer->handle, strerror(-err));

    mPostedBuffer = mLockedBuffer;
    mLockedBuffer = nullptr;
    return err;
}

3.3、Layer的消费者:

1)为Layer创建消费者:

看代码之前,我们先看下这个Layer第一次被引用时候:

void BufferQueueLayer::onFirstRef() {
   
   
    BufferLayer::onFirstRef();

    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
    sp<IGraphicBufferProducer> producer;
    sp<IGraphicBufferConsumer> consumer;
    // 创建BufferQueue的时候,里面会创建生产者和消费者
    BufferQueue::createBufferQueue(&producer, &consumer, true);
    // 将消费者做一次封装
    mProducer = new MonitoredProducer(producer, mFlinger, this);
    {
   
   
        // Grab the SF state lock during this since it's the only safe way to access RenderEngine
        // 同样,将生产者做一次封装
        Mutex::Autolock lock(mFlinger-><
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值