• Android ISurface PostBuffer 处理流程


    1 ISurface 的Create

        想了解surface的create 和surfaceflinger 可参考这篇文章,比较详细:

    http://blog.csdn.net/yili_xie/archive/2009/11/12/4803527.aspx

        Android 起步比较早的大牛们挺多,我现在只能一步步踏着革命先烈的后尘。

        每个相应的应用都会有个相应的ISurface 的对象被set进来,例如camera 的cameraService,opencore的MIO。我们只需要知道这么用就可以了。


    2 App调用流程。

        看过code就知道,这个调用是很简单的。

        先初始化memory

    1. mFrameHeap =  new  MemoryHeapBase(frameSize * kBufferCount);  
    2. if  (mFrameHeap->heapID() < 0)  
    3. {  
    4.     LOGE("Error creating frame buffer heap" );  
    5.     return   false ;  
    6. }  

        把memory 注册到ISurface上

    1. ISurface::BufferHeap buffers(displayWidth, displayHeight,  
    2.                              displayWidth, displayHeight, PIXEL_FORMAT_RGB_565, mFrameHeap);  
    3. mSurface->registerBuffers(buffers);  

     调用postBuffer 即可

       mSurface->postBuffer(mFrameBuffers[mFrameBufferIndex]);

       这里摘抄的是android_surface_output.cpp中的code,  cameraService中的和它没什么区别。

       在这里我们重点要讨论的是postBuffer的处理过程。


    3 postBuffer 处理过程。(default,我们的系统中不支持overlay)

        在ISurface.cpp中实现了两个public BpInterface<ISurface>的类:BpSurface BnSurface

        BpSurface 是使用Binder实现服务端的调用。

        BnSurface 是surfaceFlinger 向回的调用。

        我们写 mSurface->postBuffer实际上调用的是BpSurface::postBuffer

        它的实现是:

        remote()->transact(POST_BUFFER, data, &reply, IBinder::FLAG_ONEWAY);

        (Binder的机制我还不是很清楚)从developer的网站上有对 binder调用这样的注释:

    The key IBinder API is transact() matched by Binder.onTransact(). These methods allow you to send a call to an IBinder object and receive a call coming in to a Binder object, respectively. This transaction API is synchronous, such that a call to transact() does not return until the target has returned from Binder.onTransact(); this is the expected behavior when calling an object that exists in the local process, and the underlying inter-process communication (IPC) mechanism ensures that these same semantics apply when going across processes.

        也就是说整个binder调用过程是同步的。

        之后回调到:BnSurface::onTransact

    1. case  POST_BUFFER: {  
    2.     CHECK_INTERFACE(ISurface, data, reply);  
    3.     ssize_t offset = data.readInt32();  
    4.     postBuffer(offset);  
    5.     return  NO_ERROR;  
    6. break ;  

        这里就调用到了LayerBuffer 中的postBuffer :LayerBuffer::BufferSource::postBuffer(ssize_t offset)

        关于surfaceflinger中这几个layer的概念,也可以参考一醉千年的博客,我自己暂时还不是很清晰。

    1. if  (buffers.heap != 0) {  
    2.     buffer = new  LayerBuffer::Buffer(buffers, offset);  
    3.     if  (buffer->getStatus() != NO_ERROR)  
    4.         buffer.clear();  
    5.     setBuffer(buffer);  
    6.     mLayer.invalidate();  
    7. }  

     
         这里的setBuffer(buffer);会对你要post的buffer做一个记录。然后通过LayerBase::invalidate()调用mFlinger->signalEvent()

    触发一个事件,就返回了。

         而SurfaceFlinger 会再SurfaceFlinger::threadLoop()中处理这个事件。最终还会调用到 LayerBuffer::BufferSource::onDraw函数。在layer中实现surface中的数据的合成处理等.

        回到我们对postBuffer的调用,可发现这是两个进程的处理。client进程调用后只是通知surfaceflinger我要显示一个 surface,而surfaceflinger什么时候去处理,什么时候真正去使用这块memory,client并不知道。因此binder虽是同步 的调用,而buffer却是异步的处理。我自己做个试验,在postBuffer之后立刻去修改post的这块memory的内容,最终发现应该显示的内 容被改掉了。而postBuffer之后睡个40ms,屏幕就没有花,说明在修改memory之前surfaceflinger已经完成了这个 buffer的draw工作。

    http://blog.csdn.net/saphy/archive/2010/07/01/5707413.aspx

  • 相关阅读:
    三大家族的作用和区别
    正则表达式
    Math的方法
    数组API方法
    面向对象方法
    数组的常用方法
    对象和数组的遍历方法
    js运算符(运算符的结合性)
    i++和++i的运算符
    flex
  • 原文地址:https://www.cnblogs.com/eustoma/p/2415842.html
Copyright © 2020-2023  润新知