SufraceFlinger图像合成原理(3)-SurfaceFlinger中Layer的创建和销毁

我们知道应用层的一个Activity对应一个窗口,那么一个窗口对应一个Surface, 一个Surface在SurfaceFlinger 进程中对应一个Layer对象, SurfaceView比较特殊不依赖于窗口单独绘制,一个SurfaceView单独对应一个Surface和Layer,接下来我们看下Surface的创建和销毁流程。

3.1 Layer创建

应用窗口的创建要经历Actvity生命周期和ViewRootImpl的调度,大概流程如下:

应用窗口的创建要经历Actvity生命周期和ViewRootImpl的调度,大概流程如下:

下图为WMS 中的窗口和SF中的Layer 对应图:

  • 与WMS 一样,SurfaceFlinger 对layer也采用树形管理
  • Root、Display、Activity 对应的layer 为ContainerLayer ,代表容器;Task 对应EffectLayer;真正绘制的Layer BufferQueueLayer
  • 在树形层级中SF端多出了RelativeLayer ,把Layer A 设置为Layer B的RelativeLayer,那么Layer A的层级要相对于B去计算,不会受其parent影响,常用于在窗口下面显示模糊或者半透明背景, 在task 中的dimmer layer 就是使用了relativeLayer

SF 和 WMS树形数据结构代码定义:

/frameworks/native/services/surfaceflinger/Layer.h

ini 复制代码
   SortedVector<wp<Layer>> zOrderRelatives;
   LayerVector mCurrentChildren{LayerVector::StateSet::Current};
   wp<Layer> mCurrentParent;

/frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java

ini 复制代码
private WindowContainer<WindowContainer> mParent = null;
protected final WindowList<E> mChildren = new WindowList<E>();

我们从创建SurfaceControl开始,SurfaceControl 的构造方法中回调用nativeCreate

/frameworks/base/core/jni/android_view_SurfaceControl.cpp

kotlin 复制代码
  static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
          jstring nameStr, jint w, jint h, jint format, jint flags, jlong parentObject,
          jobject metadataParcel) {
      ScopedUtfChars name(env, nameStr);
      sp<SurfaceComposerClient> client;
                ... ... 
      status_t err = client->createSurfaceChecked(String8(name.c_str()), w, h, format, &surface,
                                                  flags, parentHandle, std::move(metadata));
      surface->incStrong((void *)nativeCreate);
      return reinterpret_cast<jlong>(surface.get());
  }

nativeCreate 继续调用SurfaceComposerClient::createWithSurfaceParent,返回一个native的SurfaceControl 给java层。

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

ini 复制代码
  status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,
                                                       PixelFormat format,
                                                       sp<SurfaceControl>* outSurface, uint32_t flags,
                                                       const sp<IBinder>& parentHandle,
                                                       LayerMetadata metadata,
                                                       uint32_t* outTransformHint) {
      sp<SurfaceControl> sur;
      status_t err = mStatus;
  
      if (mStatus == NO_ERROR) {
          sp<IBinder> handle;
          sp<IGraphicBufferProducer> gbp;
  
          uint32_t transformHint = 0;
          int32_t id = -1;
          err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),
                                       &handle, &gbp, &id, &transformHint);
  
          if (outTransformHint) {
              *outTransformHint = transformHint;
          }
          ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
          if (err == NO_ERROR) {
              *outSurface =
                      new SurfaceControl(this, handle, gbp, id, w, h, format, transformHint, flags);
          }
      }
      return err;
  }

createSurfaceChecked涉及到下面几个对象:

  • sp handle;

Layer 句柄,每次应用进程或system server 设置surface信息,传递handle, SF 通过handle 找到相应的layer,再设置其属性

  • sp gbp;

BpGraphicBufferProducer对象,保存在native 的SurfaceControl 对象和Surface对象中,用于实现对BufferQueue 的操作

  • mClient

ISurfaceComposerClient代理对象, 服务端是SurfaceFlinger 进程的Client

接着来到SurfaceFlinger进程:

/frameworks/native/services/surfaceflinger/Client.cpp

arduino 复制代码
  status_t Client::createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,
                                 uint32_t flags, const sp<IBinder>& parentHandle,
                                 LayerMetadata metadata, sp<IBinder>* handle,
                                 sp<IGraphicBufferProducer>* gbp, int32_t* outLayerId,
                                 uint32_t* outTransformHint) {
      // We rely on createLayer to check permissions.
      return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,
                                   parentHandle, outLayerId, nullptr, outTransformHint);
  }

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

