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也可以是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);
}
但是也就是改了这里的值,没有真正起效呢 疑问 难过 回到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就确定好了。










  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值