Android4.2.2 SurfaceFlinger本地的FramebufferSurface实现真正的显示

Android源码版本Version:4.2.2; 硬件平台 全志A31

 

 

FrameBufferSurface类,SurfaceFlinger处的本地的帧缓存,实际意义上的显存

FramebufferSurface::FramebufferSurface(HWComposer& hwc, int disp) :
    ConsumerBase(new BufferQueue(true, new GraphicBufferAlloc())),//本地的BufferQueue以及分配器
    mDisplayType(disp),
    mCurrentBufferSlot(-1),
    mCurrentBuffer(0),
    mHwc(hwc)
{
    mName = FramebufferSurface;
    mBufferQueue->setConsumerName(mName);
    mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |
                                       GRALLOC_USAGE_HW_RENDER |
                                       GRALLOC_USAGE_HW_COMPOSER);
    mBufferQueue->setDefaultBufferFormat(mHwc.getFormat(disp));
    mBufferQueue->setDefaultBufferSize(mHwc.getWidth(disp),  mHwc.getHeight(disp));
    mBufferQueue->setSynchronousMode(true);
    mBufferQueue->setDefaultMaxBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS);
}

FrameBufferSurface看上去很类似于SurfaceTexture(伴随着一个Layer的创建,供应用程序在SF处创建),两者都继承了ConsumerBase,故都为消费者。

SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,
        GLenum texTarget, bool useFenceSync, const sp &bufferQueue) :
    ConsumerBase(bufferQueue == 0 ? new BufferQueue(allowSynchronousMode) : bufferQueue),
{
  ...... 
}

区别在于SurfaceFLinger本地的这个FrameBufferSurface拥有自己的BufferQueue,以及一个GraphicBufferAlloc图形缓存分配类。

 

step2: 继续来看ConsumerBase类:

ConsumerBase::ConsumerBase(const sp& bufferQueue) :
        mAbandoned(false),
        mBufferQueue(bufferQueue) {
    // Choose a name using the PID and a process-unique ID.
    mName = String8::format(unnamed-%d-%d, getpid(), createProcessUniqueId());

    // Note that we can't create an sp<...>(this) in a ctor that will not keep a
    // reference once the ctor ends, as that would cause the refcount of 'this'
    // dropping to 0 at the end of the ctor.  Since all we need is a wp<...>
    // that's what we create.
    wp listener;
    sp proxy;
    listener = static_cast(this);
    proxy = new BufferQueue::ProxyConsumerListener(listener);//新建一个监听代理

    status_t err = mBufferQueue->consumerConnect(proxy);//创建一个ConsumerListener代理
    if (err != NO_ERROR) {
        CB_LOGE(SurfaceTexture: error connecting to BufferQueue: %s (%d),
                strerror(-err), err);
    } else {
        mBufferQueue->setConsumerName(mName);
    }
}

这里将proxy这个代理设置到mBufferQueue中去,使得mBufferQueue中的mConsumerListener = ProxyConsumerListener对象,而该对象中的mConsumerListener对象即为传入的this对象FrameBufferSurface。

 

step3: 本地的FrameBufferSurface在queueBuffer中的使用

在文章Android4.2.2 SurfaceFlinger之图形渲染queueBuffer实现和VSYNC的存在感 里面提到最后会调用

    // call back without lock held
    if (listener != 0) {
        listener->onFrameAvailable();//发布当前帧可以给消费者
    }

故依次调用为ProxyConsumerListener->onFrameAvailable, 在到FramebufferSurface::onFrameAvailable()函数。

 

而在SurfaceTexture的处理中,是这样的:

故依次调用为ProxyConsumerListener->onFrameAvailable, 在到ConsumerBase::onFrameAvailable()函数,因为SurfaceTexture没有override ConsumerBase类的onFrameAvailable()成员函数。但是最终还是会提交给SurfaceTexture,原因如下:ConsumerBase自己的一个mFrameAvailableListener成员变量被初始化为了Layer的一个内部类FrameQueuedListener。使得最终的处理复杂化。