c 复制代码
  status_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& client, uint32_t w,
                                       uint32_t h, PixelFormat format, uint32_t flags,
                                       LayerMetadata metadata, sp<IBinder>* handle,
                                       sp<IGraphicBufferProducer>* gbp,
                                       const sp<IBinder>& parentHandle, int32_t* outLayerId,
                                       const sp<Layer>& parentLayer, uint32_t* outTransformHint) {
  ... ...
      sp<Layer> layer;
  //1. 获取layer 名字,如果有同名layer 在原来名字后面加#1, #2
      std::string uniqueName = getUniqueLayerName(name.string());
  //2. 根据flags 创建不同类型的layer
      switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
          case ISurfaceComposerClient::eFXSurfaceBufferQueue:
          case ISurfaceComposerClient::eFXSurfaceBufferState: {
              result = createBufferStateLayer(client, std::move(uniqueName), w, h, flags,
                                              std::move(metadata), handle, &layer);
              std::atomic<int32_t>* pendingBufferCounter = layer->getPendingBufferCounter();
              if (pendingBufferCounter) {
                  std::string counterName = layer->getPendingBufferCounterName();
                  mBufferCountTracker.add((*handle)->localBinder(), counterName,
                                          pendingBufferCounter);
              }
          } break;
          case ISurfaceComposerClient::eFXSurfaceEffect:
              // check if buffer size is set for color layer.
              if (w > 0 || h > 0) {
                  ALOGE("createLayer() failed, w or h cannot be set for color layer (w=%d, h=%d)",
                        int(w), int(h));
                  return BAD_VALUE;
              }
  
              result = createEffectLayer(client, std::move(uniqueName), w, h, flags,
                                         std::move(metadata), handle, &layer);
              break;
          case ISurfaceComposerClient::eFXSurfaceContainer:
              // check if buffer size is set for container layer.
              if (w > 0 || h > 0) {
                  ALOGE("createLayer() failed, w or h cannot be set for container layer (w=%d, h=%d)",
                        int(w), int(h));
                  return BAD_VALUE;
              }
              result = createContainerLayer(client, std::move(uniqueName), w, h, flags,
                                            std::move(metadata), handle, &layer);
              break;
          default:
              result = BAD_VALUE;
              break;
      }
  
      if (result != NO_ERROR) {
          return result;
      }
  
      bool addToRoot = callingThreadHasUnscopedSurfaceFlingerAccess();
      //3.Layer创建后续工作
      result = addClientLayer(client, *handle, *gbp, layer, parentHandle, parentLayer, addToRoot,
                              outTransformHint);
      if (result != NO_ERROR) {
          return result;
      }
      mInterceptor->saveSurfaceCreation(layer);
  
      setTransactionFlags(eTransactionNeeded);
      *outLayerId = layer->sequence;
      return result;
  }

SurfaceFlinger::createLayer主要工作如注释。

Layer的类型:

  • BufferStateLayer:标准的Surface
  • EffectLayer:纯色或阴影的显示效果的Surface,Task就是EffectLayer
  • ContainerLayer:创建surface容器。此surface没有缓冲区,仅用作其他surfaces或InputInfo的容器。
arduino 复制代码
 status_t SurfaceFlinger::addClientLayer(const sp<Client>& client, const sp<IBinder>& handle,
                                          const sp<IGraphicBufferProducer>& gbc, const sp<Layer>& lbc,
                                          const sp<IBinder>& parentHandle,
                                          const sp<Layer>& parentLayer, bool addToRoot,
                                          uint32_t* outTransformHint) {
.. ...
      // Create a transaction includes the initial parent and producer.
      Vector<ComposerState> states;
      Vector<DisplayState> displays;
  
      ComposerState composerState;
      composerState.state.what = layer_state_t::eLayerCreated;
      composerState.state.surface = handle;
      states.add(composerState);
  
      lbc->updateTransformHint(mDefaultDisplayTransformHint);
      if (outTransformHint) {
          *outTransformHint = mDefaultDisplayTransformHint;
      }
      // attach this layer to the client
      client->attachLayer(handle, lbc);
  
      return setTransactionState(FrameTimelineInfo{}, states, displays, 0 /* flags */, nullptr,
                                 InputWindowCommands{}, -1 /* desiredPresentTime */,
                                 true /* isAutoTimestamp */, {}, false /* hasListenerCallbacks */, {},
                                 0 /* Undefined transactionId */);
  }

