GUI:BufferQueue

作者: 81bad73e9053 | 来源:发表于2016-11-15 21:30 被阅读183次

1.BufferQueue内部原理

TU 9-14
BufferQueue是IGraphicBufferProducer服务器端的实现;所以BufferQueue会重载IGraphicBufferProducer接口中的各个虚函数queueBuffer,requesBuffer,dequeueBuffer等,该类内部还有一个mSlots[NUM_BUFFER_SLOTS];

1.1 mSlots[NUM_BUFFER_SLOTS]

BufferQueue中BufferSlot的定义

struct BufferSlot{
    //用于记录缓冲区
    sp<GraphicBuffer> mGraphicBuffer;
    //用于记录缓冲区状态
    BufferState mBuffreState;
    ...
}

1.2 缓冲区状态

//缓冲区状态

enum BufferState {
//Buffer当前可用,也就是可以被dequeued,此时Buffer的拥有者可以认为是BufferQueue
        FREE = 0,
//Buffer已经被dequeued,还没被queued或者canceld,
//此时Buffer的拥有者是应用程序,此时BufferQueue和SurfaceFlinger都不可以操作这块缓冲区
        DEQUEUED = 1,
//Buffer被客户端程序queued,不过还不能对它进行dequeue,但可以acquire,
//此时拥有者还是BufferQueue
        QUEUED = 2,
//Buffer的拥有者是Consumer,可以被release然后状态回到FREE
        ACQUIRED = 3
    };
    BufferState mBufferState;
};

1.3 缓冲区状态迁移

TU 9-15

  • BufferQueue:可以认为BufferQueue是一个服务中心,其他两个Owner必须通过它来管理Buffer。
  • Producer:生产者就是填充Buffer的,通常情况下就是应用程序,应用程序不断刷新UI,从而将产生的数据源源不断的写到Buffer中,当Producer需要一块Buffer时,首先回向中介BufferQueue发起dequeue请求,然后才能对指定的缓冲区进行操作,经过dequeue后的buffer就属于producer了,它可以对缓冲区进行任何操作,而其他Owner不能插手。当producer认为一块Buffer已经写入完成后,将进一步调用BufferQueue的queue接口,把Buffer归还到BufferQueue中,一旦入列成功,Owner就变成了BufferQueue。
  • Consumer:当一块Buffer就绪之后,Consumer就可以开始工作了。

总结:BufferQueue是中介,Producer是内容的产出方,它对Buffer的操作是主动的,Consumer对Buffer的操作是被动的,它必须等到Buffer填充完成之后才工作(其中ready之后通知Consumer的工作是ConsumerListener来完成的),当数据准备就绪后,通过onFrameAvailable通知Consumer来进行消费

class ConsumerListener : public virtual RefBase {
  //当一块Buffer可以被消费时,这个函数会被调用
  virtual void onFrameAvailable(const BufferItem& item) = 0;
  //BufferQueue通知Cosumer它已经释放slot中一个或多个GraphicBuffer引用
  virtual void onBuffersReleased() = 0; 
}

2.BufferQueue中缓冲区的分配

2.1 缓冲区分配简略

  • 缓冲区的分配应该既要满足使用者的需求,又要防止浪费。
  • 既然Producer对缓冲区的操作时主动的,那么就意味着它是整个需求的发起者;也就是说只要Producer没有执行dequeueBuffer或者dequeueBuffer时能获取到可用的缓冲区,那就没有必要重新分配空间。

2.2 缓冲区分配的起点Surface::dequeueBuffer

int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
    
    int buf = -1;
    //宽高计算
    int reqW = mReqWidth ? mReqWidth : mUserWidth;
    int reqH = mReqHeight ? mReqHeight : mUserHeight;
    sp<Fence> fence;
    //dequeueBuffer得到一个缓冲区
    status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, mSwapIntervalZero,reqW, reqH, mReqFormat, mReqUsage);
    //buf是一个int值,代表mSlots数组序号
    sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
 
    if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) {
        freeAllBuffers();
    }
    //需要重新分配
    if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
        result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
        if (result != NO_ERROR) { 
            return result;
        }
    }  
    *buffer = gbuf.get();
    return OK;
}

