Android P 图形显示系统(五) 上层Client和SurfaceFlinger的交互

[TOC]

上层Client和SurfaceFlinger的交互

为了很好的切入主题,我们这里基于Native的Framework进行应用的开发呢,不是指的NDK应用。我们直接用系统接口,进行开发。Native应用直接抛弃掉Android的Java上层,AMS,WMS,View等,直接在Native开发,这样便于我们理解显示系统。

Native应用建立

在显示子系统中,Surface是一个很重要的类,通过Surface我们就能获取到Buffer,我们就能够和Android Native窗口系统建立连接。我们就基于Surface来写一个Native的应用。

首先,我们先定义一个封装类WindowSurfaceWrapper,WindowSurfaceWrapper和Surface进行交互。

class WindowSurfaceWrapper : public RefBase {
public:
    // Creates the window.
    WindowSurfaceWrapper(const String8& name);

    virtual ~WindowSurfaceWrapper() {}

    virtual void onFirstRef();

    // Retrieves a handle to the window.
    sp  getSurface() const;

    int width() {
        return mWidth;
    }

    int height() {
        return mHeight;
    }

private:
    WindowSurfaceWrapper(const WindowSurfaceWrapper&);
    WindowSurfaceWrapper& operator=(const WindowSurfaceWrapper&);

    sp mSurfaceControl;

    int mWidth;
    int mHeight;
    String8 mName;
};

WindowSurfaceWrapper对应的实现如下:

WindowSurfaceWrapper::WindowSurfaceWrapper(const String8& name) {
    mName = name;
}

void WindowSurfaceWrapper::onFirstRef() {
    status_t err;

    sp surfaceComposerClient = new SurfaceComposerClient;
    err = surfaceComposerClient->initCheck();
    if (err != NO_ERROR) {
        fprintf(stderr, "SurfaceComposerClient::initCheck error: %#x\n", err);
        return;
    }

    // Get main display parameters.
    sp mainDisplay = SurfaceComposerClient::getBuiltInDisplay(
            ISurfaceComposer::eDisplayIdMain);
    DisplayInfo mainDisplayInfo;
    err = SurfaceComposerClient::getDisplayInfo(mainDisplay, &mainDisplayInfo);
    if (err != NO_ERROR) {
        fprintf(stderr, "ERROR: unable to get display characteristics\n");
        return;
    }

    uint32_t width, height;
    if (mainDisplayInfo.orientation != DISPLAY_ORIENTATION_0 &&
            mainDisplayInfo.orientation != DISPLAY_ORIENTATION_180) {
        // rotated
        width = mainDisplayInfo.h;
        height = mainDisplayInfo.w;
    } else {
        width = mainDisplayInfo.w;
        height = mainDisplayInfo.h;
    }

    sp surfaceControl = surfaceComposerClient->createSurface(
            mName, width, height,
            PIXEL_FORMAT_RGBX_8888, ISurfaceComposerClient::eOpaque);
    if (surfaceControl == NULL || !surfaceControl->isValid()) {
        fprintf(stderr, "Failed to create SurfaceControl\n");
        return;
    }

    SurfaceComposerClient::Transaction{}
            .setLayer(surfaceControl, 0x7FFFFFFF)
            .show(surfaceControl)
            .apply();

    mSurfaceControl = surfaceControl;
    mWidth = width;
    mHeight = height;

}

sp WindowSurfaceWrapper::getSurface() const {
    sp anw = mSurfaceControl->getSurface();
    return anw;
}

getSurface获取Native 窗口,这个窗口能够和Native的窗口系统建立联系,我们直接往这个窗口里面绘制我们需要的界面就OK了。

int main(int argc, char *argv[]) {
    unsigned samples = 0;
    printf("usage: %s [samples]\n", argv[0]);
    if (argc == 2) {
        samples = atoi( argv[1] );
        printf("Multisample enabled: GL_SAMPLES = %u\n", samples);
    }

    sp proc(ProcessState::self());
    ProcessState::self()->startThreadPool();

    sp windowSurface(new WindowSurfaceWrapper(String8("NativeBinApp")));

    drawNativeWindow(windowSurface->getSurface().get(), windowSurface->width(), windowSurface->height());

    IPCThreadState::self()->joinThreadPool();

    return EXIT_SUCCESS;
}

解释一下代码中的关键点:

  • 创建一个SurfaceComposerClient,这是应用端,是SurfaceFlinger的Client端,它将建立和SurfaceFlinger服务的通信
  • getDisplayInfo,获取手机屏幕的信息
  • createSurface,创建SurfaceControl,在SurfaceFlinger创建对应的Layer等~
  • setLayer,设置窗口的z-Oder,SurfaceFlinger根据z-Oder决定窗口的可见性及可见大小
  • show,让当前窗口可见
  • apply,这时,上面的设置的属性才真正生效,传给SurfaceFlinger

至于怎么画界面,我们接来下再介绍,稍后再给出drawNativeWindow的代码。我们先来看,目前都干了什么。

应用和SurfaceFlinger的链接建立

应用和SurfaceFlinger是两个不同的进程,他们采用Binder通信,应用是Client端,SurfaceFlinger是服务端。在Android中ProcessState是客户端和服务端公共的部分,作为Binder通信的基础,ProcessState是一个singleton类,每个进程只有一个对象,这个对象负责打开Binder驱动,建立线程池,让其进程里面的所有线程都能通过Binder通信。与之相关的是IPCThreadState,每个线程都有一个IPCThreadState实例登记在Linux线程的上下文附属数据中,主要负责Binder的读取,写入和请求处理框架。IPCThreadState在构造的时候获取进程的ProcessState并记录在自己的成员变量mProcess中,通过mProcess可以获得Binder的句柄。

我们这里将不详细的介绍Binder。有需求的可以提,我们开一个专题。

SurfaceComposerClient的 定义非常简单,继承RefBase~,这样我们就可以直接用智能指针sp,wp管理SurfaceComposerClient对象,不用担心SurfaceComposerClient对象的回收问题。

智能指针sp,wp,我们这里也不做详细的介绍,有需求的可以提,我们开一个专题。

在SurfaceComposerClient的构造函数中,只初始化了一个装mStatus。

SurfaceComposerClient::SurfaceComposerClient()
    : mStatus(NO_INIT)
{
}

第一次引用的时候,才真正的建立连接:

*frameworks/native/libs/gui/SurfaceComposerClient.cpp

