SurfaceFlinger学习之路(三)BufferQueue原理

文章目录

    • 组件介绍
    • GraphicBuffer
      • GraphicBufferAllocator
      • 共享内存
      • GraphicBuffer和FrameBuffer的关系
    • BufferQueue
      • BufferQueueCore
      • BufferQueue创建
      • BufferQueueProducer
      • BufferQueueConsumer
      • Surface 生产数据
      • SurfaceFlinger 消费数据
      • 小结
    • Surface
      • GraphicBufferProducer的创建
      • Layer
      • Layer创建流程:
    • SurfaceFlinger工作流程总结

本文参考很多资料和源码,每一小结附上参考资源。

组件介绍

  • SurfaceFlinger:系统服务,接收多个源的数据,对它们进行合成,然后发送到显示设备进行显示。
  • HWComposer:在没有HWComposer之前,SurfaceFlinger将各个Layer的内容用OpenGL渲染到暂存缓冲区中,最后将暂存缓冲区传送到显示硬件。HWComposer是硬件合成器,帮助GPU做一些工作,SurfaceFlinger把多个Surface输出给hwc, hwc按照Surface的属性, 把多个Surface混合成一个Surface, 最后输出到Display。
  • Gralloc:层中提供了一个Gralloc模块,Hgralloc库负责了申请图形缓冲区的所有工作,用户空间中的进程申请图形缓冲区,可以是普通的缓存区,也可以是显存缓冲区,并且将缓冲区映射到应用程序的地址空间。

GraphicBuffer

GraphicBuffer是图形内存块,是UI绘制的缓存数据。Surface向GraphicBufferProducer申请一个GraphicBuffer,再绘制到GraphicBuffer中,提供给SurfaceFlinger进行消费合成。

那么GraphicBuffer是什么?

// GraphicBuffer.h
GraphicBufferMapper& mBufferMapper; // 辅助类
ssize_t mInitCheck; // 记录图形缓冲区的状态
sp<ANativeWindowBuffer> mWrappedBuffer; // 描述Native Buffer
uint64_t mId; // 图形缓冲区的标识
sp<IBinder> mBufferRef;
uint32_t mGenerationNumber; // 记录 generation number

其中,GraphicBufferAllocator 负责GraphicBuffer创建和释放工作;

GraphicBufferMapper负责lock和unlock操作,lock 操作将图形内存块映射到应用程序进程的虚拟地址空间内。而unlock就是归还内存。

struct ANativeWindowBuffer
{
    int width;
    int height ;
     .....
    buffer_handle_t handle ; // 硬件驱动层生成的图像缓存句柄
}

更多GraphicBuffer可以参考:
https://www.wolfcstech.com/2017/09/20/android_graphics_bufferalloc/

GraphicBufferAllocator

GraphicBufferAllocator 管理分配显示的内存,提供了申请和释放图像内存块的方法:

status_t GraphicBufferAllocator::alloc(uint32_t width, uint32_t height, PixelFormat  format, uint32_t usage, buffer_handle_t* handle, uint32_t* stride);
status_t GraphicBufferAllocator::free(buffer_handle_t handle);

GraphicBufferAllocator是单例模式,每个进程只有一个GraphicBufferAllocator对象;

GraphicBufferAllocator对接了gralloc,而gralloc模块是Android硬件抽象层提供的一个操作帧缓冲区的模块。

gralloc 提供了两种缓存区:

  • FrameBuffer帧缓冲区,映射到用户空间,应用进程可以操作FrameBuffer,来让显示设备显示;
  • 普通的数据缓冲区,内核中创建一块匿名共享内存,映射到用户空间。
