zoukankan      html  css  js  c++  java
  • Surface在C++层的创建源码解析

    Surface在C++层的创建源码解析

    源码为:android4.4.4

    1、创建SurfaceComposerClient绘图客户端

    // create a client to surfaceflinger 

        sp<SurfaceComposerClient> client = new SurfaceComposerClient();  //创建SurfaceFlinger的本地代理

    展开SurfaceComposerClient源码:frameworks ativelibsguiSurfaceComposerClient.cpp

    SurfaceComposerClient::SurfaceComposerClient()

    : mStatus(NO_INIT), mComposer(Composer::getInstance())

    // Composer::getInstance() 应该是一个单例模式

    {

    }

    mStatus: 为status_t类型变量  , mComposer:为Composer&的引用

    Composer类为SurfaceComposerClient类的友元类。

    Composer::getInstance()获取一个Composer对象赋值给mComposer。

    现在client对象的两个变量mStatus和mComposer都有值了。

    2、通过client对象获取屏幕信息

    DisplayInfo display; 

      //获取屏幕的宽高等信息

    client->getDisplayInfo(client->getBuiltInDisplay(HWC_DISPLAY_PRIMARY), &display);

    将获取到的屏幕信息存放发哦display这个结构体里。

    看看client->getBuiltInDisplay(HWC_DISPLAY_PRIMARY)这个是什么意思。

    sp<IBinder> SurfaceComposerClient::getBuiltInDisplay(int32_t id) {

        return Composer::getInstance().getBuiltInDisplay(id);

    } //调用Composer的getBuiltInDisplay方法

    sp<IBinder> Composer::getBuiltInDisplay(int32_t id) {

        return ComposerService::getComposerService()->getBuiltInDisplay(id);

    }//再次调用ComposerService对象的getBuiltInDisplay方法

    client-> getBuiltInDisplay最终获取到一个Ibinder对象

    再看看client->getDisplayInfo这个方法

    status_t SurfaceComposerClient::getDisplayInfo(

            const sp<IBinder>& display, DisplayInfo* info)

    {

        return ComposerService::getComposerService()->getDisplayInfo(display, info);

    }

    根据HWC_DISPLAY_PRIMARY获取Ibinder对象,根据Binder对象获取ComposerSeveice对象调用取得屏幕信息。

    3、根据SurfaceComposerClient对象创建SurfafeControl对象

    //创建SurfaceControl的本地代理

          sp<SurfaceControl> surfaceControl = client->createSurface(String8("testsurface"), display.w, display.h, PIXEL_FORMAT_RGBA_8888, 0); 

    看看createSurface源码

    sp<SurfaceControl> SurfaceComposerClient::createSurface(

            const String8& name,

            uint32_t w,

            uint32_t h,

            PixelFormat format,

            uint32_t flags)

    {

        sp<SurfaceControl> sur;

        if (mStatus == NO_ERROR) {

            sp<IBinder> handle;

            sp<IGraphicBufferProducer> gbp;

            status_t err = mClient->createSurface(name, w, h, format, flags,

                    &handle, &gbp); //通知服务端申请surface

            ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));

            if (err == NO_ERROR) {

                sur = new SurfaceControl(this, handle, gbp); //如果申请成功就创建

            }

        }

        return sur;

    }

    mClient是什么东西:sp<ISurfaceComposerClient>  mClient; IsurfaceComposerClient是Binder的一个接口类。

    先申请surface申请成功就创建一个surfaceControl的本地代理。

    4、设置surface的图层Z轴

    SurfaceComposerClient::openGlobalTransaction(); 

        surfaceControl->setLayer(120000); //设置z轴    

    surfaceControl->setSize(display.w, display.h); 

        surfaceControl->setPosition(0, 0);  //起始位置

    SurfaceComposerClient::closeGlobalTransaction(); //默认false

     SurfaceComposerClient::openGlobalTransaction() 源码展开后:

    void SurfaceComposerClient::openGlobalTransaction() {

        Composer::openGlobalTransaction();

    }

    static void openGlobalTransaction() {

            Composer::getInstance().openGlobalTransactionImpl();

    }

    void Composer::openGlobalTransactionImpl() {

        { // scope for the lock

            Mutex::Autolock _l(mLock);

            mTransactionNestCount += 1;  //最终是给这个变量加1

        }

    }

    看看surfaceControl->setLayer(120000)设置z轴展开:

    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_state_t* Composer::getLayerStateLocked(

            const sp<SurfaceComposerClient>& client, const sp<IBinder>& id) {

        ComposerState s;

        s.client = client->mClient;

        s.state.surface = id; //将设置的Z轴坐标存在ComposerState对象里

        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对象存放到链表中

        }

        ComposerState* const out = mComposerStates.editArray();

        return &(out[index].state);

    }

        以上就是设置Z轴方法,调用Composer对象getLayerStateLocked进行加锁,创建一个ComposerState对象,将传递进来的值存进行检查,检查是否存在,如果不存在就直接储到mComposerStates链表中。

    SurfaceComposerClient::closeGlobalTransaction()展开:

    void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) {

        Composer::closeGlobalTransaction(synchronous);

    }

    static void closeGlobalTransaction(bool synchronous) {

            Composer::getInstance().closeGlobalTransactionImpl(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;

            }

            mForceSynchronous = false;

            mAnimation = false;

        }

       sm->setTransactionState(transaction, displayTransaction, flags);

    }

    5、获取surface

    // 获取Surface本地代理

          sp<Surface> surface = surfaceControl->getSurface();//获取surface

    sp<Surface> SurfaceControl::getSurface() const

    {

        Mutex::Autolock _l(mLock);

        if (mSurfaceData == 0) {

            // This surface is always consumed by SurfaceFlinger, so the

            // producerControlledByApp value doesn't matter; using false.

            mSurfaceData = new Surface(mGraphicBufferProducer, false);

        }

        return mSurfaceData;

    }

    直接new一个suface对象返回

    6、surface->lock() 和surface->unlockAndPost();

          Lock从屏幕缓冲队列中申请屏幕,再使用unlockAndpost将申请的屏幕加入到缓冲队列中交给surfaceflinger进行组合并显示在屏幕上。其实这才是绘图显示最重要的阶段,绘图显示快慢和这里优化有直接关系。

  • 相关阅读:
    【网易官方】极客战记(codecombat)攻略-森林-村庄守卫village-warder
    【网易官方】极客战记(codecombat)攻略-森林-乡村漫游者village-rover
    【网易官方】极客战记(codecombat)攻略-森林-Agrippa 守卫战 B-the-agrippa-defense-b
    【网易官方】极客战记(codecombat)攻略-森林-Agrippa 守卫战A-the-agrippa-defense-a
    【网易官方】极客战记(codecombat)攻略-森林-Agrippa守卫战the-agrippa-defense
    【网易官方】极客战记(codecombat)攻略-森林-以静制动stillness-in-motion
    【网易官方】极客战记(codecombat)攻略-森林-跃火林中forest-fire-dancing
    Can not deserialize instance of xxx out of START_ARRAY token
    Springboot/cloud 项目突然出现许多Failed to read artifact descriptor, 或者无法解析
    redis-deskmanager 连不上 虚拟机
  • 原文地址:https://www.cnblogs.com/winfu/p/5833446.html
Copyright © 2011-2022 走看看