void SurfaceComposerClient::onFirstRef() {
    sp sf(ComposerService::getComposerService());
    if (sf != 0 && mStatus == NO_INIT) {
        auto rootProducer = mParent.promote();
        sp conn;
        conn = (rootProducer != nullptr) ? sf->createScopedConnection(rootProducer) :
                sf->createConnection();
        if (conn != 0) {
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
}

ComposerService继承模板类Singleton,ComposerService是一个单例。

ComposerService::ComposerService()
: Singleton() {
    Mutex::Autolock _l(mLock);
    connectLocked();
}

ComposerService在构建时,创建链接:

void ComposerService::connectLocked() {
    const String16 name("SurfaceFlinger");
    while (getService(name, &mComposerService) != NO_ERROR) {
        usleep(250000);
    }
    assert(mComposerService != NULL);

    // Create the death listener.
    class DeathObserver : public IBinder::DeathRecipient {
        ComposerService& mComposerService;
        virtual void binderDied(const wp& who) {
            ALOGW("ComposerService remote (surfaceflinger) died [%p]",
                  who.unsafe_get());
            mComposerService.composerServiceDied();
        }
     public:
        explicit DeathObserver(ComposerService& mgr) : mComposerService(mgr) { }
    };

    mDeathObserver = new DeathObserver(*const_cast(this));
    IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver);
}

建立连接时,采用轮循的方式,getService时,如果SurfaceFlinger服务还没有启动,等待250000后再查询,知道等到SurffaceFlinger进程启动。DeathObserver是监听SurfaceFlinger进程是否死掉,做善后处理的。

getComposerService直接返回单实例mComposerService。

/*static*/ sp ComposerService::getComposerService() {
    ComposerService& instance = ComposerService::getInstance();
    Mutex::Autolock _l(instance.mLock);
    if (instance.mComposerService == NULL) {
        ComposerService::getInstance().connectLocked();
        assert(instance.mComposerService != NULL);
        ALOGD("ComposerService reconnected");
    }
    return instance.mComposerService;
}

createScopedConnection函数,将建立和SurfaceFlinger的连接。

void SurfaceComposerClient::onFirstRef() {
    sp sf(ComposerService::getComposerService());
    if (sf != 0 && mStatus == NO_INIT) {
        auto rootProducer = mParent.promote();
        sp conn;
        conn = (rootProducer != nullptr) ? sf->createScopedConnection(rootProducer) :
                sf->createConnection();
        if (conn != 0) {
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
}

对于我们这里的使用来说,rootProducer是nullptr,所以直接走的sf->createConnection()。Bn端SurfaceFlinger的实现为:

* frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

sp SurfaceFlinger::createConnection() {
    return initClient(new Client(this));
}

static sp initClient(const sp& client) {
    status_t err = client->initCheck();
    if (err == NO_ERROR) {
        return client;
    }
    return nullptr;
}

Client继承BnSurfaceComposerClient,是ISurfaceComposerClient的Bn端。

我们来看一下,显示系统中,Client和SurfaceFlinger的关系:


Android P 图形显示系统(五) 上层Client和SurfaceFlinger的交互_第1张图片
Client和SurfaceFlinger间的关系

应用端SurfaceComposerClient通过接口ISurfaceComposerClient和SurfaceFlinger的Client建立联系。应用端通过的ComposerService通过ISurfaceComposer和SurfaceFlinger建立联系。

SurfaceFlinger的启动

SurfaceFlinger是一个系统级的服务,Android系统启动的过程中就会启动SurfaceFlinger,在初始化init时。

* frameworks/native/services/surfaceflinger/surfaceflinger.rc

service surfaceflinger /system/bin/surfaceflinger
    class core animation
    user system
    group graphics drmrpc readproc
    onrestart restart zygote
    writepid /dev/stune/foreground/tasks
    socket pdx/system/vr/display/client     stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
    socket pdx/system/vr/display/manager    stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0
    socket pdx/system/vr/display/vsync      stream 0666 system graphics u:object_r:pdx_display_vsync_endpoint_socket:s0

既然是独立的进程,系统级的服务,那就有自己的main函数:

* frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp

int main(int, char**) {
    startHidlServices();

    signal(SIGPIPE, SIG_IGN);
    // When SF is launched in its own process, limit the number of
    // binder threads to 4.
    ProcessState::self()->setThreadPoolMaxThreadCount(4);

    // start the thread pool
    sp ps(ProcessState::self());
    ps->startThreadPool();

    // instantiate surfaceflinger
    sp flinger = new SurfaceFlinger();

    setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);

    set_sched_policy(0, SP_FOREGROUND);

    // Put most SurfaceFlinger threads in the system-background cpuset
    // Keeps us from unnecessarily using big cores
    // Do this after the binder thread pool init
    if (cpusets_enabled()) set_cpuset_policy(0, SP_SYSTEM);

    // initialize before clients can connect
    flinger->init();

    // publish surface flinger
    sp sm(defaultServiceManager());
    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
                   IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL);

    // publish GpuService
    sp gpuservice = new GpuService();
    sm->addService(String16(GpuService::SERVICE_NAME), gpuservice, false);

    struct sched_param param = {0};
    param.sched_priority = 2;
    if (sched_setscheduler(0, SCHED_FIFO, ¶m) != 0) {
        ALOGE("Couldn't set SCHED_FIFO");
    }

    // run surface flinger in this thread
    flinger->run();

    return 0;
}

SurfacFlinger进程中主要4个服务:

  • startHidlServices主要是启动allocator
  • DisplayService,主要负责DisplayEvent的处理
  • SurfaceFlinger,主要显示相关的,最重要的服务
  • GpuService,GPU相关的服务,为访问GPU

SurfaceFlinger类定义如下:

* frameworks/native/services/surfaceflinger/SurfaceFlinger.h

class SurfaceFlinger : public BnSurfaceComposer,
                       public PriorityDumper,
                       private IBinder::DeathRecipient,
                       private HWC2::ComposerCallback

SurfaceComposer是ISurfaceComposer的Bn端。实现了HWC2的ComposerCallback回调。死亡回收DeathRecipient,以及Dump信息PriorityDumper。

构造函数如下:

* frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

SurfaceFlinger::SurfaceFlinger()
    :   BnSurfaceComposer(),
        mTransactionFlags(0),
        mTransactionPending(false),
        mAnimTransactionPending(false),
        mLayersRemoved(false),
        mLayersAdded(false),
        mRepaintEverything(0),
        mBootTime(systemTime()),
        mBuiltinDisplays(),
        mVisibleRegionsDirty(false),
        mGeometryInvalid(false),
        mAnimCompositionPending(false),
        mDebugRegion(0),
        mDebugDDMS(0),
        mDebugDisableHWC(0),
        mDebugDisableTransformHint(0),
        mDebugInSwapBuffers(0),
        mLastSwapBufferTime(0),
        mDebugInTransaction(0),
        mLastTransactionTime(0),
        mBootFinished(false),
        mForceFullDamage(false),
        mInterceptor(this),
        mPrimaryDispSync("PrimaryDispSync"),
        mPrimaryHWVsyncEnabled(false),
        mHWVsyncAvailable(false),
        mHasColorMatrix(false),
        mHasPoweredOff(false),
        mNumLayers(0),
        mVrFlingerRequestsDisplay(false),
        mMainThreadId(std::this_thread::get_id())
{
    ALOGI("SurfaceFlinger is starting");

    vsyncPhaseOffsetNs = getInt64< ISurfaceFlingerConfigs,
            &ISurfaceFlingerConfigs::vsyncEventPhaseOffsetNs>(1000000);

    ... ...

    mPrimaryDispSync.init(SurfaceFlinger::hasSyncFramework, SurfaceFlinger::dispSyncPresentTimeOffset);

    // debugging stuff...
    char value[PROPERTY_VALUE_MAX];

    ... ...

    property_get("ro.sf.disable_triple_buffer", value, "1");
    mLayerTripleBufferingDisabled = atoi(value);
    ALOGI_IF(mLayerTripleBufferingDisabled, "Disabling Triple Buffering");

    ... ...
}

在构造函数中,主要是做初始化。从Android O开始,vendor的一些配置,都采用configstore的方式提供,就是这里的ISurfaceFlingerConfigs,这是一个系统服务。对应的接口在 hardware/interfaces/configstore/ 。当然,采用属性进行设置,但是属性设置的是debug的参数居多。

SurfaceFlinger真正的初始化,是在init函数中:

void SurfaceFlinger::init() {
    ... ...

    Mutex::Autolock _l(mStateLock);

    // start the EventThread
    sp vsyncSrc =
            new DispSyncSource(&mPrimaryDispSync, SurfaceFlinger::vsyncPhaseOffsetNs, true, "app");
    mEventThread = new EventThread(vsyncSrc, *this, false);
    sp sfVsyncSrc =
            new DispSyncSource(&mPrimaryDispSync, SurfaceFlinger::sfVsyncPhaseOffsetNs, true, "sf");
    mSFEventThread = new EventThread(sfVsyncSrc, *this, true);
    mEventQueue.setEventThread(mSFEventThread);

    // set EventThread and SFEventThread to SCHED_FIFO to minimize jitter
    struct sched_param param = {0};
    param.sched_priority = 2;
    if (sched_setscheduler(mSFEventThread->getTid(), SCHED_FIFO, ¶m) != 0) {
        ALOGE("Couldn't set SCHED_FIFO for SFEventThread");
    }
    if (sched_setscheduler(mEventThread->getTid(), SCHED_FIFO, ¶m) != 0) {
        ALOGE("Couldn't set SCHED_FIFO for EventThread");
    }

    // Get a RenderEngine for the given display / config (can't fail)
    getBE().mRenderEngine = RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888,
            hasWideColorDisplay ? RenderEngine::WIDE_COLOR_SUPPORT : 0);
    LOG_ALWAYS_FATAL_IF(getBE().mRenderEngine == nullptr, "couldn't create RenderEngine");

    LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
            "Starting with vr flinger active is not currently supported.");
    getBE().mHwc.reset(new HWComposer(getBE().mHwcServiceName));
    getBE().mHwc->registerCallback(this, getBE().mComposerSequenceId);

    if (useVrFlinger) {
        auto vrFlingerRequestDisplayCallback = [this] (bool requestDisplay) {
            // This callback is called from the vr flinger dispatch thread. We
            // need to call signalTransaction(), which requires holding
            // mStateLock when we're not on the main thread. Acquiring
            // mStateLock from the vr flinger dispatch thread might trigger a
            // deadlock in surface flinger (see b/66916578), so post a message
            // to be handled on the main thread instead.
            sp message = new LambdaMessage([=]() {
                ALOGI("VR request display mode: requestDisplay=%d", requestDisplay);
                mVrFlingerRequestsDisplay = requestDisplay;
                signalTransaction();
            });
            postMessageAsync(message);
        };
        mVrFlinger = dvr::VrFlinger::Create(getBE().mHwc->getComposer(),
                getBE().mHwc->getHwcDisplayId(HWC_DISPLAY_PRIMARY).value_or(0),
                vrFlingerRequestDisplayCallback);
        if (!mVrFlinger) {
            ALOGE("Failed to start vrflinger");
        }
    }

    mEventControlThread = new EventControlThread(this);
    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);

    // initialize our drawing state
    mDrawingState = mCurrentState;

    // set initial conditions (e.g. unblank default device)
    initializeDisplays();

    getBE().mRenderEngine->primeCache();

    // Inform native graphics APIs whether the present timestamp is supported:
    if (getHwComposer().hasCapability(
            HWC2::Capability::PresentFenceIsNotReliable)) {
        mStartPropertySetThread = new StartPropertySetThread(false);
    } else {
        mStartPropertySetThread = new StartPropertySetThread(true);
    }

    if (mStartPropertySetThread->Start() != NO_ERROR) {
        ALOGE("Run StartPropertySetThread failed!");
    }

    ALOGV("Done initializing");
}