void ConsumerBase::onFrameAvailable() {
    CB_LOGV(onFrameAvailable);

    sp<frameavailablelistener> listener;
    { // scope for the lock
        Mutex::Autolock lock(mMutex);
        listener = mFrameAvailableListener;
    }

    if (listener != NULL) {
        CB_LOGV(actually calling onFrameAvailable);
        listener->onFrameAvailable();
    }
}
</frameavailablelistener>
void Layer::onFirstRef()
{
    LayerBaseClient::onFirstRef();//基类LayerBaseClient

    struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener {//内部类继承FrameAvailableListener
        FrameQueuedListener(Layer* layer) : mLayer(layer) { }
    private:
        wp mLayer;
        virtual void onFrameAvailable() {
            sp that(mLayer.promote());
            if (that != 0) {
                that->onFrameQueued();//调用Layer的onFrameQueued
            }
        }
    };    mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));//新建立一个帧队列监听

最终是回调到layer的onFrameQueued.故这里说明了应用层的queueBuffer只是通知了SurfaceFlinger当前的Layer图层有图形缓存一帧入列了。请求SF他来做最终的显示。

 

step4: SurfaceFLinger在处理好所有的应用层的layer函数后就要准备送显,而送显的buffer也是通过OpenGl Es的queueBuffer来触发的,只是这里直接调用了step3中说明的流程。

void FramebufferSurface::onFrameAvailable() {
    sp buf;
    sp acquireFence;
    status_t err = nextBuffer(buf, acquireFence);
    if (err != NO_ERROR) {
        ALOGE(error latching nnext FramebufferSurface buffer: %s (%d),
                strerror(-err), err);
        return;
    }
    err = mHwc.fbPost(mDisplayType, acquireFence, buf);//实现buffer的渲染
    if (err != NO_ERROR) {
        ALOGE(error posting framebuffer: %d, err);
    }
}

 

setp5: nextBuffer应该是获取一个最终要显示的图形缓存去,看到fbPost函数应该是送显,先来看看nextBuffer()函数:

status_t FramebufferSurface::nextBuffer(sp& outBuffer, sp& outFence) {
    Mutex::Autolock lock(mMutex);

    BufferQueue::BufferItem item;
    status_t err = acquireBufferLocked(&item);
    if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
        outBuffer = mCurrentBuffer;
        return NO_ERROR;
    } else if (err != NO_ERROR) {
        ALOGE(error acquiring buffer: %s (%d), strerror(-err), err);
        return err;
    }

   .............
       if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT &&
        item.mBuf != mCurrentBufferSlot) {
        // Release the previous buffer.
        err = releaseBufferLocked(mCurrentBufferSlot, EGL_NO_DISPLAY,
                EGL_NO_SYNC_KHR);
        if (err != NO_ERROR && err != BufferQueue::STALE_BUFFER_SLOT) {
            ALOGE(error releasing buffer: %s (%d), strerror(-err), err);
            return err;
        }
    }
    mCurrentBufferSlot = item.mBuf;
    mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer;
    outFence = item.mFence;
    outBuffer = mCurrentBuffer;
    return NO_ERROR;
}

函数首先调用acquireBufferLocked来获取本地最终BufferQueue中的图形缓存并保存到item.

status_t ConsumerBase::acquireBufferLocked(BufferQueue::BufferItem *item) {
    status_t err = mBufferQueue->acquireBuffer(item);
    if (err != NO_ERROR) {
        return err;
    }

    if (item->mGraphicBuffer != NULL) {
        mSlots[item->mBuf].mGraphicBuffer = item->mGraphicBuffer;
    }

    mSlots[item->mBuf].mFence = item->mFence;

    CB_LOGV(acquireBufferLocked: -> slot=%d, item->mBuf);

    return OK;
}

 

setp6:fbpost()函数

int HWComposer::fbPost(int32_t id,
        const sp& acquireFence, const sp& buffer) {
    if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
        return setFramebufferTarget(id, acquireFence, buffer);
    } else {
        if (acquireFence != NULL) {
            acquireFence->waitForever(1000, HWComposer::fbPost);
        }
        return mFbDev->post(mFbDev, buffer->handle);//framebuffer的正在渲染
    }
}

调用framebuffer的帧缓存设备的psot,完成这个buffer的显示。在gralloc模块中对应于fb_post()函数,由于不同的硬件对显示的底层机制由所区别,故fb_post()的显示也会有差别,但基本的原理就是触发当前的图像帧缓存送显而已。

 

step7:最后用一图来解释SurfaceFlinger从应用层到底层的整个绘图,显示的大致流程。

data-cke-saved-src=/uploadfile/Collfiles/20140327/201403270911373.jpg

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值