2.3 BpGraphicBufferProducer调用远程服务

class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
{
public:
    BpGraphicBufferProducer(const sp<IBinder>& impl)
        : BpInterface<IGraphicBufferProducer>(impl)
    {
        
    } 
    
    virtual status_t dequeueBuffer(int *buf, sp<Fence>* fence, bool async,
            uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
        Parcel data, reply;
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
        //只写进去5个参数,这是入参,buf和fence是出参
        data.writeInt32(async);
        data.writeInt32(w);
        data.writeInt32(h);
        data.writeInt32(format);
        data.writeInt32(usage);
        //远程调用
        status_t result = remote()->transact(DEQUEUE_BUFFER, data, &reply);
        if (result != NO_ERROR) {
            return result;
        }
        
        *buf = reply.readInt32();//slot编号
        bool nonNull = reply.readInt32();
        if (nonNull) {
            *fence = new Fence();
            reply.read(**fence);//从reply中读取数据填充fence
        }
        result = reply.readInt32();
        return result;
    }
    
    

    //这里bufferIdx是入参,传给了服务端,buf是出参
    virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) {
        Parcel data, reply;
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
        data.writeInt32(bufferIdx);
        status_t result =remote()->transact(REQUEST_BUFFER, data, &reply);
        if (result != NO_ERROR) {
            return result;
        }
        bool nonNull = reply.readInt32();//先读取标志位
        if (nonNull) {
            *buf = new GraphicBuffer();
            reply.read(**buf);//从reply中读取数据填充buf
        }
        result = reply.readInt32();
        return result;
    } 

//...
}

2.4 BnGraphicBufferProducer的响应

status_t BnGraphicBufferProducer::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch(code) {
        case DEQUEUE_BUFFER: {
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
            //读取参数
            bool async      = data.readInt32();
            uint32_t w      = data.readInt32();
            uint32_t h      = data.readInt32();
            uint32_t format = data.readInt32();
            uint32_t usage  = data.readInt32();
            //注意这两个
            int buf;
            sp<Fence> fence;
            //调用dequeueBuffer
            int result = dequeueBuffer(&buf, &fence, async, w, h, format, usage);
            //注意写入的顺序,客户端读取的顺序与这个一致
            reply->writeInt32(buf);
            reply->writeInt32(fence != NULL);
            if (fence != NULL) {
                reply->write(*fence);
            }
            reply->writeInt32(result);
            return NO_ERROR;
        } break;

        
        case REQUEST_BUFFER: {
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
            int bufferIdx   = data.readInt32();
            sp<GraphicBuffer> buffer;
            //调用requestBuffer
            int result = requestBuffer(bufferIdx, &buffer);
            reply->writeInt32(buffer != 0);
            if (buffer != 0) {
                reply->write(*buffer);
            }
            reply->writeInt32(result);
            return NO_ERROR;
        } break;
 

        
        //......
    }
}

2.5 BufferQueue::dequeueBuffer真正分配缓冲区