在init函数中,主要做了一下几件事:

  • 创建两个EventThread及其DispSyncSource,主要是用以处理和分发如Vsync;App和SurfaceFlinger的如Vsync是分开的,不是同一个。
  • 创建了自己的消息队列mEventQueue,SurfaceFlinger的消息队列
  • 初始化了Client合成模式(GPU)合成时,需要用到的RenderEngine
  • 初始化HWComposer,注册回调接口registerCallback,HAL会回调一些方法。
  • 如果是VR模式,创建mVrFlinger
  • 创建mEventControlThread,处理Event事件,如Vsync事件和hotplug事件。
  • 初始化显示设备initializeDisplays

SurfaceFlinger第一次引用时,启动mEventQueue消息队列

void SurfaceFlinger::onFirstRef()
{
    mEventQueue.init(this);
}

SurfaceFlinger这边后续再继续,先回到Native应用的创建

获取Display信息

Android支持多给屏幕,多个屏幕可以显示一样的内容,也可以显示不一样的内容。我们通常的把他们称为主显,外显和虚显。主显就是内置的,默认的手机屏幕;外显就是HDMI,MHL等连接的屏幕;虚显,就是虚拟显示器,通过WFD连接的屏幕,或者是类似屏幕一样的Buffer消费者。
屏幕都是通过ID来标记的:

* frameworks/native/services/surfaceflinger/DisplayDevice.h

    enum DisplayType {
        DISPLAY_ID_INVALID = -1,
        DISPLAY_PRIMARY     = HWC_DISPLAY_PRIMARY, //主显
        DISPLAY_EXTERNAL    = HWC_DISPLAY_EXTERNAL, //外显
        DISPLAY_VIRTUAL     = HWC_DISPLAY_VIRTUAL, //虚显4
        NUM_BUILTIN_DISPLAY_TYPES = HWC_NUM_PHYSICAL_DISPLAY_TYPES,
    };

通过getBuiltInDisplay,去获取指定ID的屏幕。

sp SurfaceComposerClient::getBuiltInDisplay(int32_t id) {
    return ComposerService::getComposerService()->getBuiltInDisplay(id);
}

getBuiltInDisplay是一个Binder调用,中间的Binder就省掉了,直接看实现:

sp SurfaceFlinger::getBuiltInDisplay(int32_t id) {
    if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
        ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
        return NULL;
    }
    return mBuiltinDisplays[id];
}

前面初始化的时候,屏幕都是采用热插拔的形式上报。内置屏幕也是这样。这个后续再介绍。

获取屏幕后,通过getDisplayInfo函数,就能获取屏幕的信息。

    DisplayInfo mainDisplayInfo;
    err = SurfaceComposerClient::getDisplayInfo(mainDisplay, &mainDisplayInfo);
    if (err != NO_ERROR) {
        fprintf(stderr, "ERROR: unable to get display characteristics\n");
        return;
    }

一个屏幕可以有多个config信息,当前再用的是activeconfig。在SurfaceComposerClient中,获取config信息时,先获取多有的config信息,再获取active的config的ID,根据ID去取Display信息。

status_t SurfaceComposerClient::getDisplayInfo(const sp& display,
        DisplayInfo* info) {
    Vector configs;
    status_t result = getDisplayConfigs(display, &configs);
    if (result != NO_ERROR) {
        return result;
    }

    int activeId = getActiveConfig(display);
    if (activeId < 0) {
        ALOGE("No active configuration found");
        return NAME_NOT_FOUND;
    }

    *info = configs[static_cast(activeId)];
    return NO_ERROR;
}

getDisplayConfigs还是通过ComposerService去获取的,走的ISurfaceComposer的接口。

status_t SurfaceComposerClient::getDisplayConfigs(
        const sp& display, Vector* configs)
{
    return ComposerService::getComposerService()->getDisplayConfigs(display, configs);
}

在看SurfaceFlinger中getDisplayConfigs的实现之前。我们先来看DisplayInfo的定义,看看Display信息都包含哪些。看看怎么来描述一个显示屏幕。

struct DisplayInfo {
    uint32_t w{0}; // 屏幕的宽
    uint32_t h{0}; // 屏幕的高
    float xdpi{0}; // 屏幕的x方向每英寸的像素点
    float ydpi{0}; // 屏幕y方向每英寸的像素点
    float fps{0}; // FPS屏幕的刷新率
    float density{0}; // 屏幕的密度
    uint8_t orientation{0}; // 屏幕的旋转方式
    bool secure{false}; // 屏幕是否是安全的
    nsecs_t appVsyncOffset{0}; // App的Vsync的偏移
    nsecs_t presentationDeadline{0}; // 显示的最后时间
};

我们结合SurfaceFlinger中getDisplayConfigs的实现,来说说Display的信息。

  • 首先,根据Display的IBinder,找到Display的类型type。
* frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

