美文网首页
SurfaceFlinger

SurfaceFlinger

作者: Wi1ls努力努力再努力 | 来源:发表于2019-09-26 17:23 被阅读0次

    Android中,在 HAL 层抽象了 Gralloc 模块,封装了对帧缓冲区的访问操作。加载 Gralloc 模块后,获得一个 gralloc 设备和 fb 设备。通过 gralloc,用户空间申请分配一块图形缓冲区,并且映射到应用程序的地址空间,以便写入想要绘制的内容。随后用户空间程序通过 fb 设备将绘制好的图形缓冲区渲染到帧缓冲区,即显示屏中。当不需要这一块图形缓冲区时,通过 gralloc 设备释放,同时解除映射。
    在 Linux 中,一个显示屏被抽象为一个帧缓冲区,注册到 FrameBuffer 中。


    • HWComposer:信号源。
      产生 VSync 信号,可以由硬件产生,也可以选择软件模拟产生。在 SurfaceFlinger->readyToRun( )的实例化。关键点,SurfaceFinger 派生自 HWComposer::EventHandler并且成为 HWComposer 的信号处理者。当 HWComposer产生 VSync 信号时,会回调SurfaceFlinger->onVSyncReceived( ),后者会将会回调 EventThread->onVSyncReceived( )
    • EventThread:是一个事件线程,内部通过 threadLoop( ) 不断得监听事件。当第三方程序调用 EventThread::createEventConnection( )可以认为是希望与 EventThread 产生一个连接,EventThread 返回一个 Connection 对象,在 Connection 对象实例化时,会在 onFirstRef()中调用 EventThread::registerDisplayEventConnection( )将自身加入监听列表。
    • MessageQueue mEventQueue:可以认为是消息队列,同时内部提供了 Looper 和 Handler 进行消息处理。在 SurfaceFlinger onFirstRef( )的时候进行 init( )。
    • SurfaceFlinger 会通过 MessageQueue::setEventThread(const sp<EventThread>& eventThread)将 MessageQueue 与 EventThread 产生联系
    void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
    {
      mEventThread = eventThread;
      mEvents = eventThread->createEventConnection( );
      mEventTube = mEvents->getDataChannel( );
      mLooper->addFd(mEventTube->getFd( ), 0, ALOOPER_EVENT_INPIT, MessageQueue::cb_eventReceiver,this);
    }
    

    这样,MessageQueue 就监听了这个 BitTube mEventTube。当 EventThread 收到事件时,会收集所有有效的注册在案的 Connection,对 Connections 进行遍历,通过 EventThread::Connection::postEvent( ),调用 DisplayEventReceiver::sendEvents(mChannel, &event,1)

    //EventThread.cpp
    status_t EventThread::Connection::postEvent(const DisplayEventReceiver::Event& event)
    {
      ssize_t size = DisplayEventReceiver::SendEvents(mChannel, &event, 1);
    }
    //DisplayEventReceiver.cpp
    ssize_t DisplayEventReceiver::sendEvents(const sp<BitTube>& dataChannel, Event const* events, size_t count)
    {
      return BitTube::sendObject(dataChannel, events, count);
    }
    //BitTube.cpp
    ssize_t BitTube::sendObjects(const sp<BitTube>& tube, void const* events, size_t count, size_t objSize)
    {
      ssize_t numObjects = 0;
      for(ssize_t i=0; i<count; i++){
        ...
        ssize_t size = tube->write(vaddr, objSize);
        ...
      }
      ...
    }
    

    于是当 EventThread 有事件发生,变会遍历其 Connection,像 Connection 的 BitTube 对象写入事件。当写入到 MessageQueue 注册的 Connection 时,MessageQueue 的 Looper 便会监听到事件,回调其 BitTube::getFd( ) 在 looper 中注册的处理函数 MessageQueue::cb_eventReceiver( ),后者通过 DisplayEventReceiver::getEvent( )获得 EventThread 写入到 BitTube 中是 Event,随后 MessageQueue 便通过其内部的 Handler 进行处理消息(MessageQueue 只会处理消息类型为 DisplayEventReceiver::DISPLAY_EVENT_VSYNC的事件,其他时间会被丢弃)。MessageQueue 内部的 Handler 会将消息转交给 SurfaceFlinger 进行处理。

    • BitTube 是通过 Socket 进行进程间通信的。
      到此 SurfaceFlinger 相关体系从 EventThread 收到消息到 SurfaceFlinger 收到并且处理消息便告一段落。

    关于 SurfaceComposerClient

    当一个应用程序与 WMS 连接时,WMS 会返回一个 Session 作为应用像 WSM 发起请求的中介。同时会产生一个 SurfaceSession 对象(一个应用程序对应一个 session 对应一个 SurfaceSession)

    //Session.java
    void windowAddedLocked( ){
      if(mSurfaceSession == null){
        mSurfaceSession = new SurfaceSession( );
      }
    }
    //SurfaceSession.java
    public SurfaceSession( ){
       //mNativeClient 就对应一个 SurfaceComposerClient 对象
      mNativeClient = nativeCreate( );
    }
    //android_view_SurfaceSession.cpp
    static jint nativeCreate(JNIEnv* env, jclass clazz){
      SurfaceComposerClient* client = new SurfaceComposerClient( );
      ...
    }
    
    //SurfaceComposerClient.cpp
    SurfaceComposerClient::SurfaceComposerClient( )
      : mStatus(NO_INIT),mComposer(Composer::getInstance())
    
    void SurfaceComposerClient::onFirstRef( ){
      sp<ISurfaceComposer> sm(ComposerService::getComposerService( ));
      if(sm != 0){
        //是一个 Client 对象,sm 即为 SurfaceFlinger
        sp<ISurfaceComposerClient> conn=sm->createConnection( );
        mClient = conn;
      }
    }
    //SurfaceFlinger.cpp
    sp<ISurfaceComposerClient> SurfaceFlinger::createConnection( ){
      sp<ISurfaceComposerClient> bclient;
      sp<Client> client(new Client(this));
      status_t err = client->initCheck( );
      if(err = NO_ERROR){
        bclient = client;
      }
      return client;
    }
    //Client.cpp
    Client::Client(const sp<SurfaceFlinger>& flinger)
      ::mFlinger(flinger)
    {
    }
    

    于是,当一个应用第一个和 WMS 交互时,会实例化一个 Session 作为该应用与 WMS 交互的通道,Session 内部持有一个SurfaceSession对象作为,SurfaceSession在 native 层对应一个 SurfaceComposerClient 对象,SurfaceComposerClient 对象持有一个 Client,于是通过 SurfaceSession->SurfaceComposerClient->Client 与 SurfaceFlinger 进行交互。在 View 体系中的 Surface,SurfaceControl,Layer 都是通过这个 Client 像 SurfaceFlinger 申请创建的。


    关于 SurfaceControl 和 Surface

    在 APP 与 WMS 交互时,会通过 WMS 实例化一个 SurfaceControl 对象。

    //WindowManagerService.java
    public int relayoutWindow(...){
      SurfaceControl surfaceControl = winAnimator.createSurfaceLocked( );
    }
    //WindowStateAnimator.java
    SurfaceControl createSurfaceLocked( ){
      mSurfaceControl = new SurfaceControl(mSession.mSurfaceSession,...);
    }
    //SurfaceControl.java
    public SurfaceControl(SurfaceSession session,...){
      ...
      mNativeObject = nativeCreate(session, name, w, h, format. flags);
    }
    //android_view_SurfaceControl.cpp
    static jint nativeCreate(...){
      //client 是 SurfaceComposerClient 对象
      sp<SurfaceComposerClient client(android_view_SurfaceSession_getClient(env,seesionObj));
    sp<SurfaceControl> surface = client->createSurface(...);
    }
    //SurfaceComposerClient.cpp
    sp<SurfaceControl> SurfaceComposerClient::createSurface(..){
      sp<SurfaceControl> sur;
      sp<IBinder> handle;
      sp<IGraphicBufferProducer> gbp;
      status_t err = mClient->createSurface(name, w, h, format, flags, &handle, &gbp);
      sur = new SurfaceControl(this, handle, gbp);
    }
    

    可以看见,在创建 Java 层的 SurfaceControl 的时候,会用 jni 层层调用,最后通过 SurfaceComposerClient.cpp 创建SurfaceControl 对象。下来看重点看 SurfaceControl 的创建过程。

    • 首先看 Surface 的创建。
    //status_t Client::createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp){
      class MessageCreateLayer:public MessageBase {
        ...
        virtual bool handler( ){
          result = flinger->createLayer(name, client, w, h, format, flags, handle, gbp);
        }
      }
      sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(), name, this, w, h, format, flags, handle, gbp);
      mFlinger->postMessageSync(msg);
      ...
    }
    

    MessageCreateLayer 作为一个 Message,在 post 后,会调用其 handler( )方法,于是会调用 SurfaceFlinger::createLayer( )进行 Layer 的创建。

    status_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& client, uint32_t w, uint32_t h, PixelFormat format, uint32_T flags, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp){
      sp<Layer> layer;
      swicth(...){
        case ... :
          result = createNormalLayer(client, name, w, h, flags, format, handle, gbp, &layer);
          break;
        case ... :
          result = createDimLayer(client, name, w, h, flags, handle, gbp, &layer);
      }
      addClientLayer(client, *handle, *gbp, layer);
    }
    

    会根据需要创建的不同 Surface 类型创建不同的 Layer,现在只看 normalLayer

    status_t SurfaceFlinger::createNormalLayer(const sp<Client>& client, const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer){
      *outLayer = new Layer(this, client, name, w, h, flags);
      status_t err = (*outLayer)->setBuffers(w,h, format, flags);
      *handle = (*outLayer)->getHandle();
      *gbp = (*outLayer)->getBufferQueue();
    }
    

    于是,来看 new Layer( )的实现

    //Layer.cpp
    Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,...){
      ...
    }
    
    void Layer::onFirstRef( ){
      sp<BufferQueue> bq = new SurfaceTextureLayer(mFlinger);
      mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextName, true, GL_TEXTURE_EXTERNAL_OES, false, bq);
      ..
      mSurfaceFlingerConsumer->setFrameAvailableListener(this);
      ...
    }
    

    创建 Layer 的时候有几个关键点,首先,创建了一个 SurfaceTextureLayer 作为BufferQueue,其次,创建了一个 SurfaceFlingerConsumer作为 consumer,当 APP 对于 Surface 进行 lock 获得一块 Canvas 后,进行 draw,随后进行 unLock(),在 unLock()时,会将 buffer 进行 enqueue,在 BufferQueue 对 buffer 进行 enqueue 时,会回调SurfaceFlingerConsumer(派生自 GLConsumer,派生自 ConsumerBase)中的FrameAvailableListener(Layer 派生自 SurfaceFlingerConsumer::FrameAvailableListener)方法onFrameAvailable(), 该方法会通知 SurfaceFlinger::signalLayerUpdate( )进行刷新。

    于是,在 Layer 中,BufferQueue 是 SurfaceTextureLayer,ConsumerBase 为 SurfaceFlingerConsumer,后者的消费回调为 Layer本身 Layer::onFrameAvailable( );

    sp<IBinder> Layer::getHandl( ){
      class Handle : public BBinder, public LayerCleaer{
        ...
      }
      return new Handle(mFlinger, this);
    }
    

    于是,返回的 Handle 持有 SurfaceFlinger 和 Layer 本身。

    sp<BufferQueue> Layer::getBufferQueue( ) const{
      return mSurfaceFlingerConsumer->getBufferQueue();
     }
    

    于是,返回的 IGraphicBufferProducer 是 SurfaceTextureLayer对象(派生自 BufferQueue),内部持有 SurfaceFlinger,在 BufferQueue 实例化的时候,会通过 createGraphicBufferAlloc( )向 SurfaceFlinger 申请一个 GraphicBufferAlloc 对象

    //SurfaceFlinger.cpp
    sp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc( ){
      sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc( ));
      return gba;
    }
    

    于是 SurfaceComposerClient::createSurface( )中的 mClient->createSurface( )便分析完了,通过 mClinent->createSurface( ),在 normal 情况下,创建了一个 Layer 对象,内部持有一个 BufferQueue,ConsumerBase(Layer 作为SurfaceFlingerConsumer::FrameAvailableListener),&handle 对象为 Layer 的内部内,持有 Layer 本身与 SurfaceFlinger,&gbp 是 SurfaceTextureLayer 对象(派生自 BufferQueue),内部像 SurfaceFlinger 申请了一个 GraphicBufferAlloc。

    SurfaceControl::SurfaceControl(const sp<SurfaceClient>& client, const sp<IBinder>& handle, const sp<IGraphicBufferProducer>& gbp)
      :mClient(client), mHandle(handle), mGraphicBufferProducer(gbp)
    {
    }
    

    可以看到,SurfaceControl只是简单地持有了 SurfaceComposerClient mClient, Handle mHandle, IGraphicBufferProducer mGraphicBufferProducer对象。真的只是 Control!


    于是在 WMS 就为 APP 端生成了一个 SurfaceControl。

    在 aidl 中,有客户端调用的 Surface 作为出参(out), 在对 aidl 生成可以发现,客户端的 Surface 并不会作为 Binder 的参数传递给 WSM,而是 WSM 生成了 Surface,将WSM 生成的 Surface 透到客户端,客户端从 WM 透来的 Surface,copy 到客户端的 Surface。

    现在WSM有了一个 SurfaceControl,WSM会调用 copyFrom(SurfaceControl)@Surface.java 生成透传给客户端的 Surface 对象了。

    //Surface.java
    public void copyForm(SurfaceControl other){
      int surfaceControlPtr = other.mNativeObject;
      int newnativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr);
    
      setNativeObjectLocked(newNativeObject);
    }
    //android_view_Surface.cpp
    static jint nativeCreateFromSurfaceControl(JNIEnv* env, jclass clazz, jint surfaceControlNativeObj){
      sp<SurfaceControl> ctl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
      sp<Surface> surface(ctl->getSurface( ));
      return reinterpret_cast<jint>(surface.get( ));
    }
    //SurfaceControl.cpp
    sp<Surface> SurfaceControl::getSurface( ) const{
      mSurfaceData = new Surface(mGraphicBufferProducer);
      return mSurfaceData;
    }
    

    于是,outSurface便 copy 完成了,只是简单的从 SurfaceControl中获得 IGraphicBufferProducer,让 Surface.cpp 持有,Surface.java 在 native 端持有该 Surface.cpp。

    WSM 将结果传给 APP 时,会将该 outSurface进行writeToParcel(),随后客户端进行readFromParcel(),先看 WSM端的 writeToParcel( )

    //Surface.java
    public void writeToParcel(Parcel dest, int flags ){
      nativeWriteToParcel(mNativeSurface, dest);
    }
    //android_view_Surface.cpp
    static void nativeWriteToParcel(JNIEnv* env, jclass clazz, jint nativeObject, jobject parcelObj){
      Parcel* parcel = parcelFroJavaObject(env, parcelObj);
      sp<Surface> self(reinterpret_cast<Surface *>(nativeObject));
      parcel->writeStrongBinder(self!=0? self->getIGraphicBufferProducet( )->asBinder( ): NULL);
    }
    

    同理来看 nativeReadFromParcel( )

    static jint nativeReadFromParcel(JNIEnv* env, jcalss clazz, jint nativeObject, jobject parcelObj){
      Parcel* parcel = parcelForJavaObject(env, parcelObj);
      sp<IBinder> binder(parcel->readStringBinder( ));
      sp<Surface> sur;
      sp<IGraphicBufferProducer> gpb(interface_cast<IGraphicBufferProducer>(binder));
      sur = new Surface(gbp);
    }
    

    可以看到,Surface 在 Binder 间通讯的时候,只是将其 IGraphicBufferProducer(normal Layer 来说是 SurfaceTextureLayer)进行传递。IGraphicBufferProducer 是 buffer的生产者,客户端对 buffer 的lock 和 unlock 都是通过 IGraphicBufferProducer 进行的。
    继承结构由 SurfaceTextureLayer 派生自 BufferQueue,SurfaceFlingerConsumer派生自 GLConsumer派生自 ConsumerRef派生自 BufferQueue::ConsumerListener
    在 Layer::onFirstRef( )中可以看到

    sp<BufferQueue> bq = new SurfaceTexturreLayer(mFlinger);
    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextureName, true, GL_TEXTURE_EXTERNAL_OES, false, bq);
    //ConsumerBase.cpp
    ConsumerBase::ConsumerBase(const sp<BufferQueue>& bufferQueue):
        mAbandoned(false), mBufferQueue(bufferQueue){
      wp<BufferQueue::ConsumerListener> listener;
      sp<BufferQueue::ConsumerListener> proxy;
      listener = static_cast<BufferQueue::ConsumerListener*>(this);
      proxy = new BufferQueue::ProxyConsumerListener(listener);
      mBufferQueue->consumerConnect(proxy);
    }
    

    于是,在 SurfaceTextureLayer 中的sp<ConsumerListener> mConsumerListener 就是 SurfaceFlingerConsumer 对象本身。那么来看 SurfaceConsumer::onFrameAvailable()方法是在父类 ConsumerBase.cpp 中定义

    void ConsumerBase::onFrameAvailable(){
      sp<FrameAvailableListener> listener;
      listener=mFrameAvailableListener.promote();
      listener->onFrameAvailable();
    }
    

    那么来看这个 mFrameAvailableListener 是在哪里赋值的

    //ConsumerBase.cpp
    void ConsumerBase::setFrameAvailableListener(const wp<FrameAvailableListener>& listener){
       mFrameAvailableListener = listener; 
    }
    

    很熟悉,在 Layer::onFirstRef()中

    //Layer.cpp
    void Layer::onFirstRef( ){
      mSurfaceFlingerConsumer->setFrameAvailableListener(this);
    }
    
    void Layer::onFrameAvilable( ){
      mFlinger->singnalLayerUpdate();
    }
    

    兜兜转转,从 BufferQueue->listener->onFrameAvailable() 转到ConsumerBase(Layer 中的 SurfaceFlingerConsumer)->onFrameAvailable()转到 Layer::onFrameAvilable()转到 SurfaceFlinger::signalLayerUpdate();[重点]


    在 performDraw()@ViewRootImpl 中调用 draw(fullRedrawNeed),现在只分析软件绘制 drawSoftware()

    private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int yoff, boolean caslingRequired, Rect dirty){
      Surface surface = mSurface;
      Canvas canvas = mSurface.lockCanvas(dirty);
      mView.draw(canvas);
      surface.unlockCanvasAndPost(canvas);
    }
    

    通过 lockCanvas()@Surface 获得一个 Canvas,然后 draw()@View[就是 Application 层可控的地方],绘制完成后 unlockCanvasAndPost()@Surface。

    public Canvas lockCanvas(Rect inOutDirty){
      nativeLockCanvas(mNativeSurface, mCanvas, inOutDirty);
    }
    //android_view_Surface.cpp
    static void nativeLockCanvas(JNIEnv* env, jclass clazz, jint nativeObject, jobject canvasObj, jobject dirtyRectObj){
      ANativeWindow_Buff outBuffer; 
      Rect dirtyBounds(dirtyRegion.getBounds());
      surface->lock(&outBuffer, &dirtyBounds);
      Skbitmap bitmap;
      bitmap.setPixels(outBuffer.bits);
      SkCanvas* nativeCanvas = SKNEW_ARGS(SkCanvas,(bitmap));
      swapCanvasPtr(env, canvasObj, nativeCanvas);
      nativeCanvas->clipRegion(clipReg);
    }
    

    通过 lock()@Surface.cpp 获得一块GraphicBuffer(通过匿名共享内存 ashmem 系统),随后实例化 SkCanvas(java层 Canvas 的 native 实现)。随后客户端进行绘制,然后进行 unlock

    //android_view_Surface.cpp
    static void nativeUnlockCanvasAndPost(JNIEnv* env, jclass clazz, jint nativeObject, jobject canvasObje){
      sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
      SkCanvas* nativeCanvas=SkNEW(SkCanvas);
      swapCanvasPtr(env, canvasObj, nativeCanvas);
      surface->unlockAndPost();
    }
    //Surface.cpp
    status_t Surface::unlockAndPost(){
      mLockedBuffer->unlock();
      queueBuffer(mLockBuffer.get(),-1);
      mPostedBuffer=mLockedBuffer;
      mLockedBuffer=0;
    }
    
    int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd){
      int i = getSlotFromBufferLocked(buffer);
      IGraphicBufferProducer::QueueBufferOutput output;
      IGraphicBufferProducer::QueueBufferInput input(timestamp, crop, mScalingMode, mTransform, fence);
      mGraphicBufferProducer->queueBuffer(i, input, &output);
    }
    //BufferQueue.cpp
    status_t BufferQueue::queueBuffer(int buf, const QueueBufferInput& input, QueueBufferOutput* output){
    ..
    listener->onFrameAvailable();
    }
    

    前面提到,就转到了 SurfaceFlinger-> signalLayerUpdate()进行更新 buffer


    关于 GraphicBuffer

    当调用 dequeueBuffer()@BufferQueue.cpp 申请一块 Buffer 时,实际上是通过 createGraphicBuffer()@GraphicBufferAlloc 申请。

    //GraphicBufferAlloc.cpp
    sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage, status_t* error){
      sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
    }
    //GraphicBuffer.cpp
    GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, PixelFormat reqFormat, uint32_t reqUsage)
      : BASE(), oWner(ownData), mBufferMapper(GraphicBufferMapper::get()),
        mInitCheck(NO_ERROR), mIndex(-1){
        ...
        mInitCheck=initSize(w, h, reqFormat, reqUsage);
    }
    

    重点就是在 initSize()分配内存

    status GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat  format, uint32_t reqUsage){
      GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();
      allocator.alloc(w, h, format, reqUsage, &handle, &stride);
    }
    
    //GraphicBufferAllocator::GraphicBufferAllocator()
      : mAllocDev(0){
      hw_module_t const* module;
      int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
      gralloc_open(module, &mAllocDev);
    }
    
    status_t GraphicBufferAllocator::alloc(unit32_t w, uint32_t h, PixelFormat format, int usage, buffer_handle_t* handle, int32_t* stride){
      err = mAllocDev->alloc(mAlocDev, w, h, format, usage, handle, stride);
    }
    

    可以得知,GraphicBufferAllocator 打开了 gralloc 模块,并且调用改硬件的 open 方法
    转:图形缓冲分配过程源码分析


    mAllocDev 是 struct alloc_device_t 结构,看这个结构的注释可以知道,这个结构负责分配和释放图形缓冲区

    //hardware/libhardware/include/hardware/gralloc.h
    typedef struct alloc_device_t {
      struct hw_device_t common;
      //分配图形缓冲区
      int (*alloc)(struct alloc_device_t* dev, int w, int h, int format, int usage, buffer_handle_t* handle, int* stride);
      //释放图形缓冲区
      int (*free)(struct alloc_device_t *dev, char *buffer, int buffer_len);
      void* reserver_proc[7]
    }
    

    从上面转:图形缓冲分配过程源码分析可以知道,如果请求分配的途径为 GRALLPC_USAGE_HW_FB,则从 FrameBuffer 系统帧缓存分配空间就。否则从内存分配空间。
    如果是从内存分配,则创建一块名为'gralloc-buffer'的匿名共享内存,并且由此构造一个private_handle_t对象。并且映射到当前进程虚拟地址(gralloc_map)。

    //native_handle.h
    typedef struct native_handle
    {
      int version;
      int numFds;
      int numInts;
      int data[0];
    } native_handle_t
    //window.h
    typedef const native_handle_t* buffer_handle_t;
    //gralloc.cpp
    static int gralloc_alloc(alloc_device_t* dev, int w, int h, int format, int usage, buffer_handle_t* pHandle, int* pStride){
      if(usage & GRALLOC_USAGE_HW_FB{
        err = gralloc_alloc_framebuffer(dev, size, usage, pHandle);
      }else{
        err = gralloc_alloc_buffer(dev_size_usage, pHandle);
      }
    }
    
    static int gralloc_alloc_buffer(alloc_dev_t* dev,size_t size, int usage, buffer_handle_t* pHandle){
      int fd = -1;
      size = roundUpToPageSize(size);
      //创建匿名共享内存
      fd  =ashme_create_region("gralloc-buffer",size);
      //根据匿名共享内存,创建 private_handle_t
      private_handle_t* hnd = new private_handle_t(fd, size, 0);
      gralloc_moudle_t8 moudle = reinterpret_cast<gralloc_moudle_t*>(dev->commom.moudle);
      //内存映射
      mapBuffer(moudle, hnd);
      *pHandle = hnd;
    }
    //mapper.cpp
    int mapBuffer(gralloc_moudle_t const* moudle, private_handle_t* hnd){
      void* vaddr;
      return gralloc_mao(moudle, hnd, &vaddr);
    }
    static int gralloc_map(gralloc_moudle_t const* moudle, buffer_handle_t handle, void**vaddr){
      private_handle_t* hnd = (private_handle_t*)handle;
      size_t size=hnd->size;
      void* mappedAddress = mmap(0, size, PROT_READ|PROT_WAIT, MAP_SHARED, hnd->fd, 0);
      hnd->base = intprt_t(mmappedAddredd)+hnd->offset;
      *vddr=(void)hnd->base;
    }
    

    于是,通过匿名共享内存,由 graoolc 分配了一块匿名共享内存,并且映射到了对应的进程。
    当调用客户端 lockCanvas( )@Surface.cpp -> nativeLockCanvas( )@android_view_Surface.cpp -> lock( )@Surface.cpp -> dequeueBuffer( )@BufferQueue -> dequeueBuffer( )@BufferQueue 获得 GraphicBuffer。
    如果 GraphicBuffer 还未分配内容,则继续走 createGraphicBuffer( )@GraphicBufferAlloc.cpp -> new GraphicBuffer( ) -> initSize( )@GraphicBuffer -> alloc( )@GraphicBufferAllocator.cpp 。随后便从 gralloc 分配一块匿名共享内存,并且映射到当前地址空间。匿名共享内存的信息保存到 buffer_handle_t 中

      int version;
      int numFds;
      int numInts;
      int data[0];
    

    由于涉及到了进程间通信,GraphicBuffer 的内存分配是在 SurfaceFlinger 进程进行的。而在应用端调用 lock( )@surface.cpp 需要将 GraphicBuffer 返回给客户端。于是Binder 间通信的 flatten() 和unflatten( )就上场了。

    status_t GraphicBuffer::flatten(void* buffer, size_t size, int fds[ ] ,size_t count) const {
      size_t sizeNeeded = GraphicBuffer::getFlattenedSize();
      size_t fdCountNeeded = GraphicBuffer::getFdCount();
      int* buf = static_cast<int*>(buffer);
      buf[0] = 'GBFR';
      buf[1] = width;
      buf[2] = height;
      buf[3] = stride;
      buf[4] = format;
      buf[5] = usage;
      buf[6] = 0;
      buf[7] = 0;
      buf[6] = handle->numFds;
      buf[7] = handle->numInts;
      native_handle_t const* const h = handle;
      memcpy(fds, h->data, h->numFds*sizeof(int));
      memcpy(&buf[8], h->data + h->numFds; h->numInts*sizeof(int));
    }
    
    status_t GraphicBuffer::unflatten(void const* buffer, size_t size, int fds[], size_t count){
      const size_t numFds = buf[6]
      const size_t numInts = buf[7]
      const size_t sizeNeeded = (8 + numInts) * sizeof(int);
       width = buf[1];
      height = buf[2];
      stride = buf[3];
      format = buf[4];
      usage = buf[5];
      native_handle* h = native_handle_create(numFds, numInts);
      memcpy(h->data, fds, numFds*sizeof(int));
      memcpy(h->data + bumFds, &buf[8], numInts*sizeof(int));
      mBufferMapper.registerBuffer(handle);
    }
    //native_handle.c
    native_handle_t* native_handle_create(int numFds, int numInts){
      native_handle_t* h =malloc(sieof(native_handle_t)+sizeof(int)*(numFds+numInts));
      h->version = sizeof(native_handle_t);
      h->numFds=numFds;
      h->numInts=numInts;
      return h;
    }
    //gralloc_priv.h
    struct private_handle_t {
      struct native_handle nativeHandle;
    
      int fd;
      int magic;
      int flags;
      int size;
      int offset;
      int base;
      int pid
    }
    

    相关文章

      网友评论

          本文标题:SurfaceFlinger

          本文链接:https://www.haomeiwen.com/subject/cjsiuctx.html