zoukankan      html  css  js  c++  java
  • 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<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就确定好了。

  • 相关阅读:
    树的同构
    最大子列和
    多项式的表示和运算
    图1
    集合及运算
    树4
    树3
    树2
    期末作业验收
    个人总结
  • 原文地址:https://www.cnblogs.com/riskyer/p/3297226.html
Copyright © 2011-2022 走看看