// gralloc
gralloc_alloc(){
    if ( usage & GRALLOC_USAGE_HW_FB ) {
       err = gralloc_alloc_framebuffer (dev, size, usage , pHandle);
    } else {
        err = gralloc_alloc_buffer (dev, size, usage , pHandle);
    }

GraphicBufferAllocator::get() 提供获取GraphicBufferAllocator的方法

GraphicBufferAllocator分配缓存Buffer,GraphicBufferMapper mmap映射到应用程序的进程

更多Gralloc参考:
https://blog.csdn.net/fu_shuwu/article/details/53048047

共享内存

由上面我们可以知道,GraphicBuffer指向的是一个图像缓存区,而应用程序执行draw动作的时候,将一帧帧的数据通过Surface写入到GraphicBuffer,等到vsync信号来了,GraphicBuffer被SurfaceFlinger消费,通过某种手段混合生成最后的帧数据,写入FrameBuffer交由显示设备显示。

其中应用进程、SurfaceFlinger都是在不同的进程,binder通信不适传递大量的图像数据,因此采用了匿名共享内存的IPC手段,在tmpfs临时文件系统中创建一个临时文件。

参考:
https://www.jianshu.com/p/d9bc9c668ba6

GraphicBuffer和FrameBuffer的关系

二者之间其实没有很直接的关系,但是自己的学习过程中,一直搞不懂之间的猫腻。

GraphicBuffer
GraphicBuffer继承自ANativeWindowBuffer,Surface继承自ANativeWindow
BufferQueue操作的具体对象,表示图像缓冲区,Surface可能包含申请多个GraphicBuffer;

FrameBuffer
帧缓冲是Linux 系统为显示设备提供的一个接口,每个显示设备被抽象为一个帧缓冲区,注册到FrameBuffer模块中,并在/dev/graphics目录下创建对应的fbX设备。屏蔽图像硬件的底层差异,允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。

http://blog.csdn.net/ear5cm/article/details/45458683

BufferQueue

GraphicBuffer是表示基本的显示内存单元,而GraphicBufferAllocator负责真正的申请和释放内存,那BufferQueue就是管理GraphicBuffer的管理者。

SurfaceFlinger在Surface创建的时候,对应创建了Layer,Layer会创建BufferQueue。
BufferQueue的原理很简单:

  1. 生产者(Producer)向BufferQueue申请出队(dequeue) GraphicBuffer,生产者向GraphicBuffer中填充图形数据后,然后将GraphicBuffer入队(queue)到BufferQueue;
  2. GraphicBuffer入队BufferQueue时,BufferQueue会通知消费者,新的图形数据生产了;
  3. 消费者(Consumer)向BufferQueue获取(acquire) GraphicBuffer,消费者消费图形数据,然后将GraphicBuffer释放交回(release)给BufferQueue;
  4. 空的GraphicBuffer交回给BufferQueue,BufferQueue又会通知到生产者有新的可利用的GraphicBuffer。
    SurfaceFlinger学习之路(三)BufferQueue原理_第1张图片

BufferQueueCore

BufferQueue 内部有一个重要的变量BufferQueueCore。BufferQueue中用BufferSlot来存储GraphicBuffer,使用数组来存储一系列BufferSlot,数组默认大小为64。

  • mSlots
    定义了64个BufferSlot, BufferSlot直接持有GraphicBuffer
  • std::set mFreeSlots
    mFreeSlots里面的slot值表明当前slot的BufferSlot是FREE状态, 并且没有GraphicBuffer
  • std::list mUnusedSlots
    mSlots的大小是64个,而mUnusedSlots就是除掉mFreeSlots剩下的BufferSlot
  • std::list mFreeBuffers
    mFreeBuffers里面的slot表明当前slot对应的BufferSlot是FREE状态,并且有GraphicBuffer
  • std::set mActiveBuffers
    mActiveBuffers里面的slot表明当前slot对应的BufferSlot都有GraphicBuffer,并且是NON FREE状态

GraphicBuffer用BufferState来表示其状态,有以下状态:

  • FREE:表示该Buffer当前可用,允许被dequeued,此时Buffer属于BufferQueue;
  • DEQUEUED:表示该Buffer被生产者获取了,属于生产者,BufferQueue不可以对这块缓冲区进行操作;
  • QUEUED:表示该Buffer被生产者填充了数据,并且入队到BufferQueue了,该Buffer的所有权属于BufferQueue
  • ACQUIRED:表示该Buffer被消费者获取了,该Buffer的所有权属于消费者

SurfaceFlinger学习之路(三)BufferQueue原理_第2张图片

BufferQueue创建

BufferQueue是由BufferLayer创建,而BufferLayer是在SurfaceFlinger创建,BufferQueue为BufferLayer管理GrapicBuffer。

void bufferqueue::createbufferqueue(sp<igraphicbufferproducer>* outproducer,
        sp<igraphicbufferconsumer>* outconsumer,
        const sp<igraphicbufferalloc>& allocator) {//allocator == null
    ...
    //创建bufferqueuecore
    sp<bufferqueuecore> core(new bufferqueuecore(allocator));
    ...
    //创建生产者
    sp<igraphicbufferproducer> producer(new bufferqueueproducer(core));
    ...
    //创建消费者
    sp<igraphicbufferconsumer> consumer(new bufferqueueconsumer(core));
    ...
    *outproducer = producer;
    *outconsumer = consumer;
}

BufferQueueProducer

BufferQueue 创建了生产者BufferQueueProducer,并赋给外部的IGraphicBufferProducer,供外部调用。

来看一下BufferQueueProducer,他继承自了BnGraphicBufferProducer,是一个binder的服务端,接收来自客户端的消息。

status_t dequeueBuffer(int* outSlot, sp<Fence>* outFence, uint32_t width,
         uint32_t height, PixelFormat format, uint64_t usage,
         uint64_t* outBufferAge, FrameEventHistoryDelta* outTimestamps);
                                   
status_t queueBuffer(int slot, const QueueBufferInput& input, QueueBufferOutput* output);
status_t requestBuffer(int slot, sp<GraphicBuffer>* buf);

参考:https://zhuanlan.zhihu.com/p/62813895

BufferQueueConsumer

BufferQueue 创建了消费者者BufferQueueConsumer,并赋给外部的IGraphicBufferConsumer,供外部调用。

同样,BufferQueueConsumer也继承了BnGraphicBufferConsumer,同样也是个binder的服务端。

status_t acquireBuffer(BufferItem* outBuffer,nsecs_t expectedPresent, uint64_t maxFrameNumber = 0);
status_t releaseBuffer(int slot, uint64_t frameNumber, const sp<Fence>& releaseFence, 
        EGLDisplay display, EGLSyncKHR fence);

更多参考:
https://www.jianshu.com/p/af5858c06d5d
https://blog.csdn.net/yangwen123/article/details/12234931

Surface 生产数据

Surface生产数据经历的流程:

  1. allocateBuffer
  2. dequeueBuffer
  3. queueBuffer
//Surface.cpp
void Surface::allocateBuffers() {
    uint32_t reqWidth = mReqWidth ? mReqWidth : mUserWidth;
    uint32_t reqHeight = mReqHeight ? mReqHeight : mUserHeight;
    mGraphicBufferProducer->allocateBuffers(reqWidth, reqHeight,
            mReqFormat, mReqUsage);
}
int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
    ...
    status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, reqWidth, reqHeight,
                                                            reqFormat, reqUsage, &mBufferAge,
                                                            enableFrameTimestamps ? &frameTimestamps : nullptr);
    ...
    Mutex::Autolock lock(mMutex);
    sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
    ...
    *buffer = gbuf.get();
    ...
    return OK;
}
int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
    Rect crop(Rect::EMPTY_RECT);
    mCrop.intersect(Rect(buffer->width, buffer->height), &crop);
    IGraphicBufferProducer::QueueBufferOutput output;
    IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp,
            static_cast<android_dataspace>(mDataSpace), crop, mScalingMode,
            mTransform ^ mStickyTransform, fence, mStickyTransform,
            mEnableFrameTimestamps);
    // 处理图像数据
    ...
    nsecs_t now = systemTime();
    status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
    ...
    return err;
}
status_t BufferQueueProducer::queueBuffer(int slot,
        const QueueBufferInput &input, QueueBufferOutput *output) {
    input.deflate(&requestedPresentTimestamp, &isAutoTimestamp, &dataSpace,
            &crop, &scalingMode, &transform, &acquireFence, &stickyTransform,
            &getFrameTimestamps);
    sp<IConsumerListener> frameAvailableListener;
    sp<IConsumerListener> frameReplacedListener;
    uint64_t currentFrameNumber = 0;
    BufferItem item;
    {
        const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);
        Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
        Rect croppedRect(Rect::EMPTY_RECT);
        crop.intersect(bufferRect, &croppedRect);
        mSlots[slot].mFence = acquireFence;
        mSlots[slot].mBufferState.queue();
        ++mCore->mFrameCounter;
        currentFrameNumber = mCore->mFrameCounter;
        mSlots[slot].mFrameNumber = currentFrameNumber;
        item.mAcquireCalled = mSlots[slot].mAcquireCalled;
        item.mGraphicBuffer = mSlots[slot].mGraphicBuffer;
        item.mCrop = crop;
        ...
        item.mQueuedBuffer = true;if (mCore->mQueue.empty()) {
            mCore->mQueue.push_back(item);
            frameAvailableListener = mCore->mConsumerListener;
        } else {
            const BufferItem& last = mCore->mQueue.itemAt(mCore->mQueue.size() - 1);
            if (last.mIsDroppable) {
                ...
                mCore->mQueue.editItemAt(mCore->mQueue.size() - 1) = item;
                frameReplacedListener = mCore->mConsumerListener;
            } else {
                mCore->mQueue.push_back(item);
                frameAvailableListener = mCore->mConsumerListener;
            }
        }
    } 
    
    { 
        Mutex::Autolock lock(mCallbackMutex);
        while (callbackTicket != mCurrentCallbackTicket) {
            mCallbackCondition.wait(mCallbackMutex);
        }
        if (frameAvailableListener != NULL) {
            frameAvailableListener->onFrameAvailable(item);
        } else if (frameReplacedListener != NULL) {
            frameReplacedListener->onFrameReplaced(item);
        }
    }
    return NO_ERROR;
}

