本文均属自己阅读源码的点滴总结,转账请注明出处谢谢。
欢迎和大家交流。qq:1037701636 email:[email protected]
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 listener;
{ // scope for the lock
Mutex::Autolock lock(mMutex);
listener = mFrameAvailableListener;
}
if (listener != NULL) {
CB_LOGV("actually calling onFrameAvailable");
listener->onFrameAvailable();
}
}
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从应用层到底层的整个绘图,显示的大致流程。