status_t SurfaceFlinger::getDisplayConfigs(const sp& display,
        Vector* configs) {
    ... ...

    int32_t type = NAME_NOT_FOUND;
    for (int i=0 ; i
  • 在根据type去获取驱动中配置的信息getConfigs,getHwComposer().getConfigs(type);
    ConditionalLock _l(mStateLock,
            std::this_thread::get_id() != mMainThreadId);
    for (const auto& hwConfig : getHwComposer().getConfigs(type)) {
  • 最后,根据驱动给的配置,和一些设置,构建完整的显示屏信息,下面是关键信息,删掉了一些log和注解。
    for (const auto& hwConfig : getHwComposer().getConfigs(type)) {
        DisplayInfo info = DisplayInfo();

        float xdpi = hwConfig->getDpiX();
        float ydpi = hwConfig->getDpiY();

        if (type == DisplayDevice::DISPLAY_PRIMARY) {
            float density = Density::getBuildDensity() / 160.0f;
            if (density == 0) {
                density = xdpi / 160.0f;
            }
            if (Density::getEmuDensity()) {
                xdpi = ydpi = density = Density::getEmuDensity();
                density /= 160.0f;
            }
            info.density = density;

            sp hw(getDefaultDisplayDeviceLocked());
            info.orientation = hw->getOrientation();
        } else {
            static const int TV_DENSITY = 213;
            info.density = TV_DENSITY / 160.0f;
            info.orientation = 0;
        }

        info.w = hwConfig->getWidth();
        info.h = hwConfig->getHeight();
        info.xdpi = xdpi;
        info.ydpi = ydpi;
        info.fps = 1e9 / hwConfig->getVsyncPeriod();
        info.appVsyncOffset = vsyncPhaseOffsetNs;

        ... ...
        info.presentationDeadline = hwConfig->getVsyncPeriod() -
                sfVsyncPhaseOffsetNs + 1000000;

        // All non-virtual displays are currently considered secure.
        info.secure = true;

        configs->push_back(info);
    }

    return NO_ERROR;
}

屏幕信息:

  • 屏幕宽高(W*H)
    屏幕的宽高是用分辨率来描述的,也就是像素点的多少。像素是指在由一个数字序列表示的图像中的一个最小单位,称为像素。屏幕多宽,就是指,屏幕横向可以显示多少个像素点。屏幕多高就是指,屏幕纵向可以显示多少给像素点。平常所说的720P屏幕,就是1080x720,横向可以显示1080个像素点,纵向可以显示720个像素点。
    此图是,平常什么所说的一些分辨率:


    Android P 图形显示系统(五) 上层Client和SurfaceFlinger的交互_第2张图片
    常用的分辨率
  • 每英寸的点数xdpi,ydpi
    显示屏幕的物理大小,用英寸来描述,描述屏幕对角线的长度。比如iPhoneX 5.8英寸,指的是对角线的长度5.8英寸。而dpi,即Dots Per Inch,表示每英寸有多少给点。百度百科的解释为,dpi是一个量度单位,用于点阵数码影像,指每一英寸长度中,取样、可显示或输出点的数目。
    PPI(pixels per inch)和DPI是措辞的差别,很多时候,都是混用的。如iPhoneX是458 ppi;荣耀V9的DPI为488左右。

  • density密度
    这里的desity是一个缩放因子,是 DPI / (160像素/英寸) 后得到的值,是一个比例值。
    这可以看DisplayMetrics中关于density的定义:

frameworks/base/core/java/android/util/DisplayMetrics.java

    /**
     * The logical density of the display.  This is a scaling factor for the
     * Density Independent Pixel unit, where one DIP is one pixel on an
     * approximately 160 dpi screen (for example a 240x320, 1.5"x2" screen), 
     * providing the baseline of the system's display. Thus on a 160dpi screen 
     * this density value will be 1; on a 120 dpi screen it would be .75; etc.
     *
     * 

This value does not exactly follow the real screen size (as given by * {@link #xdpi} and {@link #ydpi}, but rather is used to scale the size of * the overall UI in steps based on gross changes in the display dpi. For * example, a 240x320 screen will have a density of 1 even if its width is * 1.8", 1.3", etc. However, if the screen resolution is increased to * 320x480 but the screen size remained 1.5"x2" then the density would be * increased (probably to 1.5). * * @see #DENSITY_DEFAULT */ public float density;

以设备无关像素DIP(device independent pixels)在160dpi屏幕上显示为基础。160dip在160dpi的屏幕上,density就是1,在120dpi的屏幕上,density就为0.75。

  • 屏幕刷新率FPS
    FPS(Frame per second),帧每秒。表示屏幕一描述,可以显示多少帧图像数据。目前多少的手机显示屏还是60FPS,显示一帧16.67ms左右。

  • orientation屏幕旋转方向
    手机默认竖屏,0度竖屏。

/* Display orientations as defined in Surface.java and ISurfaceComposer.h. */
enum {
    DISPLAY_ORIENTATION_0 = 0,
    DISPLAY_ORIENTATION_90 = 1,
    DISPLAY_ORIENTATION_180 = 2,
    DISPLAY_ORIENTATION_270 = 3
};
  • 屏幕是否安全secure
    这主要是用于DRM(数字版权保护)时,确保显示的设备是安全的,以防止DRM的内容被在显示的过程中被截取。只有安全的设备才能显示DRM的内容。
    Android默认,所有的非虚拟显示都是安全的。
        // All non-virtual displays are currently considered secure.
        info.secure = true;
  • appVsyncOffset和presentationDeadline
    这两个都和 Vsync有关,后续会再介绍。appVsyncOffset是一个偏移量,在系统(或硬件Vsync)的基础上做一些偏移。presentationDeadline表示,一帧数据,多就内,必现要显示出来。

Ok~到此,SurfaceComposerClient端就拿到了多个config信息了,在configs中。

Active config,就是当前被激活使用的:

int SurfaceFlinger::getActiveConfig(const sp& display) {
    if (display == NULL) {
        ALOGE("%s : display is NULL", __func__);
        return BAD_VALUE;
    }

    sp device(getDisplayDevice(display));
    if (device != NULL) {
        return device->getActiveConfig();
    }

    return BAD_VALUE;
}

SurfaceFlinger服务中,Display的描述,用的DisplayDevice。每添加一个显示屏,都会创建一个DisplayDevice。

int DisplayDevice::getActiveConfig()  const {
    return mActiveConfig;
}

activeconfig,是一个索引值,对应驱动中,对应的config的索引。一般来说,active的config,都是默认的0。当然SurfaceFlinger或上层是可以去设置的。

void DisplayDevice::setActiveConfig(int mode) {
    mActiveConfig = mode;
}

回到应用~

Native创建图层Layer

拿到显示信息后,根据转屏,这边的尺寸需要做一下交换。因为不关屏幕怎么旋转,我们需要显示的内容大小是没有变的。

    uint32_t width, height;
    if (mainDisplayInfo.orientation != DISPLAY_ORIENTATION_0 &&
            mainDisplayInfo.orientation != DISPLAY_ORIENTATION_180) {
        // rotated
        width = mainDisplayInfo.h;
        height = mainDisplayInfo.w;
    } else {
        width = mainDisplayInfo.w;
        height = mainDisplayInfo.h;
    }

接下里,就可以创建图层了。

    sp surfaceControl = surfaceComposerClient->createSurface(
            mName, width, height,
            PIXEL_FORMAT_RGBX_8888, ISurfaceComposerClient::eOpaque);
    if (surfaceControl == NULL || !surfaceControl->isValid()) {
        fprintf(stderr, "Failed to create SurfaceControl\n");
        return;
    }

createSurface函数如下:

sp SurfaceComposerClient::createSurface(
        const String8& name,
        uint32_t w,
        uint32_t h,
        PixelFormat format,
        uint32_t flags,
        SurfaceControl* parent,
        uint32_t windowType,
        uint32_t ownerUid)
{
    sp sur;
    if (mStatus == NO_ERROR) {
        sp handle;
        sp parentHandle;
        sp gbp;

        if (parent != nullptr) {
            parentHandle = parent->getHandle();
        }
        status_t err = mClient->createSurface(name, w, h, format, flags, parentHandle,
                windowType, ownerUid, &handle, &gbp);
        ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
        if (err == NO_ERROR) {
            sur = new SurfaceControl(this, handle, gbp);
        }
    }
    return sur;
}

先解释一下,其中的参数:

  • name
    name就是图层的名字,没有实际意义,主要是便于debug,有有名字,就可以知道,我们创建的图层是哪个了。

  • w,h
    这个是图层的宽高,我们用只是从DisplayInfo中读出来的,跟屏幕的大小一样。

  • format
    图层的格式,应用中,我们用的格式是PIXEL_FORMAT_RGBX_8888。

我们通过RGB,红,绿,蓝,三原色可以调配所有的颜色。在数字世界里面,也是用RGB来表示颜色,外加一个Alpha通道,就是RGBA。
RGBA_8888,表示R,G,B,A分别用8bit表示。也就是说,R的取值范围为0255。R从0255,表示最不红到最红,值的大小,表示红的程度不同。

同样,Alpha A,也是表示透明的程度,RGBX中的X表示,X为255,不透明。

下面是Android中,常用的一些格式。

* frameworks/native/libs/ui/include/ui/PixelFormat.h

enum {
    //
    // these constants need to match those
    // in graphics/PixelFormat.java & pixelflinger/format.h
    //
    PIXEL_FORMAT_UNKNOWN    =   0,
    PIXEL_FORMAT_NONE       =   0,

    // logical pixel formats used by the SurfaceFlinger -----------------------
    PIXEL_FORMAT_CUSTOM         = -4,
        // Custom pixel-format described by a PixelFormatInfo structure

    PIXEL_FORMAT_TRANSLUCENT    = -3,
        // System chooses a format that supports translucency (many alpha bits)

    PIXEL_FORMAT_TRANSPARENT    = -2,
        // System chooses a format that supports transparency
        // (at least 1 alpha bit)

    PIXEL_FORMAT_OPAQUE         = -1,
        // System chooses an opaque format (no alpha bits required)

    // real pixel formats supported for rendering -----------------------------

    PIXEL_FORMAT_RGBA_8888    = HAL_PIXEL_FORMAT_RGBA_8888,    // 4x8-bit RGBA
    PIXEL_FORMAT_RGBX_8888    = HAL_PIXEL_FORMAT_RGBX_8888,    // 4x8-bit RGB0
    PIXEL_FORMAT_RGB_888      = HAL_PIXEL_FORMAT_RGB_888,      // 3x8-bit RGB
    PIXEL_FORMAT_RGB_565      = HAL_PIXEL_FORMAT_RGB_565,      // 16-bit RGB
    PIXEL_FORMAT_BGRA_8888    = HAL_PIXEL_FORMAT_BGRA_8888,    // 4x8-bit BGRA
    PIXEL_FORMAT_RGBA_5551    = 6,                             // 16-bit ARGB
    PIXEL_FORMAT_RGBA_4444    = 7,                             // 16-bit ARGB
    PIXEL_FORMAT_RGBA_FP16    = HAL_PIXEL_FORMAT_RGBA_FP16,    // 64-bit RGBA
    PIXEL_FORMAT_RGBA_1010102 = HAL_PIXEL_FORMAT_RGBA_1010102, // 32-bit RGBA
};
  • flags
    createSurface时,可用的flag如下:
* frameworks/native/libs/gui/include/gui/ISurfaceComposerClient.h

    // flags for createSurface()
    enum { // (keep in sync with Surface.java)
        eHidden = 0x00000004,
        eDestroyBackbuffer = 0x00000020,
        eSecure = 0x00000080,
        eNonPremultiplied = 0x00000100,
        eOpaque = 0x00000400,
        eProtectedByApp = 0x00000800,
        eProtectedByDRM = 0x00001000,
        eCursorWindow = 0x00002000,

        eFXSurfaceNormal = 0x00000000,
        eFXSurfaceColor = 0x00020000,
        eFXSurfaceMask = 0x000F0000,
    };
Flag 作用 说明
eHidden 隐藏 表示Layer是不可见的
eDestroyBackbuffer 销毁Back Buffer 表示Layer不保存Back Buffer
eSecure 安全layer 表示安全的Layer,只能显示在Secure屏幕上
eNonPremultiplied 非自左乘 针对Alpha通道的,如果没有Alpha通道没有实际意义
eOpaque 非透明的 表示Layer不是透明的
eProtectedByApp 应用保护 应用将请求一个安全的硬件通道传输到外显
eProtectedByDRM DRM保护 应用请求一个安全的通道传输DRM
eCursorWindow Cursor Layer 其实这Layer就是鼠标一类的图标
eFXSurfaceNormal 普通的Layer 系统中大多数layer都是此类
eFXSurfaceColor 颜色layer 在之前的版本中,这个被称为Dim Layer
  • windowType
    窗口类型,可以参照WindowManager.java中的定义,如FIRST_SYSTEM_WINDOW,TYPE_STATUS_BAR等。默认值为0。
  • ownerUid
    可以指定这个是哪个UID的Layer。

继续看createSurfface,Service端的实现如下:

status_t Client::createSurface(
        const String8& name,
        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
        const sp& parentHandle, uint32_t windowType, uint32_t ownerUid,
        sp* handle,
        sp* gbp)
{
    sp parent = nullptr;
    ... ...

    /*
     * createSurface must be called from the GL thread so that it can
     * have access to the GL context.
     */
    class MessageCreateLayer : public MessageBase {
        ... ...
    public:
        MessageCreateLayer(SurfaceFlinger* flinger,
                const String8& name, Client* client,
                uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
                sp* handle, uint32_t windowType, uint32_t ownerUid,
                sp* gbp,
                sp* parent)
            : flinger(flinger), client(client),
              handle(handle), gbp(gbp), result(NO_ERROR),
              name(name), w(w), h(h), format(format), flags(flags),
              parent(parent), windowType(windowType), ownerUid(ownerUid) {
        }
        status_t getResult() const { return result; }
        virtual bool handler() {
            result = flinger->createLayer(name, client, w, h, format, flags,
                    windowType, ownerUid, handle, gbp, parent);
            return true;
        }
    };

    sp msg = new MessageCreateLayer(mFlinger.get(),
            name, this, w, h, format, flags, handle,
            windowType, ownerUid, gbp, &parent);
    mFlinger->postMessageSync(msg);
    return static_cast( msg.get() )->getResult();
}

Client类中,创建Layer时,先找到parent Layer,对于我们的应用来说,是没有parent Layer的。然后再postMessageSync到SurfaceFlinger中,去创建,调用的SurfaceFlinger的createLayer方法。

SurfaceFlinger中,都是采用post Message的形式调到SurfaceFlinger的主线程中。

status_t SurfaceFlinger::createLayer(
        const String8& name,
        const sp& client,
        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
        uint32_t windowType, uint32_t ownerUid, sp* handle,
        sp* gbp, sp* parent)
{
    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;

    String8 uniqueName = getUniqueLayerName(name);

    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
        case ISurfaceComposerClient::eFXSurfaceNormal:
            result = createBufferLayer(client,
                    uniqueName, w, h, flags, format,
                    handle, gbp, &layer);

            break;
        case ISurfaceComposerClient::eFXSurfaceColor:
            result = createColorLayer(client,
                    uniqueName, w, h, flags,
                    handle, &layer);
            break;
        default:
            result = BAD_VALUE;
            break;
    }

    if (result != NO_ERROR) {
        return result;
    }

    // window type is WINDOW_TYPE_DONT_SCREENSHOT from SurfaceControl.java
    // TODO b/64227542
    if (windowType == 441731) {
        windowType = 2024; // TYPE_NAVIGATION_BAR_PANEL
        layer->setPrimaryDisplayOnly();
    }

    layer->setInfo(windowType, ownerUid);

    result = addClientLayer(client, *handle, *gbp, layer, *parent);
    if (result != NO_ERROR) {
        return result;
    }
    mInterceptor.saveSurfaceCreation(layer);

    setTransactionFlags(eTransactionNeeded);
    return result;
}

getUniqueLayerName,确保Layer 的name没有重名。

SurfaceFlinger中,主要处理两中类似的Layer,eFXSurfaceNormal和eFXSurfaceColor。两种类似分别有createBufferLayer和createColorLayer两个接口实现。怎么创建的这里就不介绍了,后续再介绍。

addClientLayer做了什么:

status_t SurfaceFlinger::addClientLayer(const sp& client,
        const sp& handle,
        const sp& gbc,
        const sp& lbc,
        const sp& parent)
{
    // add this layer to the current state list
    {
        Mutex::Autolock _l(mStateLock);
        if (mNumLayers >= MAX_LAYERS) {
            ALOGE("AddClientLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers,
                  MAX_LAYERS);
            return NO_MEMORY;
        }
        if (parent == nullptr) {
            mCurrentState.layersSortedByZ.add(lbc);
        } else {
            if (parent->isPendingRemoval()) {
                ALOGE("addClientLayer called with a removed parent");
                return NAME_NOT_FOUND;
            }
            parent->addChild(lbc);
        }

        mGraphicBufferProducerList.add(IInterface::asBinder(gbc));
        mLayersAdded = true;
        mNumLayers++;
    }

    // attach this layer to the client
    client->attachLayer(handle, lbc);

    return NO_ERROR;
}

将新创建的Layer添加到当前的layer列表中,按照Z-order。如果有parent的,添加到parent中。mGraphicBufferProducerList保存了当前的所有Layer内容的生产者。最后,将Layer关联的Client上。

Layer创建完成后,调用setTransactionFlags函数,告诉SurfaceFlinger,新增加了Layer,有新的显示,有很多显示数据需要去更新。SurfaceFlinger根据flag,决定是否需要换醒服务。

uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
    if ((old & flags)==0) { // wake the server up
        signalTransaction();
    }
    return old;
}

