SurfaceFlinger中各个layer的排序
概述
Surfaceflinger的主要工作就是负责把上层传递下来的各个不同的layer进行composition。 Android从4.1之后,支持多种显示设备,如HDMI,WIFIDisplay等,并使用Display对象对这些设备进行抽象,同时,对 SurfaceFlinger进行了一次大的调整,用于对每个Display构建起对应的layerlist 每个Display有一个layerstack,每个layer也有一个layerstack,若要指定一个layer显示到特定的display上,必须将其layerstack设置成display的layerstack一致才可以显示 在layer排序的时候,首先是通过layerstack进行筛选,接着是按照z-index对layer进行排序,最后按照sequence排序SurfaceFliner类和Client类
SurfaceFliner实现了具体的Composition的服务,而每个具有UI的APP都需要SurfaceFlinger去渲染,这些APP可以通过Client的一些接口来调用SurfaceFlinger来实现。Client是APP在SurfaceFlinger服务端的映射。<span style="background-color: rgb(254, 254, 254);"> 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);</span><span style="background-color: rgb(102, 255, 255);">//调用SurfaceFlinger createLayer</span><span style="background-color: rgb(254, 254, 254);"> 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(); }</span>
CreateLayer过程
createLayer函数是SurfaceFlinger类的私有函数,但是因为Client是他的友元,所以可以直接调用来创建一个layer。下面来看看createLayer函数<span style="color:#333333;">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 = </span><span style="color:#3366ff;"><strong>createNormalLayer</strong></span><span style="color:#333333;">(client, name, w, h, flags, format, handle, gbp, &layer); break; case ISurfaceComposerClient::eFXSurfaceDim: result = </span><span style="color:#3366ff;"><strong>createDimLayer</strong></span><span style="color:#333333;">(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; } </span>
这个函数很清晰,主要是调用createNormalLayer和createDimLayer去创建不同的layer。先看看createNormalLayer的实现
status_t SurfaceFlinger::<strong>createNormalLayer</strong>(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 <strong>Layer</strong>(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对象
<span style="color:#333333;">Layer::</span><strong style="color: rgb(51, 51, 51);">Layer</strong><span style="color:#333333;">(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; </span><strong><span style="color:#333333;">mCurrentState.layerStack = 0;</span><span style="color:#3366ff;">//初始化layer的时候,layerstack默认设置为0</span></strong><span style="color:#333333;"> mCurrentState.flags = layerFlags; mCurrentState.sequence = 0; mCurrentState.transform.set(0, 0); mCurrentState.requested = mCurrentState.active; // drawing state & current state are identical mDrawingState = mCurrentState; }</span>
Layer顺序相关的信息
来看看和layer顺序相关的信息sequence(uint32_t(android_atomic_inc(&sSequence))), <span style="color:#3366ff;">//为每一个layre设置唯一且递增的序列号</span> mCurrentState.z = 0; mCurrentState.layerStack = 0;着三个变量决定了layer之间的顺序。 1)首先是layerstack,它可以看成是组的含义,不同的layerstack对应的layer互不干扰。
SurfaceFlinger中有一个DisplayDevice类,它用来表示设备,可以是hdmi也可以是wifiDisplayDisplayDevice里也有个mLayerStack,进行composition的时候,只有和这个device的layerstack相等的layer才可以显示到这个设备上。 2)第二个值是z,也就是z-order,表示z轴上的顺序,数字越大,表示越在上面 3)第三个是sequence,由于mSequence是一个static变量,所以递加的效果是为每个layer设置一个唯一且递增的序列号 创建layer之后,createLayer会调用addClientLayer把这个layer添加到当前状态信息mCurrentState中去,
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.<strong>layersSortedByZ</strong>.add(lbc); mGraphicBufferProducerList.add(gbc->asBinder()); }这里,layerSortedByZ非常重要,SurfaceFlinger真正渲染的时候就是靠它来知道哪个layer在哪个layer下的。add方法负责将layer放到对应的位置(通过二分查找找到应该插入的位置)
<span style="background-color: rgb(254, 254, 254);">ssize_t SortedVectorImpl::add(const void* item) { size_t order; ssize_t index = _indexOrderOf(item, &order);</span><strong style="background-color: rgb(255, 255, 255);"><span style="color:#3366ff;">//查找插入位置</span></strong><span style="background-color: rgb(254, 254, 254);"> if (index < 0) { index = VectorImpl::insertAt(item, order, 1); } else { index = VectorImpl::replaceAt(item, index); } return index; }</span>
<span style="font-family:Helvetica Neue, Helvetica, Tahoma, Arial, STXihei, Microsoft YaHei, 微软雅黑, sans-serif;"><span style="font-size: 16px; line-height: 27.2px;">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);</span></span><span style="color:#3366ff;"><strong>//比较主要依据的地方</strong></span><span style="font-family:Helvetica Neue, Helvetica, Tahoma, Arial, STXihei, Microsoft YaHei, 微软雅黑, sans-serif;"><span style="font-size: 16px; line-height: 27.2px;"> if (c == 0) { err = l = mid; break; } else if (c < 0) { l = mid + 1; } else { h = mid - 1; } } if (order) *order = l; return err; }</span></span>
do_compare方法是比较的依据,比较layerstack,再比较z-order,最后比较sequence
int SurfaceFlinger::LayerVector::do_compare(const void* lhs, const void* rhs) const { <strong>// sort layers per layer-stack, then by z-order and finally by sequence</strong> 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; }但是到现在为止,layerstack和z都是初始化的0,初始化的时候只是根据sequence将layer放到layersSortedByZ而已,其实顺序还是没有设置。
实例
现在来看看从哪里进行了设置,以bootanimation为例(开机动画)// create the native surface sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"), dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565); SurfaceComposerClient::openGlobalTransaction(); <strong>control->setLayer(0x40000000);</strong> SurfaceComposerClient::closeGlobalTransaction();
前面的过程就是createSurface的过程。下面就是setLayer了,来了解下0x40000000的设置
status_t SurfaceControl::<strong>setLayer</strong>(int32_t layer) { status_t err = validate(); if (err < 0) return err; const sp<SurfaceComposerClient>& client(mClient); return client-><strong>setLayer</strong>(mHandle, layer); }
status_t SurfaceComposerClient::setLayer(const sp<IBinder>& id, int32_t z) { return getComposer().<strong>setLayer</strong>(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 = <em><strong>getLayerStateLocked</strong></em>(client, id); if (!s) return BAD_INDEX; <strong>s->what |= layer_state_t::eLayerChanged;//<span style="color:#3333ff;">下面</span></strong><pre class="prettyprint perl" style="padding: 0.3em; font-family: Monaco, Menlo, Consolas, "Courier New", monospace; border-radius: 4px; margin-top: 0px; margin-bottom: 1.5em; line-height: 1.5em; word-break: break-all; word-wrap: break-word; white-space: pre-wrap; border: 1px solid rgba(0, 0, 0, 0.14902); overflow-y: auto; display: inline !important; background-color: rgb(246, 246, 246);"><span style="color:#3333ff;">setClientStateLocked中会判断</span>
通过这个判断layer是否修改 s->z = z; return NO_ERROR;} 从这里可以看到layer的设置最终修改了layer_state_t *s 的z,而这个s是通过getLayerStateLocked获得的
layer_state_t* Composer::<strong>getLayerStateLocked</strong>( const sp<SurfaceComposerClient>& client, const sp<IBinder>& id) { ComposerState s; s.client = client->mClient; s.state.surface = id; ssize_t index = mComposerStates.indexOf(s);<span style="color:#3366ff;">//原来是从这里找到的</span><img alt="微笑" src="http://static.blog.csdn.net/xheditor/xheditor_emot/default/smile.gif" /> 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); }但是也就是改了这里的值,没有真正起效呢


void SurfaceComposerClient::<strong>closeGlobalTransaction</strong>(bool synchronous) { Composer::closeGlobalTransaction(synchronous); }
<span style="color:#333333;">void Composer::</span><strong style="color: rgb(51, 51, 51);">closeGlobalTransactionImpl</strong><span style="color:#333333;">(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; } <strong><em>transaction = mComposerStates;</em></strong> </span><span style="color:#3366ff;"><strong>//在上面修改修改了z值</strong></span><span style="color:#333333;"> mComposerStates.clear();</span><span style="color:#333333;"> 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-><strong>setTransactionState</strong>(<em><strong>transaction</strong></em>, displayTransaction, flags); }</span>mComposerStates被赋值给transaction,然后通过setTransactionState传递下去
<span style="color:#333333;">void SurfaceFlinger::</span><strong style="color: rgb(51, 51, 51);">setTransactionState</strong><span style="color:#333333;">( 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 |= </span><strong style="color: rgb(51, 51, 51);">setClientStateLocked</strong><span style="color:#333333;">(client, s.state);</span><span style="color:#3333ff;"><strong>//调用setClientStateLocked</strong></span><span style="color:#333333;"> } } } } ...... }</span>
uint32_t SurfaceFlinger::<strong>setClientStateLocked</strong>( 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) { <strong><span style="color:#3333ff;">//s.what在上面<span style="line-height: 27.2px; font-family: "Helvetica Neue", Helvetica, Tahoma, Arial, STXihei, "Microsoft YaHei", 微软雅黑, sans-serif;">Composer::setLayer修改过了</span></span></strong> // NOTE: index needs to be calculated before we update the state ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); if (layer->setLayer(s.z)) {<span style="color: rgb(51, 51, 255); font-weight: bold; line-height: 27.2px; font-family: "Helvetica Neue", Helvetica, Tahoma, Arial, STXihei, "Microsoft YaHei", 微软雅黑, sans-serif;">//s.z在上面</span><span style="color: rgb(51, 51, 255); line-height: 27.2px; font-family: "Helvetica Neue", Helvetica, Tahoma, Arial, STXihei, "Microsoft YaHei", 微软雅黑, sans-serif;"><strong>Composer::setLayer修改过了,调用layer的setLayer真正修改layer的layerStack值</strong></span> mCurrentState.layersSortedByZ.removeAt(idx); mCurrentState.layersSortedByZ.add(layer); // we need traversal (state changed) // AND transaction (list changed) <strong>flags |= eTransactionNeeded|eTraversalNeeded;</strong> } } ...... }
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真正意义上插入到layersSortedByZ中。
到这里,layer的真正z-order就确定好了。
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: layui实现数据分页功能
- 下一篇: surfaceflinger中各个layer的排序