SurfaceFlinger 消费数据

上面的frameAvailableListener->onFrameAvailable(),会回调通知Layer,Layer通知SurfaceFlinger消费,SurfaceFlinger利用EventThread,在VSYNC信号来时,执行INVALIDATE的操作,触发对所有Layer执行操作。SurfaceFlinger又触发REFRESH消息

void BufferLayer::onFrameAvailable(const BufferItem& item) {
    // Add this buffer from our internal queue tracker
    ...
    mFlinger->signalLayerUpdate();
}
void SurfaceFlinger::signalLayerUpdate() {
    mEventQueue->invalidate();
}
#define INVALIDATE_ON_VSYNC 1
/* when INVALIDATE_ON_VSYNC is set SF only processes
 * buffer updates on VSYNC and performs a refresh immediately
 * after.
 *
 * when INVALIDATE_ON_VSYNC is set to false, SF will instead
 * perform the buffer updates immediately, but the refresh only
 * at the next VSYNC.
 * THIS MODE IS BUGGY ON GALAXY NEXUS AND WILL CAUSE HANGS
 */
void MessageQueue::invalidate() {
#if INVALIDATE_ON_VSYNC
    mEvents->requestNextVsync();
#else
   mHandler->dispatchInvalidate();
#endif
}
void MessageQueue::Handler::handleMessage(const Message& message) {
    switch (message.what) {
        case INVALIDATE:
            android_atomic_and(~eventMaskInvalidate, &mEventMask);
            mQueue.mFlinger->onMessageReceived(message.what);
            break;
        case REFRESH:
            android_atomic_and(~eventMaskRefresh, &mEventMask);
            mQueue.mFlinger->onMessageReceived(message.what);
           break;
   }
}