Layer创建完成,回到我们的应用~

处理状态的传送

应用的代码如下:

    SurfaceComposerClient::Transaction{}
            .setLayer(surfaceControl, 0x7FFFFFFF)
            .show(surfaceControl)
            .apply();

C++的新特性,是不是有点类似Java了。

从Android P开始,google又重构了这一块的代码。之前的代码中,是SurfaceComposerClient提供全局的状态处理;从Android P开始,transactions 被区分为不同的对象,直接处理对象。这是Transaction一个类图。


Android P 图形显示系统(五) 上层Client和SurfaceFlinger的交互_第3张图片
Transaction类图

可见,将处理类型分为了两类:

  • ComposerState 合成处理状态
struct ComposerState {
    sp client;
    layer_state_t state;
    status_t    write(Parcel& output) const;
    status_t    read(const Parcel& input);
};

ComposerState封装了layer_state_t,Layer的状态,再实现Binder通信时的write,read。

  • DisplayState 显示屏状态
struct DisplayState {

    enum {
        eOrientationDefault     = 0,
        eOrientation90          = 1,
        eOrientation180         = 2,
        eOrientation270         = 3,
        eOrientationUnchanged   = 4,
        eOrientationSwapMask    = 0x01
    };

    enum {
        eSurfaceChanged             = 0x01,
        eLayerStackChanged          = 0x02,
        eDisplayProjectionChanged   = 0x04,
        eDisplaySizeChanged         = 0x08
    };

