SurfaceFlinger
在系统启动阶段作为系统服务被加载。应用程序中的每个窗口,对应本地代码中的
Surface
,而
Surface
又对应于
SurfaceFlinger
中的各个
Layer
,
SurfaceFlinger
的主要作用是为这些
Layer
申请内存,根据应用程序的请求管理这些
Layer
显示、隐藏、重画等操作,最终由
SurfaceFlinger
把所有的
Layer
组合到一起,显示到显示器上。当一个应用程序需要在一个
Surface
上进行画图操作时,首先要拿到这个
Surface
在内存中的起始地址,而这块内存是在
SurfaceFlinger
中分配的,因为
SurfaceFlinger
和应用程序并不是运行在同一个进程中,如何在应用客户端(
Surface
)和服务端(
SurfaceFlinger – Layer
)之间传递和同步显示缓冲区?这正是本文要讨论的内容。
Surface
的创建过程
我们来看看效果图:
创建Surface的过程基本上分为两步:
1. 建立 SurfaceSession
第一步通常只执行一次,目的是创建一个 SurfaceComposerClient 的实例, JAVA 层通过 JNI 调用本地代码,本地代码创建一个 SurfaceComposerClient 的实例, SurfaceComposerClient 通过 ISurfaceComposer 接口调用 SurfaceFlinger 的 createConnection , SurfaceFlinger 返回一个 ISurfaceFlingerClient 接口给 SurfaceComposerClient ,在 createConnection 的过程中, SurfaceFlinger 创建了用于管理缓冲区切换的 SharedClient ,关于 SharedClient 我们下面再介绍,最后,本地层把 SurfaceComposerClient 的实例返回给 JAVA 层,完成 SurfaceSession 的建立。
2. 利用 SurfaceSession 创建 Surface
JAVA 层通过 JNI 调用本地代码 Surface_Init(), 本地代码首先取得第一步创建的 SurfaceComposerClient 实例,通过 SurfaceComposerClient ,调用 ISurfaceFlingerClient 接口的 createSurface 方法,进入 SurfaceFlinger , SurfaceFlinger 根据参数,创建不同类型的 Layer ,然后调用 Layer 的 setBuffers() 方法,为该 Layer 创建了两个缓冲区,然后返回该 Layer 的 ISurface 接口, SurfaceComposerClient 使用这个 ISurface 接口创建一个 SurfaceControl 实例,并把这个 SurfaceControl 返回给 JAVA 层。
Java代码:
复制代码
SharedClient
在 createConnection阶段, SurfaceFlinger创建 Client对象:
复制代码
再进入
Client的构造函数中,它分配了4K大小的共享内存,并在这块内存上构建了
SharedClient对象:
Java代码:
复制代码
我们来看看效果图:
![1.png 1.png](http://www.apkbus.com/data/attachment/forum/201104/25/163735eyrsjtkmzeivte1m.png)
创建Surface的过程基本上分为两步:
1. 建立 SurfaceSession
第一步通常只执行一次,目的是创建一个 SurfaceComposerClient 的实例, JAVA 层通过 JNI 调用本地代码,本地代码创建一个 SurfaceComposerClient 的实例, SurfaceComposerClient 通过 ISurfaceComposer 接口调用 SurfaceFlinger 的 createConnection , SurfaceFlinger 返回一个 ISurfaceFlingerClient 接口给 SurfaceComposerClient ,在 createConnection 的过程中, SurfaceFlinger 创建了用于管理缓冲区切换的 SharedClient ,关于 SharedClient 我们下面再介绍,最后,本地层把 SurfaceComposerClient 的实例返回给 JAVA 层,完成 SurfaceSession 的建立。
2. 利用 SurfaceSession 创建 Surface
JAVA 层通过 JNI 调用本地代码 Surface_Init(), 本地代码首先取得第一步创建的 SurfaceComposerClient 实例,通过 SurfaceComposerClient ,调用 ISurfaceFlingerClient 接口的 createSurface 方法,进入 SurfaceFlinger , SurfaceFlinger 根据参数,创建不同类型的 Layer ,然后调用 Layer 的 setBuffers() 方法,为该 Layer 创建了两个缓冲区,然后返回该 Layer 的 ISurface 接口, SurfaceComposerClient 使用这个 ISurface 接口创建一个 SurfaceControl 实例,并把这个 SurfaceControl 返回给 JAVA 层。
Java代码:
- void SurfaceComposerClient::_init(
- const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn)
- {
- ......
- mClient = conn;
- if (mClient == 0) {
- mStatus = NO_INIT;
- return;
- }
- mControlMemory = mClient->getControlBlock();
- mSignalServer = sm;
- mControl = static_cast<SharedClient *>(mControlMemory->getBase());
- }
在 createConnection阶段, SurfaceFlinger创建 Client对象:
- sp<ISurfaceFlingerClient> SurfaceFlinger::createConnection()
- {
- Mutex::Autolock _l(mStateLock);
- uint32_t token = mTokens.acquire();
- sp<Client> client = new Client(token, this);
- if (client->ctrlblk == 0) {
- mTokens.release(token);
- return 0;
- }
- status_t err = mClientsMap.add(token, client);
- if (err < 0) {
- mTokens.release(token);
- return 0;
- }
- sp<BClient> bclient =
- new BClient(this, token, client->getControlBlockMemory());
- return bclient;
- }
Java代码:
- Client::Client(ClientID clientID, const sp<SurfaceFlinger>& flinger)
- : ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger)
- {
- const int pgsize = getpagesize();
- const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
- mCblkHeap = new MemoryHeapBase(cblksize, 0,
- "SurfaceFlinger Client control-block");
- ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());
- if (ctrlblk) { // construct the shared structure in-place.
- new(ctrlblk) SharedClient;
- }
- }