当VSync信号到来时,SurfaceFlinger处理最重要的两个操作INVALIDATE和REFRESH消息

  1. INVALIDATE
    依次调用handleMessageTransaction() 处理之前对屏幕和应用程序窗口的改动;handleMessageInvalidate()获取各Layer对应的BufferQueue缓冲数据,更新脏区域;触发REFRESH消息。

  2. REFRESH
    调用handleMessageRefresh()合并和渲染输出。

void SurfaceFlinger::onMessageReceived(int32_t what) {
    switch (what) {
        case MessageQueue::INVALIDATE: {
            ...
            if (frameMissed) {
                mTimeStats.incrementMissedFrames();
                if (mPropagateBackpressure) {
                    signalLayerUpdate();
                    break;
                }
            }
            updateVrFlinger();
            bool refreshNeeded = handleMessageTransaction();
            refreshNeeded |= handleMessageInvalidate();
            refreshNeeded |= mRepaintEverything;
            if (refreshNeeded) {
                signalRefresh();
            }
            break;
        }
        case MessageQueue::REFRESH: {
            handleMessageRefresh();
            break;
        }
    }
}

handleMessageRefresh()

void SurfaceFlinger::handleMessageRefresh() {
    mRefreshPending = false;
    nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
    preComposition(refreshStartTime); // 预处理显示和Layer的改变
    rebuildLayerStacks(); // 根据Layer层级改变次数
    setUpHWComposer(); // 更新 HWComposer层级
    doDebugFlashRegions();
    doTracing("handleRefresh");
    logLayerStats();
    doComposition();// 生成 OpenGL texture纹理
    postComposition(refreshStartTime); // 推送到物理显示设备
    mPreviousPresentFence = getBE().mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);
    ...
    mVsyncModulator.onRefreshed(mHadClientComposition);
    mLayersWithQueuedFrames.clear();
}

