本文均属自己阅读源码的点滴总结,转账请注明出处谢谢。
欢迎和大家交流。qq:1037701636 email:gzzaigcn2012@gmail.com
Android源码版本Version:4.2.2; 硬件平台 全志A31
之前的博文在BootAnimation的基础上来到了SurfaceFlinger端的Surface的创建过程,具体实现由Client的createSurface来完成。其实所谓在客户端的Surface在服务端是以Layer图层的名字存在。
sp<ISurface> Client::createSurface(
ISurfaceComposerClient::surface_data_t* params,
const String8& name,
uint32_t w, uint32_t h, PixelFormat format,
uint32_t flags)
{
/*
* createSurface must be called from the GL thread so that it can
* have access to the GL context.
*/
class MessageCreateLayer : public MessageBase {
sp<ISurface> result;
SurfaceFlinger* flinger;
ISurfaceComposerClient::surface_data_t* params;
Client* client;
const String8& name;
uint32_t w, h;
PixelFormat format;
uint32_t flags;
public:
MessageCreateLayer(SurfaceFlinger* flinger,
ISurfaceComposerClient::surface_data_t* params,
const String8& name, Client* client,
uint32_t w, uint32_t h, PixelFormat format,
uint32_t flags)
: flinger(flinger), params(params), client(client), name(name),
w(w), h(h), format(format), flags(flags)
{
}
sp<ISurface> getResult() const { return result; }
virtual bool handler() {
result = flinger->createLayer(params, name, client,
w, h, format, flags);//消息处理时创建一个layer
return true;
}
};
sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),
params, name, this, w, h, format, flags);//新建一个MessageCreateLayer对象,赋值给基类
mFlinger->postMessageSync(msg);//创建layer的消息由SF来完成
return static_cast<MessageCreateLayer*>( msg.get() )->getResult();
}
该函数的实现看上去貌似有一些复杂,首先创建一个继承与MessageBase的创建图层Layer消息类,我们从构造函数分析一步步的入手。
step1:说道SurfaceFlinger侧的消息处理机制,即可用回想到之前的博文Android4.2.2 SurfaceFlinger的相关事件和消息处理机制一文,是否知道最终都提交给SF来完成消息的处理。看这个函数mFlinger->postMessageSync(msg),看着就知道是发出一个同步的消息。
status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
nsecs_t reltime, uint32_t flags) {
status_t res = mEventQueue.postMessage(msg, reltime);
if (res == NO_ERROR) {
msg->wait();
}
return res;
}
果然这里使用了SF的成员变量MessageQueue mEventQueue来发送消息
status_t MessageQueue::postMessage(
const sp<MessageBase>& messageHandler, nsecs_t relTime)
{
const Message dummyMessage;
if (relTime > 0) {
mLooper->sendMessageDelayed(relTime, messageHandler, dummyMessage);
} else {
mLooper->sendMessage(messageHandler, dummyMessage);//使用looper发送消息,向消息队列发送消息
}
return NO_ERROR;
}
void Looper::sendMessage(const sp<MessageHandler>& handler, const Message& message) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
sendMessageAtTime(now, handler, message); //及时发送消息
}
这里传入的重点是messageHanler这个变量理解为消息句柄,按照这个调用流程实际是MessageCreateLayer这个对象。
到了这里基本就和之前的SF消息处理机制的RefreshEvent相似起来了,可以查看我对SF的消息和事件处理机制总结出来的图,最终还是回到
handler->handleMessage(message);//MessageHandler消息的handle处理,那么这里对应的这个handle是什么呢,又如何调用handleMessage呢,我们发现在这里:
void MessageBase::handleMessage(const Message&) {
this->handler();//调用继承类的多态的handle,this指向最初的对象,基类指针访问派生类对象时,调用派生类的函数
barrier.open();
};
上述的msg传入分别转为MessageBase,在转为MessageHandle。而我们知道他处于这个逐级继承的关系,而MessageBase的成员函数MessageHandle并没有被继承重载故这个MessageCreateLayer对象msg实际调用的是MessageBase的handleMessage,而这个函数的实现内部调用了this->handle,容易知道这个handleMessage实际是被继承到了MessageCreateLayer类的msg这个对象中。因此最终回到了MessageCreateLayer的handle之中。
step2.转了这么多弯路,从Client侧调用createSurface再打发送消息让SurfaceFlinger进行消息处理,再回到MessageCreateLayer的handle,而handle处理中却发现实际还是把处理提交给了SurfaceFlinger。
virtual bool handler() {
result = flinger->createLayer(params, name, client,
w, h, format, flags);//消息处理时创建一个layer
return true;
}
接着看SurfaceFlinger的createLayer函数:
sp<ISurface> SurfaceFlinger::createLayer(
ISurfaceComposerClient::surface_data_t* params,
const String8& name,
const sp<Client>& client,
uint32_t w, uint32_t h, PixelFormat format,
uint32_t flags)
{
sp<LayerBaseClient> layer;
sp<ISurface> surfaceHandle;
if (int32_t(w|h) < 0) {
ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
int(w), int(h));
return surfaceHandle;
}
//ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
case ISurfaceComposerClient::eFXSurfaceNormal:
layer = createNormalLayer(client, w, h, flags, format);//new创建一个layer,指向layer
break;
case ISurfaceComposerClient::eFXSurfaceBlur:
case ISurfaceComposerClient::eFXSurfaceDim:
layer = createDimLayer(client, w, h, flags);
break;
case ISurfaceComposerClient::eFXSurfaceScreenshot:
layer = createScreenshotLayer(client, w, h, flags);
break;
}
if (layer != 0) {
layer->initStates(w, h, flags);
layer->setName(name);
ssize_t token = addClientLayer(client, layer);//把这个layer层添加到client中并加入Z轴
surfaceHandle = layer->getSurface();//通过Layer
if (surfaceHandle != 0) {
params->token = token;
params->identity = layer->getIdentity();//layer图层的id
}
setTransactionFlags(eTransactionNeeded);
}
return surfaceHandle;
}
step3 : createNormalLayer函数处理,实际的Layer图层对象建立所在。
里看Layer的成员函数onFirstRef():
void Layer::onFirstRef()
{
LayerBaseClient::onFirstRef();//基类LayerBaseClient
struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener {//内部类继承FrameAvailableListener
FrameQueuedListener(Layer* layer) : mLayer(layer) { }
private:
wp<Layer> mLayer;
virtual void onFrameAvailable() {
sp<Layer> that(mLayer.promote());
if (that != 0) {
that->onFrameQueued();//调用Layer的onFrameQueued
}
}
};
// Creates a custom BufferQueue for SurfaceTexture to use
sp<BufferQueue> bq = new SurfaceTextureLayer();//新建一个SurfaceTextureLayer,即BufferQueue
mSurfaceTexture = new SurfaceTexture(mTextureName, true,
GL_TEXTURE_EXTERNAL_OES, false, bq);
mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));//新建立一个帧队列监听
mSurfaceTexture->setSynchronousMode(true);//支持同步模式
#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
#warning "disabling triple buffering"
mSurfaceTexture->setDefaultMaxBufferCount(2);
#else
mSurfaceTexture->setDefaultMaxBufferCount(3);
#endif
const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
updateTransformHint(hw);
}
在这个函数里面有个内部结构体FrameQueuedListener,帧队列监听。这里先关注SurfaceTextureLayer和SurfaceTexture两个类对象,分别代表着BufferQueue和ConsumerBase两个对象,这里先直接提出Layer相关的UML图,帮助下面的分析吧。
step4:先来看看SurfaceTextureLayer的构造过程吧:
SurfaceTextureLayer的构造其实是为BufferQueue而服务的,这里继续看BufferQueue这个核心类的构造过程吧。
BufferQueue::BufferQueue(bool allowSynchronousMode,
const sp<IGraphicBufferAlloc>& allocator) :
.......
mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888),
mConsumerUsageBits(0),
mTransformHint(0)
{
// Choose a name using the PID and a process-unique ID.
mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
ST_LOGV("BufferQueue");
if (allocator == NULL) {
sp<ISurfaceComposer> composer(ComposerService::getComposerService());
mGraphicBufferAlloc = composer->createGraphicBufferAlloc();//创建GraphicBuffer
if (mGraphicBufferAlloc == 0) {
ST_LOGE("createGraphicBufferAlloc() failed in BufferQueue()");
}
} else {
mGraphicBufferAlloc = allocator;
}
}
BufferQueue缓存队列的创建在于又一次调用SF(ComposerService::getComposerService是熟悉的BpSurfaceComposer,即SF在客户端的代理)来完成图形缓冲区的申请和分配,通过SF端的GraphicBufferAllocation来完成。实现如下:
sp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
{
sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());//图形缓存的申请
return gba;
}
由SF创建的图像缓存被保存在BufferQueue的成员变量里面。
step5:接着看SurfaceTexture类,即所谓的表面纹理。该类继承了ConsumerBase,所谓的消费者模式,这里主要指的是对图形缓存的渲染。
ConsumerBase::ConsumerBase(const sp<BufferQueue>& 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<BufferQueue::ConsumerListener> listener;
sp<BufferQueue::ConsumerListener> proxy;
listener = static_cast<BufferQueue::ConsumerListener*>(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);
}
}
看到这里有监听和代理两个变量,listener直接从之前创建的Bufferqueue转换过来,而proxy这里是创建一个监听的远程代理,并保存在BufferQueue的mConsumerListener变量中。
接着看SurfaceTexture类的构造函数:
SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,
GLenum texTarget, bool useFenceSync, const sp<BufferQueue> &bufferQueue) :
ConsumerBase(bufferQueue == 0 ? new BufferQueue(allowSynchronousMode) : bufferQueue),
mCurrentTransform(0),
mCurrentTimestamp(0),
mFilteringEnabled(true),
mTexName(tex),
#ifdef USE_FENCE_SYNC
mUseFenceSync(useFenceSync),
#else
mUseFenceSync(false),
#endif
mTexTarget(texTarget),
mEglDisplay(EGL_NO_DISPLAY),
mEglContext(EGL_NO_CONTEXT),
mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT),
mAttached(true)
{
ST_LOGV("SurfaceTexture");
memcpy(mCurrentTransformMatrix, mtxIdentity,
sizeof(mCurrentTransformMatrix));
mBufferQueue->setConsumerUsageBits(DEFAULT_USAGE_FLAGS);
}
回到Layer类的构造函数,mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this))分析这个处理过程,新建一个帧队列监听保存到Layer对象的mFrameAvailableListener中。
step6:在完成Layer对象的初始化后,调用了这个status_t err = layer->setBuffers(w, h, format, flags);设置相关Buffer的信息。再回到SurfaceFlinger::createLayer这个最初的Layer调用函数这里,分析下面几个函数:
ssize_t token = addClientLayer(client, layer);//把这个layer层添加到client中并加入Z轴
surfaceHandle = layer->getSurface();//通过Layer
将上面创建好的Layer对象和当前在和客户端交互的Client关联在一起。而这个surfaceHandle是最终返回给客户端请求的Surface对象,这里需要注意的是getSurface的对象layer是Layer派生类,继承了LayerBaseClient,发现getSuface没有被重载,则如下调用
sp<ISurface> LayerBaseClient::getSurface()
{
sp<ISurface> s;
Mutex::Autolock _l(mLock);
LOG_ALWAYS_FATAL_IF(mHasSurface,
"LayerBaseClient::getSurface() has already been called");
mHasSurface = true;
s = createSurface();//调用派生类的createSurface函数
mClientSurfaceBinder = s->asBinder();//BBinder
return s;
}
而这里的createSurface其实是this->createSurface,故重载后基类函数调用成员函数时调用的是派生类的该成员函数createSurface
sp<ISurface> Layer::createSurface()
{
class BSurface : public BnSurface, public LayerCleaner {
wp<const Layer> mOwner;
virtual sp<ISurfaceTexture> getSurfaceTexture() const {
sp<ISurfaceTexture> res;
sp<const Layer> that( mOwner.promote() );
if (that != NULL) {
res = that->mSurfaceTexture->getBufferQueue();//调用类SurfaceTexture的基类ConsumerBase
}
return res;//返回的是mBufferQueue,类为SurfaceTexturelayer
}
public:
BSurface(const sp<SurfaceFlinger>& flinger,
const sp<Layer>& layer)
: LayerCleaner(flinger, layer), mOwner(layer) { }
};
sp<ISurface> sur(new BSurface(mFlinger, this));
return sur;
}
最终返回的实际是一个内部类BSurface,继承了BnSurface,故也是一个本地的BBinder。后面一定会用他来进行Binder间的通信。
step7:到这里就返回到了BootAnimation的readyToRun函数:
sp<ISurface> surface = mClient->createSurface(&data, name,
w, h, format, flags);//对应的由SF侧的錍lient来完成, BpSurface
最终返回的可以看到是一个BpSurface类对象,和上面说的Binder通信相呼应起来。surface对象的创建最终都提交给了SurfaceControl,都交给他来进行进一步的界面操作。
step8:接着看 sp<Surface> s = control->getSurface();通过上面新建的sufacecontrol类对象,来获得Surface
sp<Surface> SurfaceControl::getSurface() const
{
Mutex::Autolock _l(mLock);
if (mSurfaceData == 0) {
sp<SurfaceControl> surface_control(const_cast<SurfaceControl*>(this));
mSurfaceData = new Surface(surface_control);
}
return mSurfaceData;
}
那么这个Surface类到底做了什么呢?看构造函数:
Surface::Surface(const sp<SurfaceControl>& surface)
: SurfaceTextureClient(),//父类调用SurfaceTextureClient::init();完成ANativeWindow的初始化
mSurface(surface->mSurface),
mIdentity(surface->mIdentity)
{
sp<ISurfaceTexture> st;
if (mSurface != NULL) {
st = mSurface->getSurfaceTexture();//调用BpSurface,获得远程的Bnsurface处理后的BpSurfaceTexture
}
init(st);//Surface初始化
}
看到这个SurfaceTexture是否有些熟悉,的确刚才在step5里讲到SF侧在Layer对象创建是会创建相关的表面纹理对象,这应该是在客户端侧的一个操作类对象,看看其初始化过程:
class SurfaceTextureClient
: public ANativeObjectBase<ANativeWindow, SurfaceTextureClient, RefBase>
{
public:
SurfaceTextureClient(const sp<ISurfaceTexture>& surfaceTexture);
这个类继承了一个ANativeWindow,理解为本地的窗口,也就是说在客户端这边将直接对其进行相关的操作。
SurfaceTextureClient::SurfaceTextureClient() {
SurfaceTextureClient::init();
}
void SurfaceTextureClient::init() {
// 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;//本地窗口ANativeWindow函数的回调初始化
......
}
上述是整个构造函数,只是完成了本地窗口ANativeWindow的回调初始化,后续对缓冲区等的操作都是在这些函数中。
接着看mSurface->getSurfaceTexture():这里的mSurface就是之前在调用SurfaceComposerClient::createSurface完成的,之前分析的是服务端在本地的一个BSurface匿名服务代理,故这里会由BnSurface来完成。
status_t BnSurface::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
case GET_SURFACE_TEXTURE: {
CHECK_INTERFACE(ISurface, data, reply);
reply->writeStrongBinder( getSurfaceTexture()->asBinder() );
return NO_ERROR;
}
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
他的意义在于最终返回是的BpSurfaceTexture,使得客户端也有了自己的表面纹理对象。
virtual sp<ISurfaceTexture> getSurfaceTexture() const {
sp<ISurfaceTexture> res;
sp<const Layer> that( mOwner.promote() );
if (that != NULL) {
res = that->mSurfaceTexture->getBufferQueue();//调用类SurfaceTexture的基类ConsumerBase
}
return res;//返回的是mBufferQueue,类为SurfaceTexturelayer
}
可以看到这个that->mSurfaceTexture->getBufferQueue(),that是之前创建的Layer对象,而mSUrfaceTexture是在SurfaceTextureLayer(BufferQueue所在)
sp<BufferQueue> getBufferQueue() const {
return mBufferQueue;
}
即最终getSurfaceTexture,所谓的表面纹理获取就是直接返回了BufferQueue。而BufferQueue刚好继承了BpSurfaceTexture,且以匿名Binder对象返回到应用程序的客户端。
BpSurface(const sp<IBinder>& impl)
: BpInterface<ISurface>(impl)
{
}
virtual sp<ISurfaceTexture> getSurfaceTexture() const {
Parcel data, reply;
data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
remote()->transact(GET_SURFACE_TEXTURE, data, &reply);
return interface_cast<ISurfaceTexture>(reply.readStrongBinder());//在客户端是BpSurfaceTexture,服务端是SurfaceTextureLayer
}
};
即返回的是一个BpSurfaceTexture,而会最终在init(st)里实现,维护到SurfaceTextureClient中去:
void Surface::init(const sp<ISurfaceTexture>& surfaceTexture)
{
if (mSurface != NULL || surfaceTexture != NULL) {
ALOGE_IF(surfaceTexture==0, "got a NULL ISurfaceTexture from ISurface");
if (surfaceTexture != NULL) {
setISurfaceTexture(surfaceTexture);//mSurfaceTexture = surfaceTexture;
setUsage(GraphicBuffer::USAGE_HW_RENDER);
}
......
}
经过上面的分析可以知道,这个BpSurfaceTexture匿名的Binder客户端将又回请求BnSurfaceTexture去完成一些任务了,实际上将会是BufferQueue的天下。