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对象被彻底销毁。

相关推荐
米豆同学4 小时前
SufraceFlinger图像合成原理(2)-SurfaceFlinger与应用进程间的通信
android
用户2018792831674 小时前
uses-library:系统应用报NoClassDefFoundError问题
android
叽哥4 小时前
Kotlin学习第 4 课:Kotlin 函数:从基础定义到高阶应用
android·java·kotlin
mg6684 小时前
安卓玩机工具----安卓“搞机工具箱”最新版 控制手机的玩机工具
android·智能手机
诺诺Okami4 小时前
Android Framework- Activity启动2
android
米豆同学4 小时前
SystemUI plugin 开发
android
lichong9515 小时前
【混合开发】vue+Android、iPhone、鸿蒙、win、macOS、Linux之video 的各种状态和生命周期调用说明
android·vue.js·macos
app出海创收老李6 小时前
海外独立创收日记(1)-我是如何从0到1在Google Play获得睡后被动收入的?
android·程序员
lang9998886 小时前
kodi在Android4.0.4安装播放歌曲显示歌词
android·kodi·歌词插件