关闭

Android5.1中surface和CpuConsumer下生产者和消费者间的处理框架简述

520人阅读 评论(0) 收藏 举报
分类:

前沿:

如果对SurfaceFlinger架构的工作原理较为熟悉的话,本文阅读起来会相对容易些。之所以撰写本文是因为在阅读Camera HAL3的实现过程中大量的出现了类似与SurfaceFlinger的工作模式。本文将以CallbackProcessor模块的为入口,和大家进行分享。



1 Preview模块Surface与SurfaceFlinger的基础知识

    开发过Android Camera模块的人,基本都应该熟悉实时采集的视频如果要显示到手机屏上,对应的Framework层就应该构建一个Surface对象,这对所有Android版本都是通用的。该Surface本质是一个在APP端的ANativeWindow,是需要从SurfaceFlinger端的Gralloc模块获取Buffer的,然后填充帧图像数据并送显示的过程。详细内容可以参考之前的专栏我心所向之Android4.2关于SurfaceFlinger相关的内容。

    由于目前Android系统版本升级过快,在5.0以上的版本中SurfaceFlinger部分框架发生了变化(目前还没有深入去研读过),了解到的是:

  一方面他去掉了SurfaceTexture/SurfaceTextureClient等内容,增强了Surface的功能。

  另一方面BufferQueue的使用也更加简单与明了,Producer与Consumer的关系也更加明确,BufferQueue不再是以前的消费者角色,转而成为ProducerBufferQueue和Consumer相互关联的桥梁。

 此外,如果你在深入的话,会了解到Gralloc模块中非framebuff的缓存管理与共享不在是那个Ashmem匿名共享内存,而是出现了一种新的内存管理机制/dev/ION/,后面会和大家分享他部分的工作机制。

对于SurfaceFlinger与Camera Preview Surface而言,ANativeWindow作为两者的共性负责管理和维护Buffer的创建与共享,在SurfaceFlinger端ANativeWindow创建buffer,在Surface侧通过dequeuebuffer获取buffer handle到本地进行共享,在填充完数据后通过queuebuffer告诉SurfaceFlinger当前buffer可用,这样就形成了一个buffer生产与消费的关系,基于这种原理我们在Camera3Device中除了看到正常的Preview Surface之外还看到了其他模块中出现了Surface的创建。


2 CallbackProcessor::updateStream() 创建Surface

  1. sp<IGraphicBufferProducer> producer;  
  2.     sp<IGraphicBufferConsumer> consumer;  
  3.     BufferQueue::createBufferQueue(&producer, &consumer);//BufferQueueProducer与BufferQueueConsumer  
  4.     mCallbackConsumer = new CpuConsumer(consumer, kCallbackHeapCount);  
  5.     mCallbackConsumer->setFrameAvailableListener(this);//当前CallbackProcessor继承于CpuConsumer::FrameAvailableListener  
  6.     mCallbackConsumer->setName(String8("Camera2Client::CallbackConsumer"));  
  7.     mCallbackWindow = new Surface(producer);//用于queue操作,这里直接进行本地的buffer操作  
上述代码看上去很简单,但就是他最终形成了一个bufferstream Product和Consumer的处理,这种方式也为Camera2Client下出现多路stream,多路数据流存在奠定了基础,下面我们来简单的描述他的工作机制。


2.1 BufferQueue::createBufferQueue

  1. void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,  
  2.         sp<IGraphicBufferConsumer>* outConsumer,  
  3.         const sp<IGraphicBufferAlloc>& allocator) {  
  4.     LOG_ALWAYS_FATAL_IF(outProducer == NULL,  
  5.             "BufferQueue: outProducer must not be NULL");  
  6.     LOG_ALWAYS_FATAL_IF(outConsumer == NULL,  
  7.             "BufferQueue: outConsumer must not be NULL");  
  8.   
  9.     sp<BufferQueueCore> core(new BufferQueueCore(allocator));  
  10.     LOG_ALWAYS_FATAL_IF(core == NULL,  
  11.             "BufferQueue: failed to create BufferQueueCore");  
  12.   
  13.     sp<IGraphicBufferProducer> producer(new BufferQueueProducer(core));//本地Bn的BufferQueueProducer  
  14.     LOG_ALWAYS_FATAL_IF(producer == NULL,  
  15.             "BufferQueue: failed to create BufferQueueProducer");  
  16.   
  17.     sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core));//本地Bn的BufferQueueConsumer  
  18.     LOG_ALWAYS_FATAL_IF(consumer == NULL,  
  19.             "BufferQueue: failed to create BufferQueueConsumer");  
  20.   
  21.     *outProducer = producer;  
  22.     *outConsumer = consumer;  
  23. }  
