SurfaceFlinger中各个layer的排序

时间:2021-08-16 04:12:55

概述

  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也可以是wifiDisplay
DisplayDevice里也有个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);
}
但是也就是改了这里的值,没有真正起效呢 SurfaceFlinger中各个layer的排序SurfaceFlinger中各个layer的排序 回到bootanimation的代码,我们发现,后面紧接着是 closeGlobalTransaction,来看看这个方法都做了什么吧 ^_^
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就确定好了。