    DisplayState();
    void merge(const DisplayState& other);

    uint32_t what;
    sp token;
    sp surface;
    uint32_t layerStack;
    uint32_t orientation;
    Rect viewport;
    Rect frame;
    uint32_t width, height;
    status_t write(Parcel& output) const;
    status_t read(const Parcel& input);
};

Display的状态目前就4个,也就是

    enum {
        eSurfaceChanged             = 0x01, // Surface改变了
        eLayerStackChanged          = 0x02, // layerStack改变了
        eDisplayProjectionChanged   = 0x04, // Display的Projection改变了
        eDisplaySizeChanged         = 0x08 // Size改变了
    };

这里的what,就是用以标记mark到底是哪个属性改变了,有多个属性改变的时候,加上对应的mark标记位即可。

ComposerState中的layer_state_t和这里的DisplayState类似。也是采用what来标记的。Layer的状态处理,包括以下属性。

    enum {
        ePositionChanged            = 0x00000001,
        eLayerChanged               = 0x00000002,
        eSizeChanged                = 0x00000004,
        eAlphaChanged               = 0x00000008,
        eMatrixChanged              = 0x00000010,
        eTransparentRegionChanged   = 0x00000020,
        eFlagsChanged               = 0x00000040,
        eLayerStackChanged          = 0x00000080,
        eCropChanged                = 0x00000100,
        eDeferTransaction           = 0x00000200,
        eFinalCropChanged           = 0x00000400,
        eOverrideScalingModeChanged = 0x00000800,
        eGeometryAppliesWithResize  = 0x00001000,
        eReparentChildren           = 0x00002000,
        eDetachChildren             = 0x00004000,
        eRelativeLayerChanged       = 0x00008000,
        eReparent                   = 0x00010000,
        eColorChanged               = 0x00020000
    };

好了,让我们通过本实例中的示例,来看看状态处理是怎么传递,生效的。

setLayer,实际上是设置Layer的z-order,

SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLayer(
        const sp& sc, int32_t z) {
    layer_state_t* s = getLayerStateLocked(sc);
    if (!s) {
        mStatus = BAD_INDEX;
        return *this;
    }
    s->what |= layer_state_t::eLayerChanged;
    s->z = z;
    return *this;
}

getLayerStateLocked,就是根据SurfaceCotrol对象去找,对应的layer_state_t。

layer_state_t* SurfaceComposerClient::Transaction::getLayerStateLocked(const sp& sc) {
    ComposerState s;
    s.client = sc->getClient()->mClient;
    s.state.surface = sc->getHandle();

    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);
}

我们看,setLayer时,增加mask标识what是layer_state_t::eLayerChanged,而对应的值保存到layer_state_t z中。注意,这里的设置并没有立即生效。