设置eLayerCreated flag, 将Layer添加到相应的client里,主要工作在setTransactionState里

c 复制代码
 status_t SurfaceFlinger::setTransactionState(
          const FrameTimelineInfo& frameTimelineInfo, const Vector<ComposerState>& states,
          const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,
          const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime,
          bool isAutoTimestamp, const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
          const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId) {
      ATRACE_CALL();
  
      ... ...
  
      IPCThreadState* ipc = IPCThreadState::self();
      const int originPid = ipc->getCallingPid();
      const int originUid = ipc->getCallingUid();
      TransactionState state{frameTimelineInfo,  states,
                             displays,           flags,
                             applyToken,         inputWindowCommands,
                             desiredPresentTime, isAutoTimestamp,
                             uncacheBuffer,      postTime,
                             permissions,        hasListenerCallbacks,
                             listenerCallbacks,  originPid,
                             originUid,          transactionId};
  
      // Check for incoming buffer updates and increment the pending buffer count.
      state.traverseStatesWithBuffers([&](const layer_state_t& state) {
          mBufferCountTracker.increment(state.surface->localBinder());
      });
      queueTransaction(state);//放入待合成队列 mTransactionQueue
  
      // Check the pending state to make sure the transaction is synchronous.
      //触发SF合成
      if (state.transactionCommittedSignal) {
          waitForSynchronousTransaction(*state.transactionCommittedSignal);
      }
  
      return NO_ERROR;
  }

SurfaceFlinger 合成Vsync 到来后会调用: SurfaceFlinger::flushTransactionQueues 遍历mTransactionQueue 调用applyTransactionState

-> setClientStateLocked

-> handleLayerCreatedLocked 设置layer 合成位置,如果有parent 则加入到parent中,否则按照z order加入到mCurrentState

scss 复制代码
  sp<Layer> SurfaceFlinger::handleLayerCreatedLocked(const sp<IBinder>& handle) {
 ... ...
      if (parent == nullptr && allowAddRoot) {
          layer->setIsAtRoot(true);
          mCurrentState.layersSortedByZ.add(layer);
      } else if (parent == nullptr) {
          layer->onRemovedFromCurrentState();
      } else if (parent->isRemovedFromCurrentState()) {
          parent->addChild(layer);
          layer->onRemovedFromCurrentState();
      } else {
          parent->addChild(layer);
      }
  
      layer->updateTransformHint(mDefaultDisplayTransformHint);
    ... ...
  
      return layer;
  }

3.2 Layer销毁

窗口销毁时会释放surface,首先调用到 SurfaceControl.release -> nativeRelease -> ~SurfaceControl(),我们就从native的SurfaceControl 类析构函数开始。

scss 复制代码
SurfaceControl::~SurfaceControl()
{
    // Trigger an IPC now, to make sure things
    // happen without delay, since these resources are quite heavy.
    mClient.clear();
    mHandle.clear();
    mGraphicBufferProducer.clear();
    IPCThreadState::self()->flushCommands();
}

mHandle的类型是sp<IBinder> ,在调用mHandle.clear(); 时只是引用计数减1,并不是马上释放。当mHandle可以被释放时,由于Binder生命周期的设计,当所有的代理对象(BpBinder)被销毁时,Binder 实体对象也会被销毁,此时会走到服务端Handle 的析构函数:

frameworks/native/services/surfaceflinger/Layer.h

