浅谈Android之SurfaceFlinger相关介绍(二)
来源:互联网 发布:淘宝店铺客服流程 编辑:程序博客网 时间:2024/05/21 11:27
3.2 绘图表面相关(Surface& Layer & BufferQueue)
App和SurfaceFlinger连接后,接下去就可以调用mClient->createSurface创建Surface, 然后SurfaceFlinger会对应的创建Layer,然后Layer内部会创建BufferQueueProducer和
BufferQueueConsumer,一个负责生产graphic buffer,一个负责消费
接下去看下它们之间简单的关系图
上面章节说过,Surface是一个派生自ANativeWindow的本地窗口,从图上可知,这个本地窗口其实只是一个代理,它对应的真正的绘图表面其实是SurfaceFlinger中的Layer,所以,Surface 的dequeuebuffer其实对应的就是从Layer关联的BufferQueueProducer获取graphicbuffer的过程,至于queuebuffer,对应则是将已经绘制好的graphic buffer通知并给到Layer关联的BufferQueueConsumer。
这里有两个问题要解决:
1) Surface如何从Layer关联的BufferQueueProducer获取buffer,以及如何将绘制完buffer通知到BufferQueueConsumer
2) Buffer如何在两个间快速传输?
SurfaceFlinger的解决方案是:
1) 直接将BufferQueueProducer定义成binderservice,派生自BnGraphicBufferProducer,然后在mClient.createSurface时,直接将BufferQueueProducer返回给App Client
2) 封装GraphicBuffer用来实现进程间数据共享
3.2.1 GraphicBuffer介绍
先介绍下GraphicBuffer是如何实现进程间数据共享:
1) 包含GraphicBufferAllocator实例,在GraphicBufferAllocator构造的时会打开
int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,&module);
gralloc_open(module, &mAllocDev);
然后调用GraphicBufferAllocator.alloc分配buffer,如果成功,会返回这个buffer对应的handle,对应数据类型为buffer_handle_t
这个是HAL层Gralloc提供的方法
2) 包含GraphicBufferMapper实例,同样的,GraphicBufferMapper在构造时会打开
int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,&module);
mAllocMod = (gralloc_module_t const *)module;
两个不同点是,一个调用gralloc_open,一个直接使用module指针,至于区别,Gralloc的代码没看过,不清楚
可以调用GraphicBufferMapper.lock并传入buffer_handle_t,它才会锁定对应的内存并返回首地址,然后内存使用结束后,调用GraphicBufferMapper.unlock解锁
3) GraphicBuffer要支持序列化(Flattenable),主要是序列化内部的buffer_handle_t值。
接着看类介绍
class GraphicBuffer
: public ANativeObjectBase< ANativeWindowBuffer, GraphicBuffer, RefBase >,
public Flattenable<GraphicBuffer>
{
ANativeObjectBase模板我觉得更多的还是为了兼容性设计的,由于ANativeWindowBuffer是个结构体,然后ANativeWindowBuffer内存布局的第一个变量是:
struct android_native_base_t common;
这个模板的用意是,通过定义getSelf来实现android_native_base_t类型的地址和GraphicBuffer之间的转换,还有,通过调用incRef和decRef,并传入android_native_base_t指针,由于android_native_base_t是类的第一个变量,可以通过reinterpret_cast又重新将其转换成GraphicBuffer对象,然后在对应的调用incStrong和decStrong,但是在我看的代码里面没发现对android_native_base_t使用,所以对其使用场景就不是很了解了。
不过通过类定义,可以很清晰的知道,GraphicBuffer派生自ANativeWindowBuffer,而且支持Flattenable
构造GraphicBuffer新分配buffer,得到buffer_handle_t:
GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
PixelFormat reqFormat, uint32_t reqUsage)
: BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
mInitCheck(NO_ERROR), mId(getUniqueId())
{
width =
height =
stride =
format =
usage = 0;
handle = NULL;
mInitCheck = initSize(w, h, reqFormat, reqUsage);
}
接着看initSize:
status_t GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat format,
uint32_t reqUsage)
{
GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();
status_t err = allocator.alloc(w, h, format, reqUsage, &handle, &stride);
if (err == NO_ERROR) {
this->width = w;
this->height = h;
this->format = format;
this->usage = reqUsage;
}
return err;
}
通过已有的buffer_handle_t来创建GraphicBuffer对象
GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
PixelFormat inFormat, uint32_t inUsage,
uint32_t inStride, native_handle_t* inHandle, bool keepOwnership)
: BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
mBufferMapper(GraphicBufferMapper::get()),
mInitCheck(NO_ERROR), mId(getUniqueId())
{
width = w;
height = h;
stride = inStride;
format = inFormat;
usage = inUsage;
handle = inHandle;
}
3.2.2 Surface,SurfaceControl, Layer和BufferQueue的创建
接下去,我们从SurfaceComposerClient.createSurface作为入口,从代码的角度完整的介绍整个创建流程
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;
status_t err = mClient->createSurface(name, w, h, format, flags,
&handle, &gbp);
ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
if (err == NO_ERROR) {
sur = new SurfaceControl(this, handle, gbp);
}
}
return sur;
}
直接将调用转发到mClient->createSurface,这是一个RPC调用,代码直接跑到SurfaceFlinger端对应的Client::createSurface,这个函数内部创建一个Message,然后添加到SurfaceFlinger的消息队列里,接着同步等待执行结束将结果返回,这个Message在执行时,会调用
SurfaceFlingerde.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)
{
//ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
if (int32_t(w|h) < 0) {
ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
int(w), int(h));
return BAD_VALUE;
}
status_t result = NO_ERROR;
sp<Layer> layer;
switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
case ISurfaceComposerClient::eFXSurfaceNormal:
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;
default:
result = BAD_VALUE;
break;
}
if (result == NO_ERROR) {
addClientLayer(client, *handle, *gbp, layer);
setTransactionFlags(eTransactionNeeded);
}
return result;
}
从代码可以看出,这里可以创建两个类型的Layer,Normal或者Dim, 这里基于
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) {
case PIXEL_FORMAT_TRANSPARENT:
case PIXEL_FORMAT_TRANSLUCENT:
format = PIXEL_FORMAT_RGBA_8888;
break;
case PIXEL_FORMAT_OPAQUE:
format = PIXEL_FORMAT_RGBX_8888;
break;
}
*outLayer = new Layer(this, client, name, w, h, flags);
status_t err = (*outLayer)->setBuffers(w, h, format, flags);
if (err == NO_ERROR) {
*handle = (*outLayer)->getHandle();
*gbp = (*outLayer)->getProducer();
}
ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err));
return err;
}
函数内通过new Layer创建Layer对象,接着在Layer::onFirstRef时创建BufferQueue
void Layer::onFirstRef() {
// Creates a custom BufferQueue for SurfaceFlingerConsumer to use
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer);
mProducer = new MonitoredProducer(producer, mFlinger);
mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
mSurfaceFlingerConsumer->setContentsChangedListener(this);
mSurfaceFlingerConsumer->setName(mName);
#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
#warning "disabling triple buffering"
mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
#else
mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
#endif
const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
updateTransformHint(hw);
}
接着调用BufferQueue::createBufferQueue创建BufferQueue:
void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
sp<IGraphicBufferConsumer>* outConsumer,
const sp<IGraphicBufferAlloc>& allocator) {
LOG_ALWAYS_FATAL_IF(outProducer == NULL,
"BufferQueue: outProducer must not be NULL");
LOG_ALWAYS_FATAL_IF(outConsumer == NULL,
"BufferQueue: outConsumer must not be NULL");
sp<BufferQueueCore> core(new BufferQueueCore(allocator));
LOG_ALWAYS_FATAL_IF(core == NULL,
"BufferQueue: failed to create BufferQueueCore");
sp<IGraphicBufferProducer> producer(new BufferQueueProducer(core));
LOG_ALWAYS_FATAL_IF(producer == NULL,
"BufferQueue: failed to create BufferQueueProducer");
sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core));
LOG_ALWAYS_FATAL_IF(consumer == NULL,
"BufferQueue: failed to create BufferQueueConsumer");
*outProducer = producer;
*outConsumer = consumer;
}
从函数可以看出,BufferQueueCore是核心,那它应该就负责BufferQueue的管理,然后
BufferQueueProducer负责从BufferQueueCore拿出空闲buffer,塞满数据后,给到
BufferQueueConsumer用于消费,也就是给到SurfaceFlinger进行混合输出
当然,上面是我认为的设计应该是这样的,但是实际从代码来看,Android这块代码的编写人员虽然设计成生产者,消费者,数据管理中心的模式,但是具体内部代码实现,感觉没有完全基于这一点,代码耦合度还是非常高的。
BufferQueueCore主要做了:
1) 创建BufferSlot数组,默认长度为64,用于存放分配的GraphicBuffer,还有Buffer状态
2) 初始化sp<IGraphicBufferAlloc> mAllocator;用于创建GraphicBuffer
其实就是初始化两个变量,其他比如寻找empty slot的操作,都是在BufferQueueProducer里完成的,这个后续介绍。
接着看代码,BufferQueueCore定义了如下变量用于保存bufferqueue:
BufferQueueDefs::SlotsType mSlots;
接着看SlotsType的定义:
namespace BufferQueueDefs {
// BufferQueue will keep track of at most this value of buffers.
// Attempts at runtime to increase the number of buffers past this
// will fail.
enum { NUM_BUFFER_SLOTS = 64 };
typedef BufferSlot SlotsType[NUM_BUFFER_SLOTS];
} // namespace BufferQueueDefs
可以看出,SlotsType对应的就是BufferSlot数组,注意,这个数组内部是没有数据的
接着看构造函数对mAllocator变量的初始化:
BufferQueueCore::BufferQueueCore(const sp<IGraphicBufferAlloc>& allocator) :
{
if (allocator == NULL) {
sp<ISurfaceComposer> composer(ComposerService::getComposerService());
mAllocator = composer->createGraphicBufferAlloc();
if (mAllocator == NULL) {
BQ_LOGE("createGraphicBufferAlloc failed");
}
}
}
默认allocator为null,所以这里直接调用composer->createGraphicBufferAlloc(),ISurfaceComposer上面介绍过,对应的就是SurfaceFlingerbinder service,所以对应调用到
SurfaceFlinger.createGraphicBufferAlloc:
sp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
{
sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
return gba;
}
这个函数直接构造了GraphicBufferAlloc对象并返回:
class GraphicBufferAlloc : public BnGraphicBufferAlloc {
public:
GraphicBufferAlloc();
virtual ~GraphicBufferAlloc();
virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
PixelFormat format, uint32_t usage, status_t* error);
};
看类派生自BnGraphicBufferAlloc,说明其是nativebinder service,可以跨进程调用,接着看
createGraphicBuffer是如何创建GraphicBuffer的:
sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
PixelFormat format, uint32_t usage, status_t* error) {
sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
status_t err = graphicBuffer->initCheck();
*error = err;
if (err != 0 || graphicBuffer->handle == 0) {
if (err == NO_MEMORY) {
GraphicBuffer::dumpAllocationsToSystemLog();
}
ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
"failed (%s), handle=%p",
w, h, strerror(-err), graphicBuffer->handle);
return 0;
}
return graphicBuffer;
}
一目了然,直接通过new GraphicBuffer创建对象并返回。
BufferQueueCore创建完成后,我们再回到void BufferQueue::createBufferQueue函数,接着就是基于BufferQueueCore创建:
sp<IGraphicBufferProducer> producer(new BufferQueueProducer(core));
sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core));
继续看BufferQueueProducer类定义:
class BufferQueueProducer : public BnGraphicBufferProducer,
private IBinder::DeathRecipient {
接着看BufferQueueConsumer定义:
class BufferQueueConsumer : public BnGraphicBufferConsumer {
可以看出,两个都是native binder service
至此,Layer创建结束,接下去重新回来SurfaceFlinger::createNormalLayer,看Layer创建成功后做了什么
*outLayer = new Layer(this, client, name, w, h, flags);
status_t err = (*outLayer)->setBuffers(w, h, format, flags);
if (err == NO_ERROR) {
*handle = (*outLayer)->getHandle();
*gbp = (*outLayer)->getProducer();
}
主要是返回两个native binder service,一个是BufferQueueProducer,这个app拿过去用于获取graphicbuffer,那handle是什么?继续看getHandle:
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);
}
直接返回一个Handle对象,由于它派生自BBinder,所以它是一个native binder service,可以作为这个Layer的唯一标识(原理看第二章),Handle内部保存SurfaceFlinger对象和关联的Layer对象。
接着回到SurfaceFlinger::createLayer, 看createNormalLayer结束后做了什么
if (result == NO_ERROR) {
addClientLayer(client, *handle, *gbp, layer);
setTransactionFlags(eTransactionNeeded);
}
继续看addClientLayer的实现:
void SurfaceFlinger::addClientLayer(const sp<Client>& client,
const sp<IBinder>& handle,
const sp<IGraphicBufferProducer>& gbc,
const sp<Layer>& lbc)
{
// attach this layer to the client
client->attachLayer(handle, lbc);
// add this layer to the current state list
Mutex::Autolock _l(mStateLock);
mCurrentState.layersSortedByZ.add(lbc);
mGraphicBufferProducerList.add(gbc->asBinder());
}
Client->attachLayer函数对应代码:
void Client::attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer)
{
Mutex::Autolock _l(mLock);
mLayers.add(handle, layer);
}
这个函数将新创建Layer对应的handle作为key,Layer对象作为value,保存到Client内部变量mLayers Map中,这样就可以通过Handle快速的找到对应的Layer
接着调用mCurrentState.layersSortedByZ.add(lbc);将新创建的Layer添加到Z order顺序列表中,同时调用mGraphicBufferProducerList.add(gbc->asBinder());将BufferQueueProducer添加到mGraphicBufferProducerList列表中。
到这里,SurfaceComposerClient::createSurface RPC调用在SurfaceFlinger这边已经执行结束,接着返回到AppClient端:
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;
status_t err = mClient->createSurface(name, w, h, format, flags,
&handle, &gbp);
ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
if (err == NO_ERROR) {
sur = new SurfaceControl(this, handle, gbp);
}
}
return sur;
通过mClient->createSurface返回Layer关联的handle和GraphicBufferProducer,然后基于这两个关键数据,创建SurfaceControl。
既然叫SurfaceControl,说明其既要包含Surface对象,又要负责对这个Surface关联的Layer进行状态控制;Surface对象主要用于图形绘制,这就涉及到GraphicBuffer的dequeue和queue,所以肯定要基于GraphicBufferProducer来创建;至于Surface关联Layer的控制,肯定要通过Handle来操作了。
所以SurfaceControl就是一个代理封装类,对应操作Handle关联Layer的代码:
status_t SurfaceControl::setAlpha(float alpha) {
status_t err = validate();
if (err < 0) return err;
return mClient->setAlpha(mHandle, alpha);
}
生成Surface的代码:
sp<Surface> SurfaceControl::getSurface() const
{
Mutex::Autolock _l(mLock);
if (mSurfaceData == 0) {
// This surface is always consumed by SurfaceFlinger, so the
// producerControlledByApp value doesn't matter; using false.
mSurfaceData = new Surface(mGraphicBufferProducer, false);
}
return mSurfaceData;
}
接着看Surface的构造函数:
Surface::Surface(
const sp<IGraphicBufferProducer>& bufferProducer,
bool controlledByApp)
: mGraphicBufferProducer(bufferProducer)
{
// Initialize the ANativeWindow function pointers.
ANativeWindow::setSwapInterval = hook_setSwapInterval;
ANativeWindow::dequeueBuffer = hook_dequeueBuffer;
ANativeWindow::cancelBuffer = hook_cancelBuffer;
ANativeWindow::queueBuffer = hook_queueBuffer;
ANativeWindow::query = hook_query;
ANativeWindow::perform = hook_perform;
ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
ANativeWindow::cancelBuffer_DEPRECATED = hook_cancelBuffer_DEPRECATED;
ANativeWindow::lockBuffer_DEPRECATED = hook_lockBuffer_DEPRECATED;
ANativeWindow::queueBuffer_DEPRECATED = hook_queueBuffer_DEPRECATED;
const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
}
Surface派生自ANativeWindow,ANativeWindow上头已经做过介绍,是一个结构体,需要在构造时手动对其函数变量进行赋值。就这样,Surface创建结束。
3.2.3 SurfacedequeueBuffer流程介绍
先简单介绍下整个流程:
1) Surface::dequeuebuffer直接调用mGraphicBufferProducer->dequeueBuffer获取free的buffer slot id并返回buffer对应的status
2) 如果buffer空间未分配或者status标明需要重新分配,则调用
mGraphicBufferProducer->requestBuffer(buf, &gbuf);
请求为这个buffer slot分配新空间
3) 最后将buffer slot关联的GraphicBuffer对象返回
上面只是描述了App端的流程,由于SurfaceFlinger端只是RPC执行对应的函数,这里就没有写出,直接通过代码来描述
先看Surface::dequeueBuffer函数部分代码:
int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
ATRACE_CALL();
ALOGV("Surface::dequeueBuffer");
int reqW;
int reqH;
bool swapIntervalZero;
uint32_t reqFormat;
uint32_t reqUsage;
{
Mutex::Autolock lock(mMutex);
reqW = mReqWidth ? mReqWidth : mUserWidth;
reqH = mReqHeight ? mReqHeight : mUserHeight;
swapIntervalZero = mSwapIntervalZero;
reqFormat = mReqFormat;
reqUsage = mReqUsage;
} // Drop the lock so that we can still touch the Surface while blocking in IGBP::dequeueBuffer
int buf = -1;
sp<Fence> fence;
status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, swapIntervalZero,
reqW, reqH, reqFormat, reqUsage);
Mutex::Autolock lock(mMutex);
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) {
ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result);
mGraphicBufferProducer->cancelBuffer(buf, fence);
return result;
}
}
*buffer = gbuf.get();
return OK;
}
大家可能会奇怪,最后GraphicBuffer怎么保存到android_native_buffer_t*类型的buffer里了呢? 这个之前有过介绍,GraphicBuffer派生自ANativeWindowBuffer,再看如下代码:
typedef ANativeWindowBuffer_t android_native_buffer_t;
所以,将GraphicBuffer返回给*buffer没有任何问题。
接着主要看看SurfaceFlinger端的代码,先看BufferQueueProducer::dequeueBuffer的实现,
函数先调用BufferQueueProducer::waitForFreeSlotThenRelock,这个函数主要代码
*found = BufferQueueCore::INVALID_BUFFER_SLOT;
int dequeuedCount = 0;
int acquiredCount = 0;
for (int s = 0; s < maxBufferCount; ++s) {
switch (mSlots[s].mBufferState) {
case BufferSlot::DEQUEUED:
++dequeuedCount;
break;
case BufferSlot::ACQUIRED:
++acquiredCount;
break;
case BufferSlot::FREE:
// We return the oldest of the free buffers to avoid
// stalling the producer if possible, since the consumer
// may still have pending reads of in-flight buffers
if (*found == BufferQueueCore::INVALID_BUFFER_SLOT ||
mSlots[s].mFrameNumber < mSlots[*found].mFrameNumber) {
*found = s;
}
break;
default:
break;
}
}
遍历mSlots中状态为free的buffer,如果找到,将buffer slot id,也就是数组索引返回
接着判断是否需要重新分配内存,如果需要,则重新创建GraphicBuffer并保存到对应的slot:
if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
status_t error;
BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot);
sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
width, height, format, usage, &error));
if (graphicBuffer == NULL) {
BQ_LOGE("dequeueBuffer: createGraphicBuffer failed");
return error;
}
{ // Autolock scope
Mutex::Autolock lock(mCore->mMutex);
if (mCore->mIsAbandoned) {
BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned");
return NO_INIT;
}
mSlots[*outSlot].mFrameNumber = UINT32_MAX;
mSlots[*outSlot].mGraphicBuffer = graphicBuffer;
} // Autolock scope
}
接着将slot id返回给App Client
接着通过调用BufferQueueProducer::requestBuffer并传入slot id拿到id对应的GraphicBuffer
status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
ATRACE_CALL();
BQ_LOGV("requestBuffer: slot %d", slot);
Mutex::Autolock lock(mCore->mMutex);
if (mCore->mIsAbandoned) {
BQ_LOGE("requestBuffer: BufferQueue has been abandoned");
return NO_INIT;
}
if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)",
slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
return BAD_VALUE;
} else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) {
BQ_LOGE("requestBuffer: slot %d is not owned by the producer "
"(state = %d)", slot, mSlots[slot].mBufferState);
return BAD_VALUE;
}
mSlots[slot].mRequestBufferCalled = true;
*buf = mSlots[slot].mGraphicBuffer;
return NO_ERROR;
}
3.2.4 SurfacequeueBuffer流程介绍
Surface通过DequeueBuffer拿到buffer后,接着在buffer上绘制图形数据,绘制好后通知SurfaceFlinger做后续的图形混合操作,通知的过程,其实就是queueBuffer的过程
流程很简单,直接看代码
int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
ATRACE_CALL();
ALOGV("Surface::queueBuffer");
Mutex::Autolock lock(mMutex);
int64_t timestamp;
bool isAutoTimestamp = false;
if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
isAutoTimestamp = true;
ALOGV("Surface::queueBuffer making up timestamp: %.2f ms",
timestamp / 1000000.f);
} else {
timestamp = mTimestamp;
}
int i = getSlotFromBufferLocked(buffer);
if (i < 0) {
return i;
}
// Make sure the crop rectangle is entirely inside the buffer.
Rect crop;
mCrop.intersect(Rect(buffer->width, buffer->height), &crop);
sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
IGraphicBufferProducer::QueueBufferOutput output;
IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp,
crop, mScalingMode, mTransform ^ mStickyTransform, mSwapIntervalZero,
fence, mStickyTransform);
status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
if (err != OK) {
ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
}
uint32_t numPendingBuffers = 0;
uint32_t hint = 0;
output.deflate(&mDefaultWidth, &mDefaultHeight, &hint,
&numPendingBuffers);
// Disable transform hint if sticky transform is set.
if (mStickyTransform == 0) {
mTransformHint = hint;
}
mConsumerRunningBehind = (numPendingBuffers >= 2);
return err;
}
这个函数先找到buffer对应的slot id,然后再通过mGraphicBufferProducer->queueBuffer传入slot id将对应的buffer入列
接着在BufferQueueProducer::quequeBuffer中,先根据slot id从mSlots中拿到对应的
GraphicBuffer
const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);
接着转换成BufferItem并放入BufferQueueCore的mQueue中
mCore->mQueue.push_back(item);
然后通过回调通知有新的Buffer可用:
frameAvailableListener = mCore->mConsumerListener;
frameAvailableListener->onFrameAvailable(item);
到这里,唯一的疑问就是mCore->mConsumerListener这个回调指向哪里?它是如何被设置的?我们回过头重新看BufferQueue::createBufferQueue的代码,它在创建BufferQueueCore之后,接着调用如下代码:
sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core));
基于core创建了consumer,接着看BufferQueueConsumer的构造函数
BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) :
mCore(core),
mSlots(core->mSlots),
mConsumerName() {}
简单的保存core和mSlots两个变量的引用
所以到这里,mCore->mConsumerListener还未被设置,接着看Layer::onFirstRef在调用
BufferQueue::createBufferQueue(&producer,&consumer);创建BufferQueue后做了什么:
void Layer::onFirstRef() {
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer);
mProducer = new MonitoredProducer(producer, mFlinger);
mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
mSurfaceFlingerConsumer->setContentsChangedListener(this);
mSurfaceFlingerConsumer->setName(mName);
}
先看SurfaceFlingerConsumer类的定义:
SurfaceFlingerConsumer : public GLConsumer:public ConsumerBase
先看SurfaceFlingerConsumer构造:
SurfaceFlingerConsumer(const sp<IGraphicBufferConsumer>& consumer,
uint32_t tex)
: GLConsumer(consumer, tex, GLConsumer::TEXTURE_EXTERNAL, false, false),
mTransformToDisplayInverse(false)
{}
接着看GLConsumer构造:
GLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t tex,
uint32_t texTarget, bool useFenceSync, bool isControlledByApp) :
ConsumerBase(bq, isControlledByApp),
{
ST_LOGV("GLConsumer");
memcpy(mCurrentTransformMatrix, mtxIdentity,
sizeof(mCurrentTransformMatrix));
mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS);
}
最后看ConsumerBase构造:
ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue, bool controlledByApp) :
mAbandoned(false),
mConsumer(bufferQueue) {
// Choose a name using the PID and a process-unique ID.
mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this);
sp<IConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener);
status_t err = mConsumer->consumerConnect(proxy, controlledByApp);
if (err != NO_ERROR) {
CB_LOGE("ConsumerBase: error connecting to BufferQueue: %s (%d)",
strerror(-err), err);
} else {
mConsumer->setConsumerName(mName);
}
}
终于找到你了,先将IGraphicBufferConsumer保存到mConsumer,接着调用
mConsumer->consumerConnect(proxy,controlledByApp);
virtual status_t BufferQueueConsumer::consumerConnect(const sp<IConsumerListener>& consumer,
bool controlledByApp) {
return connect(consumer, controlledByApp);
}
啥都没做,直接转到BufferQueueConsumer::connect:
status_t BufferQueueConsumer::connect(
const sp<IConsumerListener>& consumerListener, bool controlledByApp) {
if (consumerListener == NULL) {
BQ_LOGE("connect(C): consumerListener may not be NULL");
return BAD_VALUE;
}
mCore->mConsumerListener = consumerListener;
mCore->mConsumerControlledByApp = controlledByApp;
return NO_ERROR;
}
到这里清楚了,mCore->mConsumerListener实际指向的就是SurfaceFlingerConsumer,
SurfaceFlingerConsumer没有实现onFrameAvailable,咱们看父类的默认实现:
void ConsumerBase::onFrameAvailable(const BufferItem& item) {
CB_LOGV("onFrameAvailable");
sp<FrameAvailableListener> listener;
{ // scope for the lock
Mutex::Autolock lock(mMutex);
listener = mFrameAvailableListener.promote();
}
if (listener != NULL) {
CB_LOGV("actually calling onFrameAvailable");
listener->onFrameAvailable(item);
}
}
mFrameAvailableListener是一个若引用,通过对其尝试提升获取绑定对象,如果还存在,则调用其onFrameAvailable,所以,最终还是要看mFrameAvailableListener被设置成那个对象了,回到Layer创建SurfaceFlingerConsumer的地方:
mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
mSurfaceFlingerConsumer->setContentsChangedListener(this);
mSurfaceFlingerConsumer->setName(mName);
看setContentsChangedListener代码:
void SurfaceFlingerConsumer::setContentsChangedListener(
const wp<ContentsChangedListener>& listener) {
setFrameAvailableListener(listener);
Mutex::Autolock lock(mMutex);
mContentsChangedListener = listener;
}
接着看setFrameAvailableListener:
void ConsumerBase::setFrameAvailableListener(
const wp<FrameAvailableListener>& listener) {
CB_LOGV("setFrameAvailableListener");
Mutex::Autolock lock(mMutex);
mFrameAvailableListener = listener;
}
终于知道了mFrameAvailableListener最终被设置为Layer对象,也就是说,Surfacequeuebuffer最终被回调到了Layer::onFrameAvailable
void Layer::onFrameAvailable(const BufferItem& item) {
// Add this buffer from our internal queue tracker
{ // Autolock scope
Mutex::Autolock lock(mQueueItemLock);
mQueueItems.push_back(item);
}
android_atomic_inc(&mQueuedFrames);
mFlinger->signalLayerUpdate();
}
这里将buffer item添加到mQueueItems,然后通知SurfaceFlinger Layer内部有更新。
3.2.5 Layer状态参数设置
Layer提供了很多函数用以设置其自身状态,比如position,alpha值,但是如果每改动一次Layer的状态数据,就通知SurfaceFlinger调整Layer显示效果,这样明显是不合理的,所以,最好能提供批量处理,一次设置多个数据,然后集中提交。
上面说过,每个Layer在创建的时候,对应创建BBinder作为handler传给App client端,所以我们在配置Layer数据的时候,就可以通过Handle来指定要设置的Layer,然后和配置数据一同保存到ComposerState对象中,通过创建ComposerState数组,一次设置多个Layer的配置数据,最后调用ISurfaceComposer. setTransactionState把数组传到SurfaceFlinger,SurfaceFlinger.setTransactionState接着遍历数组,依次调用setClientStateLocked,
setClientStateLocked则会通过Handle从Client中找到对应的Layer,然后将ComposerState中保存的数据设置到Layer中。
下面介绍下上述操作在App Client端的封装:
SurfaceComposerClient::openGlobalTransaction();
control->setLayer(0x40000000);
SurfaceComposerClient::closeGlobalTransaction();
之前介绍过,Composer就是封装Layer数据配置相关操作的,所以上面代码,最终肯定跑到Composer对应实现中
void Composer::openGlobalTransactionImpl() {
{ // scope for the lock
Mutex::Autolock _l(mLock);
mTransactionNestCount += 1;
}
}
void Composer::closeGlobalTransactionImpl(bool synchronous) {
sp<ISurfaceComposer> sm(ComposerService::getComposerService());
Vector<ComposerState> transaction;
Vector<DisplayState> displayTransaction;
uint32_t flags = 0;
{ // scope for the lock
Mutex::Autolock _l(mLock);
mForceSynchronous |= synchronous;
if (!mTransactionNestCount) {
ALOGW("At least one call to closeGlobalTransaction() was not matched by a prior "
"call to openGlobalTransaction().");
} else if (--mTransactionNestCount) {
return;
}
transaction = mComposerStates;
mComposerStates.clear();
displayTransaction = mDisplayStates;
mDisplayStates.clear();
if (mForceSynchronous) {
flags |= ISurfaceComposer::eSynchronous;
}
if (mAnimation) {
flags |= ISurfaceComposer::eAnimation;
}
mForceSynchronous = false;
mAnimation = false;
}
sm->setTransactionState(transaction, displayTransaction, flags);
}
openGlobalTransactionImpl啥也没做,就是将mTransactionNestCount加1,这个变量用来确保open和close操作必须要成对出现。
closeGlobalTransactionImpl首先mComposerStates和mDisplayStates拷贝到对应的transaction和displayTransaction中,接着清除mComposerStates和mDisplayStates内的数据,接着调用sm->setTransactionState将transaction和displayTransaction的数据传到SurfaceFlinger
接着看control->setLayer(0x40000000);
status_t SurfaceControl::setLayer(int32_t layer) {
status_t err = validate();
if (err < 0) return err;
return mClient->setLayer(mHandle, layer);
}
直接调用SurfaceComposerClient::setLayer
status_t SurfaceComposerClient::setLayer(const sp<IBinder>& id, int32_t z) {
return getComposer().setLayer(this, id, z);
}
接着到Composer::setLayer
status_t Composer::setLayer(const sp<SurfaceComposerClient>& client,
const sp<IBinder>& id, int32_t z) {
Mutex::Autolock _l(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
if (!s)
return BAD_INDEX;
s->what |= layer_state_t::eLayerChanged;
s->z = z;
return NO_ERROR;
}
通过getLayerStateLocked拿到layer_state_t数据结构指针
layer_state_t* Composer::getLayerStateLocked(
const sp<SurfaceComposerClient>& client, const sp<IBinder>& id) {
ComposerState s;
s.client = client->mClient;
s.state.surface = id;
ssize_t index = mComposerStates.indexOf(s);
if (index < 0) {
// we don't have it, add an initialized layer_state to our list
index = mComposerStates.add(s);
}
ComposerState* const out = mComposerStates.editArray();
return &(out[index].state);
很简单,先通过client和handle信息判断Layer是否已经存在mComposerStates中,如果不存在,则将其添加到mComposerStates中,然后返回ComposerState内部state变量的地址。
接着通过layer_state_t*指针修改数据即可
- 浅谈Android之SurfaceFlinger相关介绍(二)
- 浅谈Android之SurfaceFlinger相关介绍(一)
- 浅谈Android之SurfaceFlinger相关介绍(三)
- 浅谈Android之Activity相关介绍
- Android SurfaceFlinger 学习之路(二)----SurfaceFlinger概述
- 浅谈Android之Binder原理介绍(二)
- 浅谈Android之Activity 窗口显示流程介绍(二)
- Android SurfaceFlinger介绍
- Android SurfaceFlinger 介绍
- Android4.4深入浅出之SurfaceFlinger (二)
- Android4.4深入浅出之SurfaceFlinger (二)
- 【Android】Android SurfaceFlinger之SurfaceFlinger启动过程
- Binder和SurfaceFlinger以及SystemServer介绍-android学习之旅(79)
- Android GDI之SurfaceFlinger
- Android GDI之SurfaceFlinger
- Android SurfaceFlinger之SurfaceFlinger启动过程
- Android O 前期预研之二:HIDL相关介绍
- Android O 前期预研之二:HIDL相关介绍
- Java:String、StringBuffer和StringBuilder的区别
- CentOS7安装ActiveMQ
- MSM8225 thermal设计
- CVBS两种电路-记录
- AndroidUI—三种动画实现
- 浅谈Android之SurfaceFlinger相关介绍(二)
- VS2015安装signalR
- Ubuntu14.04虚拟网络设备TUN安装
- HTML和CSS高级指南整理翻译(08) 一 过渡与动画
- PL/SQL 数值类型
- java并发多线程
- eclipse配置maven
- 安装配置PHPUnit+Composer
- 校门外的树