SurfaceFlinger学习之路(三)BufferQueue原理详解手机开发

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

组件介绍

  • 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。
    在这里插入图片描述

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的所有权属于消费者

BufferQueueCore

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

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/6247.html

(0)
上一篇 2021年7月17日
下一篇 2021年7月17日

相关推荐

发表回复

登录后才能评论