参考:
https://juejin.im/post/5baf275f5188255c9a7740ba
http://gityuan.com/2017/02/18/surface_flinger_2/

小结

Surface创建过程中,SurfaceFlinger对应创建一个BufferLayer,BufferLayer创建对应的BufferQueue。

上面大致领略了BufferQueue的生产者消费者模式,由GraphicBufferAllocator分配buffer内存,其中Surface生产图像数据,SurfaceFlinger消费图像数据。

Surface

剩下的问题:

  1. 上一文章中最后Surface创建的时候赋值了一个GraphicBufferProducer,而SurfaceFlinger创建对应的Layer,Surface中的GraphicBufferProducer是哪里来的?
  2. Layer是什么?怎么创建的?
  3. Native层的Surface到底是什么? 怎么创建的

GraphicBufferProducer的创建

其实是利用了SurfaceFlinger的Client创建传递过来的。

// Surface.cpp
err = mClient->createSurface(name, w, h, format, flags, parentHandle,
                windowType, ownerUid, &handle, &gbp);
// gbp就是GraphicBufferProducer

Layer

Layer 有两种类型:

  • BufferLayer 具备Buffer可缓存显示数据的Layer;
  • ColorLayer 可绘制指定颜色和透明度的Layer

BufferLayer,通过BufferQueue的createBufferQueue,创建了一个buffer队列,一个buffer队列,有一个生产者producer,和一个消费者consumer。

BufferLayer实现ContentsChangedListener和FrameAvailableListener两个接口类

private:
    sp<BufferLayerConsumer> mConsumer;
    sp<IGraphicBufferProducer> mProducer;
    // constants
    uint32_t mTextureName; // from GLES
    PixelFormat mFormat;
    // main thread
    uint32_t mCurrentScalingMode;
    bool mBufferLatched = false;   // TODO: Use mActiveBuffer?
    uint64_t mPreviousFrameNumber; // Only accessed on the main thread.
    // The texture used to draw the layer in GLES composition mode
    mutable Texture mTexture;
    bool mUpdateTexImageFailed; // This is only accessed on the main thread.
    bool mRefreshPending;

BufferLayer是什么

void BufferLayer::onFirstRef() {
    Layer::onFirstRef();
    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
    sp<IGraphicBufferProducer> producer;
    sp<IGraphicBufferConsumer> consumer;
    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->mStateLock);
        mConsumer = new BufferLayerConsumer(consumer, mFlinger->getRenderEngine(), mTextureName,
                                            this);
    }
    mConsumer->setConsumerUsageBits(getEffectiveUsage(0));
    mConsumer->setContentsChangedListener(this);
    mConsumer->setName(mName);
    if (mFlinger->isLayerTripleBufferingDisabled()) {
        mProducer->setMaxDequeuedBufferCount(2);
    }
    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
    updateTransformHint(hw);
}
  1. Producer生产完后,会通过BufferQueueCore中的mConsumerListener通知ConsumerBase
  2. ConsumerBase,接受到BufferQueueConsumer的通知,再通过BufferLayer传下来的信使mFrameAvailableListener,通知BufferLayer。
  3. BufferLayer接受到通知后,就可以去消费生产完的Buffer了。

Layer创建流程:

SurfaceFlinger为Surface创建了一个Layer与之对应,

