本文均属自己阅读源码的点滴总结,转账请注明出处谢谢。
欢迎和大家交流。qq:1037701636 email:[email protected]
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的天下。