status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>* outFence, bool async,
        uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
 
    {  
        Mutex::Autolock lock(mMutex); 
        int found = -1;
        bool tryAgain = true;
        while (tryAgain) {//查询符合要求的slot
            //......
            found = INVALID_BUFFER_SLOT;//初始值
            int dequeuedCount = 0;
            int acquiredCount = 0;
            for (int i = 0; i < maxBufferCount; i++) {
                const int state = mSlots[i].mBufferState;//该slot的状态
                switch (state) {
                    case BufferSlot::DEQUEUED:
                        dequeuedCount++;//统计DEQUEUED的slot个数
                        break;
                    case BufferSlot::ACQUIRED:
                        acquiredCount++;
                        break;
                    case BufferSlot::FREE: //找到处于空闲状态的slot
                        if ((found < 0) ||
                                mSlots[i].mFrameNumber < mSlots[found].mFrameNumber) {
                            found = i;
                        }
                        break;
                }
            } 
 
            if (!mOverrideMaxBufferCount && dequeuedCount) {
                //如果client没有设置buffer count的话,就不允许dequeue一个以上buffer
                return -EINVAL;
            }

            //是否需要重试
            tryAgain = found == INVALID_BUFFER_SLOT;
            if (tryAgain) {
                //如果需要重试的话,就等待,因为如果这时候直接开始也是拿不到的                
                mDequeueCondition.wait(mMutex);
            }
        } 
        
        const int buf = found;
        *outBuf = found;//返回值
 
        //成功找到可用序号,接下来就是进行初始化操作以及状态变迁
        //BuffreSlot的一个成员mBufferState的赋值
        mSlots[buf].mBufferState = BufferSlot::DEQUEUED;

        const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
        if ((buffer == NULL) ||
            (uint32_t(buffer->width)  != w) ||
            (uint32_t(buffer->height) != h) ||
            (uint32_t(buffer->format) != format) ||
            ((uint32_t(buffer->usage) & usage) != usage))
        {
            mSlots[buf].mAcquireCalled = false;
            mSlots[buf].mGraphicBuffer = NULL;
            mSlots[buf].mRequestBufferCalled = false;
            mSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
            mSlots[buf].mFence = Fence::NO_FENCE;
            mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
            //如果需要重新分配的话,返回值里有BUFFER_NEEDS_REALLOCATION
            returnFlags |= IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION;
        } 
    }  // end lock scope
    //如果需要重新分配的话
    if (returnFlags & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) {
        status_t error;
        sp<GraphicBuffer> graphicBuffer(
                mGraphicBufferAlloc->createGraphicBuffer(w, h, format, usage, &error));
        if (graphicBuffer == 0) { 
            return error;
        } 
        
        { // Scope for the lock
            Mutex::Autolock lock(mMutex); 
            mSlots[*outBuf].mFrameNumber = ~0;
            //BufferSlot的另一个重要成员mGraphicBuffer赋值
            mSlots[*outBuf].mGraphicBuffer = graphicBuffer;
        }
    } 
    return returnFlags;
}

分配空间会调用mGraphicBufferAlloc->createGraphicBuffer,如果重新分配了空间,那么需要加上BUFFER_NEEDS_REALLOCATION标志。客户端在使用的时候发现这个标志会调用requestBuffer来取得最新的buffer地址。

2.6 BufferQueue::requestBuffer

status_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
    //根据索引和状态判断
    if (slot < 0 || slot >= NUM_BUFFER_SLOTS) { 
        return BAD_VALUE;
    } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) { 
        return BAD_VALUE;
    }
    mSlots[slot].mRequestBufferCalled = true;
    *buf = mSlots[slot].mGraphicBuffer;//注意buf
    return NO_ERROR;
}

requestBuffer后,通过Binder的传递,就把这个buf传给了Surface里gbuf,然后又通过*buffer = gbuf.get();就把这块缓冲区也给了Surface里的buffer

2.7总结

Surface通过dequeueBuffer来申请一块缓冲区,该操作会通过客户端的mGraphicBufferProducer经Binder调用到服务端的BufferQueue(IGraphicBufferProducer的服务端),BufferQueue通过找到一个合适的slot序号并为BufferSlot分配空间,然后通过Binder返回给客户端,客户端通过读取将值传递过去。客户端对缓冲区的操作会通过到服务端使用的是共享内存ashmem。

3.绘图流程:以开机动画为例

3.1 几个相关类的简单梳理

  • SurfaceComposerClient是每个应用程序与SurfaceFlinger之间的桥梁。不过SurfaceComposerClient只是一个封装,真正起作用的还是其内部的ISurfaceComposerClient
  • IGraphicBufferProducer是应用程序和BufferQueue之间的传输通道

TU 9-17

3.2 BootAnimation的构造方法