当前Android5.1版本中可以看到BufferQueue已经改变了原先的角色,成为了一个用于创建一组操作BufferQueue的接口,实现了BufferQueueProducer与BufferQueueConsumer的创建。更本质说现在BufferQueue的工作量已经很小,基本由Surface来全盘操作。这里通过BufferQueueCore会将BufferQueueProducer与BufferQueueConsumer绑定在一起,BufferQueueProducer可以说是替代了旧版本Android4.2中的SurfaceTextureClient,而BufferQueueConsumer则直接是SurfaceTexture以及BufferQueue的替代者。下图是在Android4.2.2中Surface和SurfaceFlinger间基于Bn/BpSurfaceTexture的多进程间buffer的queue操作机制。


2.2 CpuConsumer

    在2.1中本质上是创建了BufferQueueProducer和BufferQueueConsumer,一般是成对出现。

这个CpuConsumer的地位本质是和SurfaceFlinger是一样的,主要角色就是来处理已经带有帧数据的buffer块,所以整个的处理机制都是类型的,其中两者均为继承一个ConsumerBase类,用于实现对buffer块的处理。

  1. CpuConsumer::CpuConsumer(const sp<IGraphicBufferConsumer>& bq,  
  2.         uint32_t maxLockedBuffers, bool controlledByApp) :  
  3.     ConsumerBase(bq, controlledByApp),  
  4.     mMaxLockedBuffers(maxLockedBuffers),  
  5.     mCurrentLockedBuffers(0)  
  6. {  
  7.     // Create tracking entries for locked buffers  
  8.     mAcquiredBuffers.insertAt(0, maxLockedBuffers);  
  9.   
  10.     mConsumer->setConsumerUsageBits(GRALLOC_USAGE_SW_READ_OFTEN);  
  11.     mConsumer->setMaxAcquiredBufferCount(maxLockedBuffers);  
  12. }  


2.3 mCallbackConsumer->setFrameAvailableListener(this)

    这里所完成的过程是需要Consumer去将一个listener加入到Productor端去,便于在帧数据可用时,可以监听到并告知Consumer去做数据的处理,Product需要在数据可用时触发这个listener的onFrameAvailable,从而让数据从Productor转到Consumer则,数据处理应该是在同一进程的而不是跨进程。

    如果作为Consumer如CPUConsumer没有使用setFrameAvailableListener将自己加入到listener中去,会由ConsumerBase的接口onFrameAvailable来替代完成。

2.4 mCallbackWindow = new Surface(producer)
    这里是建立一个Surface,也就是类型于Preview模式下创建的Surface,两者的本质是一样的。在Android5.1中,Surface已经拥有了绝对的控制权,Preview模式下的Surface是跨进程的和SF进行交互,故构造函数传入的sp<IGraphicBufferProducer>& bufferProducer参数一般是一个BufferQueue中BufferQueueProducer侧匿名的binder BpGraphicBufferProducer。对于CPUConsumer而言,两者是处于同一进程之中的,Surface主要行驶如下的操作,而在旧版本中这些主要由SurfaceTextureClient来管理的:

  1. ANativeWindow::setSwapInterval  = hook_setSwapInterval;  
  2.  ANativeWindow::dequeueBuffer    = hook_dequeueBuffer;  
  3.  ANativeWindow::cancelBuffer     = hook_cancelBuffer;  
  4.  ANativeWindow::queueBuffer      = hook_queueBuffer;  
  5.  ANativeWindow::query            = hook_query;  
  6.  ANativeWindow::perform          = hook_perform;  
  7.   
  8.  ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;  
  9.  ANativeWindow::cancelBuffer_DEPRECATED  = hook_cancelBuffer_DEPRECATED;  
  10.  ANativeWindow::lockBuffer_DEPRECATED    = hook_lockBuffer_DEPRECATED;  
  11.  ANativeWindow::queueBuffer_DEPRECATED   = hook_queueBuffer_DEPRECATED;  
    一般对Buffer的操作都先是基于Struct ANativeWindow这个本地的窗口类来处理,再是通过hook到实际的surface再交由GraphicBufferProducer来完成的。


3 Android5.1下Surface的queuebuffer操作逻辑


对比上一图可知,当前CPUConsumer模式下,从queuebuffer的处理过程来看更加体现出Productor和Consumer这种设计模式,整个架构代码看起来也更明了,这也是谷歌不断升级系统去冗存精的道理吧。整个用户在调用这种逻辑是,只需几句代码就可以获得对一个buffer块的读与写的操作接口,具体后续在分析Camera HAL3的数据流时可以很深刻的看到。

    总的来说Surface在Camera3Device的架构下,与HAL3相组合是充当了消费者,与CPUCOnsumer或者Surfaceflinger来说就是生产者。或者说surface充当了buffer信息的传输与过渡。


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:212053次
    • 积分:2517
    • 等级:
    • 排名:第15188名
    • 原创:7篇
    • 转载:212篇
    • 译文:0篇
    • 评论:8条
    最新评论