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

本文详细介绍了在Android P系统中,Native应用如何与SurfaceFlinger进行交互,包括Native应用的建立、与SurfaceFlinger的链接建立、SurfaceFlinger的启动过程、Display信息获取、图层Layer的创建以及状态处理的传递。文章通过实例展示了如何在Native层创建Surface和设置图层属性,并解释了SurfaceFlinger如何处理这些状态以进行图形显示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


#上层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<ANativeWindow>  getSurface() const;

    int width() {
        return mWidth;
    }

    int height() {
        return mHeight;
    }

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

    sp<SurfaceControl> mSurfaceControl;

    int mWidth;
    int mHeight;
    String8 mName;
};

WindowSurfaceWrapper对应的实现如下:

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

void WindowSurfaceWrapper::onFirstRef() {
    status_t err;

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

    // Get main display parameters.
    sp<IBinder> 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> 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<ANativeWindow> WindowSurfaceWrapper::getSurface() const {
    sp<ANativeWindow> 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<ProcessState> proc(ProcessState::self());
    ProcessState::self()->startThreadPool();

    sp<WindowSurfaceWrapper> 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<ISurfaceComposer> sf(ComposerService::getComposerService());
    if (sf != 0 && mStatus == NO_INIT) {
        auto rootProducer = mParent.promote();
        sp<ISurfaceComposerClient> conn;
        conn = (rootProducer != nullptr) ? sf->createScopedConnection(rootProducer) :
                sf->createConnection();
        if (conn != 0) {
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
}

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

ComposerService::ComposerService()
: Singleton<ComposerService>() {
    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<IBinder>& who) {
            ALOGW("ComposerService remote (surfaceflinger) died [%p]",
                  who.unsafe_get());
            mComposerService.composerServiceDied();
        }
     public:
        explicit DeathObserver(ComposerService& mgr) : mComposerService(mgr) { }
    };

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

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

getComposerService直接返回单实例mComposerService。

/*static*/ sp<ISurfaceComposer> 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<ISurfaceComposer> sf(ComposerService::getComposerService());
    if (sf != 0 && mStatus == NO_INIT) {
        auto rootProducer = mParent.promote();
        sp<ISurfaceComposerClient> 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<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
    return initClient(new Client(this));
}

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

Client继承BnSurfaceComposerClient,是ISurfaceComposerClient的Bn端。

我们来看一下,显示系统中,Client和SurfaceFlinger的关系:
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()->setThreadPoolMaxThr
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夕月风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值