BootAnimation::BootAnimation() : Thread(false)
{
    mSession = new SurfaceComposerClient();
}

3.3 onFirstRef方法

BootAnimation继承自RefBase,所以当main函数中通过sp引用它的时候,会触发onFirstRef

void BootAnimation::onFirstRef() {
    //
    status_t err = mSession->linkToComposerDeath(this); 
}

linkToComposerDeath方法

status_t SurfaceComposerClient::linkToComposerDeath(
        const sp<IBinder::DeathRecipient>& recipient,
        void* cookie, uint32_t flags) {
    sp<ISurfaceComposer> sm(ComposerService::getComposerService());
    return sm->asBinder()->linkToDeath(recipient, cookie, flags);
}

3.4 readyToRun

 status_t BootAnimation::readyToRun() {
    mAssets.addDefaultAssets();

    sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
            ISurfaceComposer::eDisplayIdMain));
    DisplayInfo dinfo;
    status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo);
    if (status)
        return -1;

    // 创建一个SurfaceControl
    sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"),
            dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);

    SurfaceComposerClient::openGlobalTransaction();
    control->setLayer(0x40000000);
    SurfaceComposerClient::closeGlobalTransaction();
    //通过SurfaceControl获取一个Surface
    sp<Surface> s = control->getSurface();
 
    EGLint w, h, dummy;
    EGLint numConfigs;
    EGLConfig config;
    EGLSurface surface;
    EGLContext context;

    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

    eglInitialize(display, 0, 0);
    eglChooseConfig(display, attribs, &config, 1, &numConfigs);
    surface = eglCreateWindowSurface(display, config, s.get(), NULL);
    context = eglCreateContext(display, config, NULL, NULL);
    eglQuerySurface(display, surface, EGL_WIDTH, &w);
    eglQuerySurface(display, surface, EGL_HEIGHT, &h);

    if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE)
        return NO_INIT;

    mDisplay = display;
    mContext = context;
    mSurface = surface;
    mWidth = w;
    mHeight = h;
    mFlingerSurfaceControl = control;
    mFlingerSurface = s;
 

    return NO_ERROR;
}

3.5 createSurface

3.5.1 入口

sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"), dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);
sp<SurfaceControl> SurfaceComposerClient::createSurface(
        const String8& name,
        uint32_t w,
        uint32_t h,
        PixelFormat format,
        uint32_t flags)
{
    sp<SurfaceControl> sur;
    if (mStatus == NO_ERROR) {
        sp<IBinder> handle;
        sp<IGraphicBufferProducer> gbp;
        //这里handle和gbp是经过处理之后才真正有值
        status_t err = mClient->createSurface(name, w, h, format, flags,
                &handle, &gbp); 
        if (err == NO_ERROR) {//新建一个SurfaceControl
            sur = new SurfaceControl(this, handle, gbp);
        }
    }
    return sur;
} 

3.5.2 Binder过程

class BpSurfaceComposerClient : public BpInterface<ISurfaceComposerClient>
{
public:
    BpSurfaceComposerClient(const sp<IBinder>& impl)
        : BpInterface<ISurfaceComposerClient>(impl) {
    }

    virtual status_t createSurface(const String8& name, uint32_t w,
            uint32_t h, PixelFormat format, uint32_t flags,
            sp<IBinder>* handle,
            sp<IGraphicBufferProducer>* gbp) {
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
        data.writeString8(name);
        data.writeInt32(w);
        data.writeInt32(h);
        data.writeInt32(format);
        data.writeInt32(flags);
        remote()->transact(CREATE_SURFACE, data, &reply);
        *handle = reply.readStrongBinder();
        *gbp = interface_cast<IGraphicBufferProducer>(reply.readStrongBinder());
        return reply.readInt32();
    }


};

IMPLEMENT_META_INTERFACE(SurfaceComposerClient, "android.ui.ISurfaceComposerClient");

// ----------------------------------------------------------------------