同样,show时,也是将对应的mask表示加到what中,而是否显示的标识存放在layer_state_t的flag中。

SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::show(
        const sp& sc) {
    return setFlags(sc, 0, layer_state_t::eLayerHidden);
}

SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFlags(
        const sp& sc, uint32_t flags,
        uint32_t mask) {
    layer_state_t* s = getLayerStateLocked(sc);
    if (!s) {
        mStatus = BAD_INDEX;
        return *this;
    }
    if ((mask & layer_state_t::eLayerOpaque) ||
            (mask & layer_state_t::eLayerHidden) ||
            (mask & layer_state_t::eLayerSecure)) {
        s->what |= layer_state_t::eFlagsChanged;
    }
    s->flags &= ~mask;
    s->flags |= (flags & mask);
    s->mask |= mask;
    return *this;
}

我们设置的处理状态,在apply时,才生效。

status_t SurfaceComposerClient::Transaction::apply(bool synchronous) {
    if (mStatus != NO_ERROR) {
        return mStatus;
    }

    sp sf(ComposerService::getComposerService());

    Vector composerStates;
    Vector displayStates;
    uint32_t flags = 0;

    mForceSynchronous |= synchronous;

    composerStates = mComposerStates;
    mComposerStates.clear();

    displayStates = mDisplayStates;
    mDisplayStates.clear();

    if (mForceSynchronous) {
        flags |= ISurfaceComposer::eSynchronous;
    }
    if (mAnimation) {
        flags |= ISurfaceComposer::eAnimation;
    }

    mForceSynchronous = false;
    mAnimation = false;

    sf->setTransactionState(composerStates, displayStates, flags);
    mStatus = NO_ERROR;
    return NO_ERROR;
}

apply时,最重要的就是调用setTransactionState,

void SurfaceFlinger::setTransactionState(
        const Vector& state,
        const Vector& displays,
        uint32_t flags)
{
    ATRACE_CALL();
    Mutex::Autolock _l(mStateLock);
    uint32_t transactionFlags = 0;

    if (flags & eAnimation) {
        ... ...
        // Animation flag的处理,在Androd P上很少用到,重要是用做模拟back-pressure
    }

    // 处理Display State
    size_t count = displays.size();
    for (size_t i=0 ; i binder = IInterface::asBinder(s.client);
            if (binder != NULL) {
                if (binder->queryLocalInterface(ISurfaceComposerClient::descriptor) != NULL) {
                    sp client( static_cast(s.client.get()) );
                    transactionFlags |= setClientStateLocked(client, s.state);
                }
            }
        }
    }

    // 处理假动画和同步模式
    if (transactionFlags == 0 &&
            ((flags & eSynchronous) || (flags & eAnimation))) {
        transactionFlags = eTransactionNeeded;
    }

    if (transactionFlags) {
       ... ...
    }
}

SurfaceFlinger中,处理状态是怎么工作的呢?

SurfaceF中,有两个状态: mCurrentStatemDrawingState

  • mCurrentState主要是用作接受Client的处理变更请求;需要状态锁mStateLock的保护
  • mDrawingState主要用作,控制合成;只能在SurfaceFlinger的主线程中使用,不需要锁的保护。

其实这很好理解,每个状态中都有显示数据及其处理的描述。mCurrentState在做显示数据的准备,mDrawingState状态,就是将显示数据合成送给Display。两个处理同时进行,两个都处理完后,再将mCurrentState处理状态,给到mDrawingState。主线程根据mDrawingState中描述的显示数据和处理,把数据进行合成。

状态的处理,同样分为Display和Layer。
Client端采用Mask标记的方式,标记处理状态的改变。SurfaceFlinger这边收到后,根据mask标记,再将参数还原出来。保存到mCurrentState中。Display状态的处理如下:

uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
{
    ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token);
    if (dpyIdx < 0)
        return 0;

    uint32_t flags = 0;
    DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx));
    if (disp.isValid()) {
        const uint32_t what = s.what;
        ... ...
        if (what & DisplayState::eDisplaySizeChanged) {
            if (disp.width != s.width) {
                disp.width = s.width;
                flags |= eDisplayTransactionNeeded;
            }
            if (disp.height != s.height) {
                disp.height = s.height;
                flags |= eDisplayTransactionNeeded;
            }
        }
    }
    return flags;
}

Layer状态的处理也是类似的,我们来看一下z-order的处理。

uint32_t SurfaceFlinger::setClientStateLocked(
        const sp& client,
        const layer_state_t& s)
{
    ... ...
    if (what & layer_state_t::eLayerChanged) {
        // NOTE: index needs to be calculated before we update the state
        const auto& p = layer->getParent();
        if (p == nullptr) {
            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
            if (layer->setLayer(s.z) && idx >= 0) {
                mCurrentState.layersSortedByZ.removeAt(idx);
                mCurrentState.layersSortedByZ.add(layer);
                // we need traversal (state changed)
                // AND transaction (list changed)
                flags |= eTransactionNeeded|eTraversalNeeded;
            }
        } else {
            if (p->setChildLayer(layer, s.z)) {
                flags |= eTransactionNeeded|eTraversalNeeded;
            }
        }
    }
    ... ...
}

SurfaceFlinger有两个状态,Layer也是有两个状态的。

bool Layer::setLayer(int32_t z) {
    if (mCurrentState.z == z) return false;
    mCurrentState.sequence++;
    mCurrentState.z = z;
    mCurrentState.modified = true;

    // Discard all relative layering.
    if (mCurrentState.zOrderRelativeOf != nullptr) {
        sp strongRelative = mCurrentState.zOrderRelativeOf.promote();
        if (strongRelative != nullptr) {
            strongRelative->removeZOrderRelative(this);
        }
        mCurrentState.zOrderRelativeOf = nullptr;
    }
    setTransactionFlags(eTransactionNeeded);
    return true;
}

到此,我们的WindowSurfaceWrapper基本算构建完成。

小结

本章从Native应用的角度出发,讲解了应用怎么和SurfaceFlinger建立联系,同时介绍了SurfaceFlinger的启动。我们做应用开发,坑需要根据实际的屏幕参数来做,所以介绍了怎么获取显示屏参数信息;SurfaceFlinger中显示的数据都是通过Layer进行封装,介绍了创建Layer的过程。最后,介绍了,显示的数据参数,也就说处理的状态,怎么从Client端传到SurfaceFlinger的。

你可能感兴趣的:(Android P 图形显示系统(五) 上层Client和SurfaceFlinger的交互)