android 排序函数,surfaceflinger中各个layer的排序

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* handle,

sp* 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* handle;

sp* 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* handle,

sp* 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 msg = new MessageCreateLayer(mFlinger.get(),

name, this, w, h, format, flags, handle, gbp);

mFlinger->postMessageSync(msg);

return static_cast( 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,

uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,

sp* handle, sp* 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;

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,

const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,

sp* handle, sp* gbp, sp* 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,

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,

const sp& handle,

const sp& gbc,

const sp& 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(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& l(*reinterpret_cast*>(lhs));

const sp& r(*reinterpret_cast*>(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 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& client(mClient);

return client->setLayer(mHandle, layer);

}

status_t SurfaceComposerClient::setLayer(const sp& id, int32_t z) {

return getComposer().setLayer(this, id, z);

}

status_t Composer::setLayer(const sp& client,

const sp& 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& client, const sp& 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 sm(ComposerService::getComposerService());

Vector transaction;

Vector 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& state,

const Vector& displays,

uint32_t flags)

{

......

count = state.size();

for (size_t i=0 ; 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 binder = s.client->asBinder();

if (binder != NULL) {

String16 desc(binder->getInterfaceDescriptor());

if (desc == ISurfaceComposerClient::descriptor) {

sp client( static_cast(s.client.get()) );

transactionFlags |= setClientStateLocked(client, s.state);

}

}

}

}

......

}

uint32_t SurfaceFlinger::setClientStateLocked(

const sp& client,

const layer_state_t& s)

{

uint32_t flags = 0;

sp 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就确定好了。

(责任编辑:最模板)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值