surfaceflinger的主要工作就是负责把上层传递下来的各个不同的layer进行composition。
这里,我们来讨论一下各个layer在surfaceflinger中的上下排序关系和相关的代码实现,代码基于android4.3
首先介绍一下两个类,SurfaceFlinger和Client。
简单的说,这两个类的关系可以这么理解:SurfaceFlinger实现了具体的composition的服务,而每一个有UI的程序都需要通过SurfaceFlinger去实现渲染。
这些程序可以通过Client的一些接口来调用SurfaceFlinger以实现这个目的。
Client类中有一个createSurface成员函数
status_t Client::createSurface( const String8& name, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) { /* * createSurface must be called from the GL thread so that it can * have access to the GL context. */ class MessageCreateLayer : public MessageBase { SurfaceFlinger* flinger; Client* client; sp<IBinder>* handle; sp<IGraphicBufferProducer>* gbp; status_t result; const String8& name; uint32_t w, h; PixelFormat format; uint32_t flags; public: MessageCreateLayer(SurfaceFlinger* flinger, const String8& name, Client* client, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) : flinger(flinger), client(client), handle(handle), gbp(gbp), name(name), w(w), h(h), format(format), flags(flags) { } status_t getResult() const { return result; } virtual bool handler() { result = flinger->createLayer(name, client, w, h, format, flags, handle, gbp); return true; } }; sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(), name, this, w, h, format, flags, handle, gbp); mFlinger->postMessageSync(msg); return static_cast<MessageCreateLayer*>( msg.get() )->getResult(); }
createLayer函数是SurfaceFlinger类的私有函数,但是因为Client是他的友元,所以可以直接调用来创建一个layer。
private: friend class Client; friend class DisplayEventConnection; friend class Layer; friend class SurfaceTextureLayer;
看下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; }
这个函数很清晰,主要是调用createNormalLayer和createDimLayer去创建不同的layer。
我们先忽略createDimLayer,只看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: #ifdef NO_RGBX_8888 format = PIXEL_FORMAT_RGB_565; #else format = PIXEL_FORMAT_RGBX_8888; #endif break; } #ifdef NO_RGBX_8888 if (format == PIXEL_FORMAT_RGBX_8888) format = PIXEL_FORMAT_RGBA_8888; #endif *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)->getBufferQueue(); } ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err)); return err; }
这里主要是创建了一个Layer对象。
Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name, uint32_t w, uint32_t h, uint32_t flags) : contentDirty(false), sequence(uint32_t(android_atomic_inc(&sSequence))), mFlinger(flinger), mTextureName(-1U), mPremultipliedAlpha(true), mName("unnamed"), mDebug(false), mFormat(PIXEL_FORMAT_NONE), mGLExtensions(GLExtensions::getInstance()), mOpaqueLayer(true), mTransactionFlags(0), mQueuedFrames(0), mCurrentTransform(0), mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), mCurrentOpacity(true), mRefreshPending(false), mFrameLatencyNeeded(false), mFiltering(false), mNeedsFiltering(false), mSecure(false), mProtectedByApp(false), mHasSurface(false), mClientRef(client) { mCurrentCrop.makeInvalid(); glGenTextures(1, &mTextureName); uint32_t layerFlags = 0; if (flags & ISurfaceComposerClient::eHidden) layerFlags = layer_state_t::eLayerHidden; if (flags & ISurfaceComposerClient::eNonPremultiplied) mPremultipliedAlpha = false; mName = name; mCurrentState.active.w = w; mCurrentState.active.h = h; mCurrentState.active.crop.makeInvalid(); mCurrentState.z = 0; mCurrentState.alpha = 0xFF; mCurrentState.layerStack = 0; mCurrentState.flags = layerFlags; mCurrentState.sequence = 0; mCurrentState.transform.set(0, 0); mCurrentState.requested = mCurrentState.active; // drawing state & current state are identical mDrawingState = mCurrentState; }
这里我们主要关注和layer顺序相关的信息
sequence(uint32_t(android_atomic_inc(&sSequence))), mCurrentState.z = 0; mCurrentState.layerStack = 0;
这三个变量决定了layer之间的顺序,我来说明一下具体的含义。
首先是layerStack,大家可以把它理解为组的含义。也就是说属于不同组的layer之间互不干扰。
SurfaceFlinger中有一个DisplayDevice类,他表示用来显示的设备,譬如LCD或者是HDMI。
DisplayDevice里也有一个成员变量mLayerStack,在进行composition的时候,只有和这个device的layerstack相同的layer才可能被显示在这个设备上。
第二个是z,其实他就是z-order的意思,表示x,y,z轴的z轴上的顺序。数字越大,表示越在上面,数字越小,表示越在下面。
第三个是sequence,因为sSequence是一个static的变量,所以递加的效果就是为每一个layer设置一个唯一且递增的序列号。
概念介绍完了,我们继续看代码,看看到底是不是这样。
创建完layer之后,createLayer会调用addClientLayer把这个layer的信息添加到当前的状态信息里去。
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()); }
layersSortedByZ变量很重要,surfaceflinger真正渲染的时候就是靠它来知道哪个layer在上哪个在下的。
这里的add函数就负责把layer放进去
ssize_t SortedVectorImpl::add(const void* item) { size_t order; ssize_t index = _indexOrderOf(item, &order); if (index < 0) { index = VectorImpl::insertAt(item, order, 1); } else { index = VectorImpl::replaceAt(item, index); } return index; }
ssize_t SortedVectorImpl::_indexOrderOf(const void* item, size_t* order) const { // binary search ssize_t err = NAME_NOT_FOUND; ssize_t l = 0; ssize_t h = size()-1; ssize_t mid; const void* a = arrayImpl(); const size_t s = itemSize(); while (l <= h) { mid = l + (h - l)/2; const void* const curr = reinterpret_cast<const char *>(a) + (mid*s); const int c = do_compare(curr, item); if (c == 0) { err = l = mid; break; } else if (c < 0) { l = mid + 1; } else { h = mid - 1; } } if (order) *order = l; return err; }
int SurfaceFlinger::LayerVector::do_compare(const void* lhs, const void* rhs) const { // sort layers per layer-stack, then by z-order and finally by sequence const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs)); const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs)); uint32_t ls = l->currentState().layerStack; uint32_t rs = r->currentState().layerStack; if (ls != rs) return ls - rs; uint32_t lz = l->currentState().z; uint32_t rz = r->currentState().z; if (lz != rz) return lz - rz; return l->sequence - r->sequence; }
连着贴了3个函数,其主要作用就是判断这个layer要插在layersSortedByZ的什么位置。
从do_compare我们可以看出,和我刚才分析的是一样的。
第一步是比较layerstack,不同的layerstack分开。
然后再比较z,最后假设这些都一样,就比较唯一的layer序列号。
但是至今为止,layerStack和z都还只是初始化时的0,所以在创建layer的时候,只是把他根据序列号放进layersSortedByZ而已,其实他的顺序还是没有设置的。
下面我们就要去找找看到底在哪里设置了这些。
大家应该都知道bootanimation吧,就是开机负责绘制闪啊闪的android字样的那个程序。
在里面我找到了这样的代码
// create the native surface sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"), dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565); SurfaceComposerClient::openGlobalTransaction(); control->setLayer(0x40000000); SurfaceComposerClient::closeGlobalTransaction();
前面的createSurface我们在前面已经分析完成了。
下面就是setLayer了,这个0x40000000到底是设置了什么那?
我们一步步往下看
status_t SurfaceControl::setLayer(int32_t layer) { status_t err = validate(); if (err < 0) return err; const sp<SurfaceComposerClient>& client(mClient); return client->setLayer(mHandle, layer); }
status_t SurfaceComposerClient::setLayer(const sp<IBinder>& id, int32_t z) { return getComposer().setLayer(this, id, z); }
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; }
可以看到,这个layer变量最终变成了z,存进了layer_state_t结构体内。
这个结构体是哪来的?在看看getLayerStateLocked
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); }
原来是从mComposerStates里找来的啊。
这些代码看上去是在做相关的操作,但是设置还没有具体生效。
下面我们看看SurfaceComposerClient::closeGlobalTransaction()的作用
void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) { Composer::closeGlobalTransaction(synchronous); }
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; } if (mTransition) { flags |= ISurfaceComposer::eTransition; } if (mOrientationEnd) { flags |= ISurfaceComposer::eOrientationEnd; } mForceSynchronous = false; mAnimation = false; } sm->setTransactionState(transaction, displayTransaction, flags); }
mComposerStates被赋值给transaction,然后通过sm->setTransactionState传递下去。
void SurfaceFlinger::setTransactionState( const Vector<ComposerState>& state, const Vector<DisplayState>& displays, uint32_t flags) { ...... count = state.size(); for (size_t i=0 ; i<count ; i++) { const ComposerState& s(state[i]); // Here we need to check that the interface we're given is indeed // one of our own. A malicious client could give us a NULL // IInterface, or one of its own or even one of our own but a // different type. All these situations would cause us to crash. // // NOTE: it would be better to use RTTI as we could directly check // that we have a Client*. however, RTTI is disabled in Android. if (s.client != NULL) { sp<IBinder> binder = s.client->asBinder(); if (binder != NULL) { String16 desc(binder->getInterfaceDescriptor()); if (desc == ISurfaceComposerClient::descriptor) { sp<Client> client( static_cast<Client *>(s.client.get()) ); transactionFlags |= setClientStateLocked(client, s.state); } } } } ...... }
uint32_t SurfaceFlinger::setClientStateLocked( const sp<Client>& client, const layer_state_t& s) { uint32_t flags = 0; sp<Layer> layer(client->getLayerUser(s.surface)); if (layer != 0) { const uint32_t what = s.what; if (what & layer_state_t::ePositionChanged) { if (layer->setPosition(s.x, s.y)) flags |= eTraversalNeeded; } if (what & layer_state_t::eLayerChanged) { // NOTE: index needs to be calculated before we update the state ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); if (layer->setLayer(s.z)) { mCurrentState.layersSortedByZ.removeAt(idx); mCurrentState.layersSortedByZ.add(layer); // we need traversal (state changed) // AND transaction (list changed) flags |= eTransactionNeeded|eTraversalNeeded; } } ...... } }
bool Layer::setLayer(uint32_t z) { if (mCurrentState.z == z) return false; mCurrentState.sequence++; mCurrentState.z = z; setTransactionFlags(eTransactionNeeded); return true; }
可以看到,只要设置的z值和之前的不同,setLayer就会返回true。
然后mCurrentState.layersSortedByZ.removeAt和mCurrentState.layersSortedByZ.add就会被执行。
至此,layer的真正z-order就确定好了。