// Client.cpp
status_t Client::createSurface(... , sp<IGraphicBufferProducer>* gbp)
{
    result = flinger->createLayer(name, client, w, h, format, flags,
        windowType, ownerUid, handle, gbp, parent);        
}
// SurfaceFlinger.cpp
status_t SurfaceFlinger::createLayer(
        const String8& name,
        const sp<Client>& client,
        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
        int32_t windowType, int32_t ownerUid, sp<IBinder>* handle,
        sp<IGraphicBufferProducer>* gbp, sp<Layer>* parent)
{
    status_t result = NO_ERROR;
    sp<Layer> layer;
    String8 uniqueName = getUniqueLayerName(name);
    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
        case ISurfaceComposerClient::eFXSurfaceNormal:
            result = createBufferLayer(client,
                    uniqueName, w, h, flags, format,
                    handle, gbp, &layer);
            break;
        case ISurfaceComposerClient::eFXSurfaceColor:
            result = createColorLayer(client,
                    uniqueName, w, h, flags,
                    handle, &layer);
            break;
        default:
            result = BAD_VALUE;
            break;
    }
    ...
    layer->setInfo(windowType, ownerUid);
    result = addClientLayer(client, *handle, *gbp, layer, *parent);
    if (result != NO_ERROR) {
        return result;
    }
    mInterceptor->saveSurfaceCreation(layer);
    setTransactionFlags(eTransactionNeeded);
    return result;
}

看createBufferLayer和addClientLayer

status_t SurfaceFlinger::createBufferLayer(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)
{
    // initialize the surfaces
    switch (format) {
    case PIXEL_FORMAT_TRANSPARENT:
    case PIXEL_FORMAT_TRANSLUCENT:
        format = PIXEL_FORMAT_RGBA_8888;
        break;
    case PIXEL_FORMAT_OPAQUE:
        format = PIXEL_FORMAT_RGBX_8888;
        break;
    }
    sp<BufferLayer> layer = new BufferLayer(this, client, name, w, h, flags);
    status_t err = layer->setBuffers(w, h, format, flags);
    if (err == NO_ERROR) {
        *handle = layer->getHandle();
        *gbp = layer->getProducer();
        *outLayer = layer;
    }
    return err;
}

addClientLayer

status_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
        const sp<IBinder>& handle,
        const sp<IGraphicBufferProducer>& gbc,
        const sp<Layer>& lbc,
        const sp<Layer>& parent)
{
    // add this layer to the current state list
    {
        Mutex::Autolock _l(mStateLock);
        if (mNumLayers >= MAX_LAYERS) {
            ALOGE("AddClientLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers,
                  MAX_LAYERS);
            return NO_MEMORY;
        }
        if (parent == nullptr) {
            mCurrentState.layersSortedByZ.add(lbc);
        } else {
            if (parent->isPendingRemoval()) {
                ALOGE("addClientLayer called with a removed parent");
                return NAME_NOT_FOUND;
            }
            parent->addChild(lbc);
        }
        if (gbc != nullptr) {
            mGraphicBufferProducerList.insert(IInterface::asBinder(gbc).get());
            LOG_ALWAYS_FATAL_IF(mGraphicBufferProducerList.size() >
                                        mMaxGraphicBufferProducerListSize,
                                "Suspected IGBP leak: %zu IGBPs (%zu max), %zu Layers",
                                mGraphicBufferProducerList.size(),
                                mMaxGraphicBufferProducerListSize, mNumLayers);
        }
        mLayersAdded = true;
        mNumLayers++;
    }
    // attach this layer to the client
    client->attachLayer(handle, lbc);
    return NO_ERROR;
}

SurfaceFlinger工作流程总结

app进程向WMS申请创建对应的RootView

WMS向SurfaceFlinger申请创建Surface

SurfaceFlinger对应创建Layer,Layer内部创建一个BufferQueue,app负责申请GraphicBuffer利用匿名共享内存方式写入图像数据,SurfaceFlinger负责从BufferQueue取出消费图像数据。

Surfaceflinger把所有的显示的buffer做图层合并处理,利用HWC或者OpenGL,合并到FrameBuffer中。

framebuffer本身申请的内存能存两个屏幕的数据量还大的内存,所以采样交替送显的方式进行eglSwapBuffers交换(即fb_pan_display指定切换到另外framebuffer的另一部分地址),即framebuffer的A部分用于merge处理,framebuffer的B部分用于送显显示,

下一个节拍例如vsync时,进行切换,framebuffer的A部分送显,framebuffer的B部分用于merge。送显的内容除了framebuffer外,还有overlay的内容,硬件会把他们进行合并,再送到显示屏幕。

参考:
https://blog.csdn.net/happylishang/article/details/78282527
https://www.jianshu.com/p/af5858c06d5d

你可能感兴趣的:(android)