kotlin 复制代码
 class Handle : public BBinder, public LayerCleaner {
   public:
       Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
             : LayerCleaner(flinger, layer), owner(layer) {}

       wp<Layer> owner;
   };

   class LayerCleaner {
       sp<SurfaceFlinger> mFlinger;
       sp<Layer> mLayer;

   protected:
       ~LayerCleaner() {
           // destroy client resources
           mFlinger->onHandleDestroyed(mLayer);
       }

   public:
       LayerCleaner(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
             : mFlinger(flinger), mLayer(layer) {}
   };

调用到 LayerCleaner析构,LayerCleaner析构调用SurfaceFlinger 的onHandleDestroyed

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

scss 复制代码
void SurfaceFlinger::onHandleDestroyed(sp<Layer>& layer){
   Mutex::Autolock lock(mStateLock);
   // If a layer has a parent, we allow it to out-live it's handle
   // with the idea that the parent holds a reference and will eventually
   // be cleaned up. However no one cleans up the top-level so we do so
   // here.
   if (layer->getParent() == nullptr) {
       mCurrentState.layersSortedByZ.remove(layer);
   }
   markLayerPendingRemovalLocked(layer);

   auto it = mLayersByLocalBinderToken.begin();
   while (it != mLayersByLocalBinderToken.end()) {
       if (it->second == layer) {
           it = mLayersByLocalBinderToken.erase(it);
       } else {
           it++;
       }
   }

   layer.clear();
}

这里注意,如果layer 还被parent引用,就暂时不释放,等parent也被释放时,当前layer 才会被释放,所以在Activity中使用SurfaceView 的场景,要尤其注意SurfaceView 的生命周期和其所在的Activity 的surface 生命周期是否一致, 否则有可能造成layer 泄漏,直到Activity stop 流程后才会释放SurfaceView layer. Activity 的surface 要在 stoped 流程才会被释放 ,调用堆栈如下:

php 复制代码
05-23 18:19:40.611   798  1303 E lzh100  : lzh100 release Surface(name=com.autonavi.amapauto/com.autonavi.amapauto.MainMapActivity)/@0x25e983f
05-23 18:19:40.611   798  1303 E lzh100  : java.lang.RuntimeException
05-23 18:19:40.611   798  1303 E lzh100  :         at android.view.SurfaceControl.release(SurfaceControl.java:1141)
05-23 18:19:40.611   798  1303 E lzh100  :         at android.view.SurfaceControl$Transaction.remove(SurfaceControl.java:3126)
05-23 18:19:40.611   798  1303 E lzh100  :         at com.android.server.wm.WindowSurfaceController.destroyNotInTransaction(WindowSurfaceController.java:185)
05-23 18:19:40.611   798  1303 E lzh100  :         at com.android.server.wm.WindowStateAnimator.destroySurface(WindowStateAnimator.java:1562)
05-23 18:19:40.611   798  1303 E lzh100  :         at com.android.server.wm.WindowStateAnimator.destroySurfaceLocked(WindowStateAnimator.java:633)
05-23 18:19:40.611   798  1303 E lzh100  :         at com.android.server.wm.WindowState.destroySurfaceUnchecked(WindowState.java:3293)
05-23 18:19:40.611   798  1303 E lzh100  :         at com.android.server.wm.WindowState.destroySurface(WindowState.java:3267)
05-23 18:19:40.611   798  1303 E lzh100  :         at com.android.server.wm.ActivityRecord.destroySurfaces(ActivityRecord.java:4557)
05-23 18:19:40.611   798  1303 E lzh100  :         at com.android.server.wm.ActivityRecord.destroySurfaces(ActivityRecord.java:4538)
05-23 18:19:40.611   798  1303 E lzh100  :         at com.android.server.wm.ActivityRecord.notifyAppStopped(ActivityRecord.java:4591)
05-23 18:19:40.611   798  1303 E lzh100  :         at com.android.server.wm.ActivityRecord.activityStopped(ActivityRecord.java:5170)
05-23 18:19:40.611   798  1303 E lzh100  :         at com.android.server.wm.ActivityTaskManagerService.activityStopped(ActivityTaskManagerService.java:2355)
05-23 18:19:40.611   798  1303 E lzh100  :         at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:2052)
05-23 18:19:40.611   798  1303 E lzh100  :         at android.os.Binder.execTransactInternal(Binder.java:1159)
05-23 18:19:40.611   798  1303 E lzh100  :         at android.os.Binder.execTransact(Binder.java:1123)

最后调用到各个子类的析构,如

scss 复制代码
BufferQueueLayer::~BufferQueueLayer() {
   mContentsChangedListener->abandon();
   mConsumer->abandon();
}

至此Layer对象被彻底销毁。

相关推荐
阿巴斯甜20 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker20 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq952721 小时前
Andorid Google 登录接入文档
android
黄林晴1 天前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab1 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿2 天前
Android MediaPlayer 笔记
android
Jony_2 天前
Android 启动优化方案
android
阿巴斯甜2 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇2 天前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_2 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android