SharedClient:客户端(Surface)和服务端(Layer)

SurfaceFlinger 在系统启动阶段作为系统服务被加载。应用程序中的每个窗口,对应本地代码中的 Surface ,而 Surface 又对应于 SurfaceFlinger 中的各个 Layer SurfaceFlinger 的主要作用是为这些 Layer 申请内存,根据应用程序的请求管理这些 Layer 显示、隐藏、重画等操作,最终由 SurfaceFlinger 把所有的 Layer 组合到一起,显示到显示器上。当一个应用程序需要在一个 Surface 上进行画图操作时,首先要拿到这个 Surface 在内存中的起始地址,而这块内存是在 SurfaceFlinger 中分配的,因为 SurfaceFlinger 和应用程序并不是运行在同一个进程中,如何在应用客户端( Surface )和服务端( SurfaceFlinger – Layer )之间传递和同步显示缓冲区?这正是本文要讨论的内容。 Surface 的创建过程

我们来看看效果图:
1.png
2011-4-25 16:37 上传
下载附件 (37.81 KB)




       创建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代码:
  1. void SurfaceComposerClient::_init(
  2. const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn)
  3. {
  4. ......
  5. mClient = conn;
  6. if (mClient == 0) {
  7. mStatus = NO_INIT;
  8. return;
  9. }

  10. mControlMemory = mClient->getControlBlock();
  11. mSignalServer = sm;
  12. mControl = static_cast<SharedClient *>(mControlMemory->getBase());
  13. }
复制代码
SharedClient

      在 createConnection阶段, SurfaceFlinger创建 Client对象:
  1. sp<ISurfaceFlingerClient> SurfaceFlinger::createConnection()
  2. {
  3. Mutex::Autolock _l(mStateLock);
  4. uint32_t token = mTokens.acquire();

  5. sp<Client> client = new Client(token, this);
  6. if (client->ctrlblk == 0) {
  7. mTokens.release(token);
  8. return 0;
  9. }
  10. status_t err = mClientsMap.add(token, client);
  11. if (err < 0) {
  12. mTokens.release(token);
  13. return 0;
  14. }
  15. sp<BClient> bclient =
  16. new BClient(this, token, client->getControlBlockMemory());
  17. return bclient;
  18. }
复制代码
再进入 Client的构造函数中,它分配了4K大小的共享内存,并在这块内存上构建了 SharedClient对象:

Java代码:
  1. Client::Client(ClientID clientID, const sp<SurfaceFlinger>& flinger)
  2. : ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger)
  3. {
  4. const int pgsize = getpagesize();
  5. const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));

  6. mCblkHeap = new MemoryHeapBase(cblksize, 0,
  7. "SurfaceFlinger Client control-block");

  8. ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());
  9. if (ctrlblk) { // construct the shared structure in-place.
  10. new(ctrlblk) SharedClient;
  11. }
  12. }
复制代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值