status_t BnSurfaceComposerClient::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
     switch(code) {
        case CREATE_SURFACE: {
            CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
            String8 name = data.readString8();
            uint32_t w = data.readInt32();
            uint32_t h = data.readInt32();
            PixelFormat format = data.readInt32();
            uint32_t flags = data.readInt32();
            sp<IBinder> handle;
            sp<IGraphicBufferProducer> gbp;
            status_t result = createSurface(name, w, h, format, flags,
                    &handle, &gbp);
            reply->writeStrongBinder(handle);
            reply->writeStrongBinder(gbp->asBinder());
            reply->writeInt32(result);
            return NO_ERROR;
        } break;

        } break;
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
}

3.5.3 服务端createSurface

SurfaceComposerClient对应的Server端实现是Client(cpp)


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 {
        SurfaceFlinger* flinger;
        Client* client;
        sp<IBinder>* handle;
        sp<IGraphicBufferProducer>* gbp;
        status_t result;
        const String8& name;
        uint32_t w, h;
        PixelFormat format;
        uint32_t flags; 
    };
    //
    virtual bool handler() {
        //调用SurfaceFlinger处理消息
        result = flinger->createLayer(name, client, w, h, format, flags,
                handle, gbp);
        return true;
    }
    sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),
            name, this, w, h, format, flags, handle, gbp);
    //发送消息
    mFlinger->postMessageSync(msg);
    return static_cast<MessageCreateLayer*>( msg.get() )->getResult();
}

Client通过postMessageSync将消息发送给SurfaceFlinger处理

3.5.4 SurfaceFlinger的createLayer


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; 

    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
        case ISurfaceComposerClient::eFXSurfaceNormal:
            //createNormalLayer创建Layer
            result = createNormalLayer(client, name, w, h, flags, format, handle, gbp, &layer);
            break;
        case ISurfaceComposerClient::eFXSurfaceDim:
            result = createDimLayer(client, name, w, h, flags, handle, gbp, &layer);
            break;
 
    }

    if (result == NO_ERROR) {
        //2.addClientLayer
        addClientLayer(client, *handle, *gbp, layer);
        setTransactionFlags(eTransactionNeeded);
    }
    return result;
}

3.5.4.1 createNormalLayer


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)
{
    // initialize the surfaces
    switch (format) {
         //format赋值
    } 

    *outLayer = new Layer(this, client, name, w, h, flags);//生成一个layer
    status_t err = (*outLayer)->setBuffers(w, h, format, flags);//为layer设置缓冲区
    if (err == NO_ERROR) {
        //handle和gbp
        *handle = (*outLayer)->getHandle();
        *gbp = (*outLayer)->getBufferQueue();//这里获取到了bufferQueue
    } 
    return err;
} 

Layer的构造函数

Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
        const String8& name, uint32_t w, uint32_t h, uint32_t flags)
    :   contentDirty(false),
        sequence(uint32_t(android_atomic_inc(&sSequence))),
        mFlinger(flinger), 
        mFormat(PIXEL_FORMAT_NONE),
        mOpaqueLayer(true),
        mTransactionFlags(0),
        mQueuedFrames(0),
        mCurrentTransform(0),
        mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
        mCurrentOpacity(true),
        mRefreshPending(false),
        mFrameLatencyNeeded(false),
        mFiltering(false), 
        mProtectedByApp(false),
        mHasSurface(false),
        mClientRef(client)
{
    mCurrentCrop.makeInvalid();
    mFlinger->getRenderEngine().genTextures(1, &mTextureName);
    mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);

    uint32_t layerFlags = 0;
 

    mName = name;

    mCurrentState.active.w = w;
    mCurrentState.active.h = h;
    mCurrentState.active.crop.makeInvalid();
    mCurrentState.z = 0;
    mCurrentState.alpha = 0xFF;
    mCurrentState.layerStack = 0;
    mCurrentState.flags = layerFlags;
    mCurrentState.sequence = 0;
    mCurrentState.transform.set(0, 0);
    mCurrentState.requested = mCurrentState.active;

    // drawing state & current state are identical
    mDrawingState = mCurrentState;

    nsecs_t displayPeriod =
            flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
    mFrameTracker.setDisplayRefreshPeriod(displayPeriod);//设置刷新周期
}


3.5.4.2 addClientLayer

void SurfaceFlinger::addClientLayer(const sp<Client>& client,
        const sp<IBinder>& handle,
        const sp<IGraphicBufferProducer>& gbc,
        const sp<Layer>& lbc)
{
    //将layer和client绑定
    client->attachLayer(handle, lbc); 
    // add this layer to the current state list 
    mCurrentState.layersSortedByZ.add(lbc);
    mGraphicBufferProducerList.add(gbc->asBinder());
} 

3.5.5 new SurfaceControl

sur = new SurfaceControl(this, handle, gbp);


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

3.6 getSurface

sp<Surface> s = control->getSurface(); 
sp<Surface> SurfaceControl::getSurface() const
{
    Mutex::Autolock _l(mLock);
    if (mSurfaceData == 0) { 
        mSurfaceData = new Surface(mGraphicBufferProducer, false);
    }
    return mSurfaceData;
}
  • ISurfaceComposerClient:应用程序和SurfaceFlinger之间的通道,在应用程序中被封装在SurfaceComposerClient这个类中。这是一个匿名Binder,由应用程序调用SurfaceFlinger这个实名Binder的createConnection方法来获取到(具体是在SurfaceComposerClient的onFirstRef中),服务端的实现是SurfaceFlinger::Client.

  • IGraphicBufferProducer:由应用程序调用ISurfaceComposerClient::createSurface得到,同时在SurfaceFlinger这一进程中会有一个Layer被创建,代表了一个画面,ISurface就是控制这个画面的handle,它将保存在应用程序端的SurfaceControl中。

  • Surface:从逻辑上看,它是ISurface的使用者,从继承关系看,它是一个本地窗口。Surface内部持有IGraphicBufferProducer,也就是BufferQueue的实现接口,当EGL通过Surface完成某些功能时候,实际上是利用ISurface和IGraphicBufferProducer来取得远程服务端的对应服务,以完成EGL的请求

4.应用程序与BufferQueue的关系

当应用程序通过ISurfaceComposerClient通过createSurface来发起创建Surface请求的时候,SurfaceFlinger服务进程这一边会创建一个Layer,Layer代表了一个画面图层,所以Layer里一定有存储图层数据的地方。

getHandle和getBufferQueue

4.1 Handle

sp<IBinder> Layer::getHandle() {
    Mutex::Autolock _l(mLock);  
    mHasSurface = true; 
    class Handle : public BBinder, public LayerCleaner {
        wp<const Layer> mOwner;
    public:
        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
            : LayerCleaner(flinger, layer), mOwner(layer) {
        }
    }; 
    return new Handle(mFlinger, this);
}

Layer::LayerCleaner::~LayerCleaner() { 
    mFlinger->onLayerDestroyed(mLayer);
} 

Handle继承自LayerCleaner,当LayerCleaner或者Handle析构的时候会调用SurfaceFliger的onLayerDestroyed来进行图层清理工作。也就是说一旦没有人引用这个handle对象,系统就会开始清理工作。

4.2 BufferQueue来自哪里


sp<IGraphicBufferProducer> Layer::getBufferQueue() const {
    return mBufferQueue;//返回BufferQueue对象
}

在Layer的onFirstRef函数中

void Layer::onFirstRef() {
    // 创建一个BufferQueue供SurfaceFlingerConsumer使用
    mBufferQueue = new SurfaceTextureLayer(mFlinger);//BufferQueue的初始化
    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName);
    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
    mSurfaceFlingerConsumer->setFrameAvailableListener(this);
    mSurfaceFlingerConsumer->setName(mName); 
    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2或者3); 
    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
    updateTransformHint(hw);
}

相关文章

网友评论

    本文标题:GUI:BufferQueue

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