背景:
有学员在vip群里反馈一个SurfaceFlinger相关的报错
群里讨论也非常激烈。
问题如下:
sf的报错信息大概可以看出这个是创建的Layer数量已经大于4096个,sf端有保护机制,为了让内存不会永久持续增大,只能报错异常,不然在创建新的。
对应的代码如下:
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
那么出现这种问题一般是什么原因呢?正常的系统要展示窗口时候创建layer,不展示时候肯定就会销毁layer,这样layer肯定不会只增不减,所以4096在长期经验来说已经足够大了,一旦会超过4096这个数量,那一般就是有泄露。
那么这种问题如何排查呢?这个相关优秀学员也回答很详细,在这里给大家做一个记录,方便大家以后遇到同样问题可以参考这篇文章。
【Android 13】SurfaceFlinger - Layer的创建与销毁
SurfaceControl的创建
SurfaceControl的创建流程(app端创建SurfaceControl,sf端创建Layer)
Java层
ViewRootImpl创建SurfaceSession和SurfaceControl
ViewRootImpl的SurfaceSession在初始化的时候就构造完成:
代码位于:frameworks/base/core/java/android/view/ViewRootImpl.java
private final SurfaceSession mSurfaceSession = new SurfaceSession();
代码位于:frameworks/base/core/java/android/view/SurfaceSession.java
public SurfaceSession() {
mNativeClient = nativeCreate();
}
ViewRootImpl通过setView()可以通过Session在system_server端构建一个WindowToken和WindowState。WindowToken和WindowState这类窗口容器的SurfaceControl在1.1.2中提到创建过程。
ViewRootImpl在初始化的时候,就构造了一个空的SurfaceControl:
代码位于frameworks/base/core/java/android/view/ViewRootImpl.java
private final SurfaceControl mSurfaceControl = new SurfaceControl();
在ViewRootImpl需要绘制的时候,通过session.relayout()会在system_server端为这个ViewRootImpl创建一个SurfaceControl,挂到WindowState下面去:
代码位于frameworks/base/core/java/android/view/ViewRootImpl.java
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
boolean insetsPending) throws RemoteException {
//...
relayoutResult = mWindowSession.relayout(mWindow, params,
requestedWidth, requestedHeight, viewVisibility,
insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
mTmpFrames, mPendingMergedConfiguration, mSurfaceControl /* 注意到这里把SurfaceControl作参数传入 */, mTempInsets,
mTempControls, mRelayoutBundle);
}
来到WMS,在relayout的过程中会为其构建真正的SurfaceControl (implements Parcelable),并将创建好的SurfaceControl回传给应用端的ViewRootImpl:
代码位于frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public int relayoutWindow(Session session, IWindow client, LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewVisibility, int flags,
ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
SurfaceControl outSurfaceControl, InsetsState outInsetsState,
InsetsSourceControl[] outActiveControls, Bundle outSyncIdBundle) {
// ...
// Create surfaceControl before surface placement otherwise layout will be skipped
// (because WS.isGoneForLayout() is true when there is no surface.
if (shouldRelayout) {
try {
result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
} catch (Exception e) {
displayContent.getInputMonitor().updateInputWindowsLw(true /*force*/);
Binder.restoreCallingIdentity(origId);
return 0;
}
}
}
private int createSurfaceControl(SurfaceControl outSurfaceControl, int result,
WindowState win, WindowStateAnimator winAnimator) {
WindowSurfaceController surfaceController;
// 在system_server端为ViewRootImpl构建一个SurfaceControl
// winAnimator是WindowState的一个成员变量,这个WindowState是ViewRootImpl在system_server侧的挂载父亲
surfaceController = winAnimator.createSurfaceLocked();
if (surfaceController != null) {
// 将创建好的SurfaceControl回传给ViewRootImpl
surfaceController.getSurfaceControl(outSurfaceControl);
} else {
ProtoLog.w(WM_ERROR, "Failed to create surface control for %s", win);
outSurfaceControl.release();
}
return result;
}
WindowStateAnimator中会构建一个mSurfaceController,其中维护了mSurfaceControl:
代码位于frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java
WindowSurfaceController createSurfaceLocked() {
final WindowState w = mWin;
if (mSurfaceController != null) {
return mSurfaceController;
}
// ...
mSurfaceController = new WindowSurfaceController(attrs.getTitle().toString(), format,
flags, this, attrs.type);
// ...
return mSurfaceController;
}
实例化WindowSurfaceController的时候,构造了mSurfaceControl,可以通过其getSurfaceControl()方法,将其拷贝出去:
- 需要注意的是,这里为ViewRootImpl创建的SurfaceControl的父亲,就是其需要挂载的WindowState的SurfaceControl
代码位于frameworks/base/services/core/java/com/android/server/wm/WindowSurfaceController.java
WindowSurfaceController(String name, int format, int flags, WindowStateAnimator animator,
int windowType) {
mAnimator = animator;
title = name;
mService = animator.mService;
final WindowState win = animator.mWin;
mWindowType = windowType;
mWindowSession = win.mSession;
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
final SurfaceControl.Builder b = win.makeSurface()
.setParent(win.getSurfaceControl()) /* 需要注意的是,ViewRootImpl创建的SurfaceControl挂载的父亲就是WindowState */
.setName(name)
.setFormat(format)
.setFlags(flags)
.setMetadata(METADATA_WINDOW_TYPE, windowType)
.setMetadata(METADATA_OWNER_UID, mWindowSession.mUid)
.setMetadata(METADATA_OWNER_PID, mWindowSession.mPid)
.setCallsite("WindowSurfaceController");
final boolean useBLAST = mService.mUseBLAST && ((win.getAttrs().privateFlags
& WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST) != 0);
if (useBLAST) {
b.setBLASTLayer();
}
mSurfaceControl = b.build();
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
WindowContainer创建SurfaceSession和SurfaceControl
WindowContainer的SurfaceSession在DisplayContent初始化的时候就构造完成,其孩子使用session时,可以从父亲这里取得Session:
代码位于:frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
private final SurfaceSession mSession = new SurfaceSession();
当WindowContainer挂载到窗口结构树上时,会为其初始化一个SurfaceControl与该窗口容器一一对应:
代码位于frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java
void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent,
PreAssignChildLayersCallback callback) {
//...
if (mSurfaceControl == null) {
createSurfaceControl(false /*force*/);
} else {
reparentSurfaceControl(getSyncTransaction(), mParent.mSurfaceControl);
}
}
使用SurfaceControl.Builder进行构造:
代码位于frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java
void createSurfaceControl(boolean force) {
setInitialSurfaceControlProperties(makeSurface());
}
SurfaceControl.Builder makeSurface() {
final WindowContainer p = getParent();
return p.makeChildSurface(this);
}
void setInitialSurfaceControlProperties(SurfaceControl.Builder b) {
setSurfaceControl(b.setCallsite("WindowContainer.setInitialSurfaceControlProperties").build());
if (showSurfaceOnCreation()) {
getSyncTransaction().show(mSurfaceControl);
}
onSurfaceShown(getSyncTransaction());
updateSurfacePositionNonOrganized();
}
如果窗口容器是Task.java,还会为SurfaceControl打上EffectLayer标签
代码位于frameworks/base/services/core/java/com/android/server/wm/Task.java
@Override
void setInitialSurfaceControlProperties(SurfaceControl.Builder b) {
b.setEffectLayer().setMetadata(METADATA_TASK_ID, mTaskId);
super.setInitialSurfaceControlProperties(b);
}
jni的发起
最终都会通过SurfaceController.Build()的方式,进行SurfaceControl的构造。SurfaceControl.java只是一个壳,真正的对象在native层:
代码位于frameworks/base/core/java/android/view/SurfaceControl.java
private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,
SurfaceControl parent, SparseIntArray metadata, WeakReference<View> localOwnerView,
String callsite) throws OutOfResourcesException, IllegalArgumentException {
if (name == null) {
throw new IllegalArgumentException("name must not be null");
}
mName = name;
mWidth = w;
mHeight = h;
mLocalOwnerView = localOwnerView;
Parcel metaParcel = Parcel.obtain();
try {
if (metadata != null && metadata.size() > 0) {
metaParcel.writeInt(metadata.size());
for (int i = 0; i < metadata.size(); ++i) {
metaParcel.writeInt(metadata.keyAt(i));
metaParcel.writeByteArray(
ByteBuffer.allocate(4).order(ByteOrder.nativeOrder())
.putInt(metadata.valueAt(i)).array());
}
metaParcel.setDataPosition(0);
}
// 发起构建
mNativeObject = nativeCreate(session, name, w, h, format, flags,
parent != null ? parent.mNativeObject : 0, metaParcel);
} finally {
metaParcel.recycle();
}
if (mNativeObject == 0) {
throw new OutOfResourcesException(
"Couldn't allocate SurfaceControl native object");
}
mNativeHandle = nativeGetHandle(mNativeObject);
mCloseGuard.openWithCallSite("release", callsite);
}
private static native long nativeCreate(SurfaceSession session, String name,
int w, int h, int format, int flags, long parentObject, Parcel metadata)
throws OutOfResourcesException;
native层
代码位于:frameworks/base/core/jni/android_view_SurfaceControl.cpp
-
获取一个SurfaceComposerClient的引用
- 这是客户端对象,将用于和SurfaceFlinger服务端通信
-
sp parentHandle 指向传入的需要挂载的SurfaceControl父亲
- 在native层,通过handle来指向SurfaceControl,在SurfaceFlinger端,handle->owner指向Layer
-
通过SurfaceComposerClient创建SurfaceControl,同时将向sf发起构建Layer的请求
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;
if (sessionObj != NULL) {
client = android_view_SurfaceSession_getClient(env, sessionObj);
} else {
client = SurfaceComposerClient::getDefault();
}
SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject);
sp<SurfaceControl> surface;
LayerMetadata metadata;
Parcel* parcel = parcelForJavaObject(env, metadataParcel);
if (parcel && !parcel->objectsCount()) {
status_t err = metadata.readFromParcel(parcel);
if (err != NO_ERROR) {
jniThrowException(env, "java/lang/IllegalArgumentException",
"Metadata parcel has wrong format");
}
}
sp<IBinder> parentHandle;
if (parent != nullptr) {
parentHandle = parent->getHandle();
}
status_t err = client->createSurfaceChecked(String8(name.c_str()), w, h, format, &surface,
flags, parentHandle, std::move(metadata));
if (err == NAME_NOT_FOUND) {
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
return 0;
} else if (err != NO_ERROR) {
jniThrowException(env, OutOfResourcesException, NULL);
return 0;
}
surface->incStrong((void *)nativeCreate);
return reinterpret_cast<jlong>(surface.get());
}
SurfaceComposerClient发起Layer(surfaceflinger服务端)和SurfaceControl(client端)构建:
- 可以看到SurfaceControl对象也是存在于客户端的,其中维护了handle,这可以用来指向sf端的Layer
- 这里的mClient则是位于sf端的Client.cpp对象的BpBinder,它的构建在下一小节解释
代码位于:frameworks/native/libs/gui/SurfaceComposerClient.cpp
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;
}
实例化SurfaceControl
将sf端构造好的Layer的句柄handle (BpBinder)进行维护,以便后续deconstructor()调用时,可以远程调用进行资源释放
代码位于:frameworks/native/libs/gui/SurfaceControl.cpp
SurfaceControl::SurfaceControl(const sp<SurfaceComposerClient>& client, const sp<IBinder>& handle,
const sp<IGraphicBufferProducer>& gbp, int32_t layerId,
uint32_t w, uint32_t h, PixelFormat format, uint32_t transform,
uint32_t flags)
: mClient(client),
mHandle(handle),
mGraphicBufferProducer(gbp),
mLayerId(layerId),
mTransformHint(transform),
mWidth(w),
mHeight(h),
mFormat(format),
mCreateFlags(flags) {}
SurfaceComposerClient与SurfaceFlinger建联
SurfaceComposerClient获取SurfaceFlinger服务远程代理对象
当SurfaceComposerClient首次构建的时候,会尝试与SurfaceFlinger进程建立联系:
代码位于:frameworks/native/libs/gui/SurfaceComposerClient.cpp
代码位于:frameworks/native/libs/gui/SurfaceComposerClient.cpp
void SurfaceComposerClient::onFirstRef() {
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
if (sf != nullptr && mStatus == NO_INIT) {
sp<ISurfaceComposerClient> conn;
conn = sf->createConnection();
if (conn != nullptr) {
mClient = conn;
mStatus = NO_ERROR;
}
}
}
这里会获取一个sf对象,这是sf服务在客户端的BpBinder,通过ComposerService::getComposerService()获取:
代码位于:frameworks/native/libs/gui/SurfaceComposerClient.cpp
/*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() {
// ComposerService继承了Singleton这是个单例
ComposerService& instance = ComposerService::getInstance();
Mutex::Autolock _l(instance.mLock);
if (instance.mComposerService == nullptr) {
if (ComposerService::getInstance().connectLocked()) {
ALOGD("ComposerService reconnected");
WindowInfosListenerReporter::getInstance()->reconnect(instance.mComposerService);
}
}
return instance.mComposerService;
}
在构造ComposerService的时候,通过ServiceManager获取SurfaceFlinger服务的BpBinder
代码位于:frameworks/native/libs/gui/SurfaceComposerClient.cpp
ComposerService::ComposerService()
: Singleton<ComposerService>() {
Mutex::Autolock _l(mLock);
connectLocked();
}
bool ComposerService::connectLocked() {
const String16 name("SurfaceFlinger");
mComposerService = waitForService<ISurfaceComposer>(name);
if (mComposerService == nullptr) {
return false; // fatal error or permission problem
}
// 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);
return true;
}
SurfaceComposerClient通过sf的BpBinder远程调用,创建Client的BpBinder,用于后续通信
回到SurfaceComposerClient构建的时机,获取到sf的BpBinder后,调用了其createConnection()方法,这会在SurfaceFlinger服务端构建一个Client.cpp的实体对象,它的BpBinder交给客户端,后续SurfaceComposerClient向sf服务发起请求,都通过client的BpBinder,而不总通过SurfaceFlinger的BpBinder
代码位于:frameworks/native/libs/gui/SurfaceComposerClient.cpp
void SurfaceComposerClient::onFirstRef() {
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
if (sf != nullptr && mStatus == NO_INIT) {
sp<ISurfaceComposerClient> conn;
conn = sf->createConnection();
if (conn != nullptr) {
// 获取到Client的BpBinder
mClient = conn;
mStatus = NO_ERROR;
}
}
}
来到surfaceflinger进程,SurfaceFlinger.cpp响应createConnection()远程调用,构造一个Client,并将其BpBinder交给客户端:
代码位于:frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
const sp<Client> client = new Client(this);
return client->initCheck() == NO_ERROR ? client : nullptr;
}
SurfaceComposerClient通过Client发起Layer创建
SurfaceControl与Layer的对应关系:
回到SurfaceComposerClient创建SurfaceControl,在客户端创建SurfaceControl之前,会通过Client的BpBinder在sf端建立Layer,并将其引用句柄handle回传,由即将创建的SurfaceControl维护:
代码位于:frameworks/native/libs/gui/SurfaceComposerClient.cpp
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) {
// ...
if (mStatus == NO_ERROR) {
sp<IBinder> handle;
err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),
&handle, &gbp, &id, &transformHint);
if (err == NO_ERROR) {
*outSurface =
new SurfaceControl(this, handle, gbp, id, w, h, format, transformHint, flags);
}
}
return err;
}
来到surfaceflinger进程,Client.cpp响应该远程调用:
代码位于:frameworks/native/services/surfaceflinger/Client.cpp
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>* outHandle, sp<IGraphicBufferProducer>* /* gbp */,
int32_t* outLayerId, uint32_t* outTransformHint) {
// We rely on createLayer to check permissions.
LayerCreationArgs args(mFlinger.get(), this, name.c_str(), flags, std::move(metadata));
return mFlinger->createLayer(args, outHandle, parentHandle, outLayerId, nullptr,
outTransformHint);
}
转发给SurfaceFlinger.cpp来进行Layer的创建:
- 根据不同的Layer类型进行创建,类型有:EffectLayer(例如Task的Layer),ContainerLayer(例如ActivityRecord的Layer), BufferStateLayer(有实在内容的Layer)
- 将构建好的Layer进行记录,addClientLayer()
- 为Layer带上sequence,这是递增的数值,用来维护其唯一性
代码位于:frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
status_t SurfaceFlinger::createLayer(LayerCreationArgs& args, sp<IBinder>* outHandle,
const sp<IBinder>& parentHandle, int32_t* outLayerId,
const sp<Layer>& parentLayer, uint32_t* outTransformHint) {
status_t result = NO_ERROR;
sp<Layer> layer;
switch (args.flags & ISurfaceComposerClient::eFXSurfaceMask) {
case ISurfaceComposerClient::eFXSurfaceBufferQueue:
case ISurfaceComposerClient::eFXSurfaceBufferState: {
result = createBufferStateLayer(args, outHandle, &layer);
} break;
case ISurfaceComposerClient::eFXSurfaceEffect:
result = createEffectLayer(args, outHandle, &layer);
break;
case ISurfaceComposerClient::eFXSurfaceContainer:
result = createContainerLayer(args, outHandle, &layer);
break;
default:
result = BAD_VALUE;
break;
}
//...
result = addClientLayer(args.client, *outHandle, layer, parent, addToRoot, outTransformHint);
*outLayerId = layer->sequence;
return result;
}
重点关注1: 构造Layer的时候,会同时构建一个指向该Layer的Handle, 以createEffectLayer为例:
代码位于frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
status_t SurfaceFlinger::createEffectLayer(const LayerCreationArgs& args, sp<IBinder>* handle,
sp<Layer>* outLayer) {
*outLayer = getFactory().createEffectLayer(args);
*handle = (*outLayer)->getHandle();
return NO_ERROR;
}
代码位于:frameworks/native/services/surfaceflinger/Layer.cpp
sp<IBinder> Layer::getHandle() {
Mutex::Autolock _l(mLock);
if (mGetHandleCalled) {
ALOGE("Get handle called twice" );
return nullptr;
}
mGetHandleCalled = true;
return new Handle(mFlinger, this);
}
重点关注到Handle:
- 作为Layer的句柄,是BBinder类型,在sf端,可以通过owner找到对应的Layer,在客户端可以通过handle远程对应到Layer
- 可以控制Layer的销毁,当Layer被销毁的时候,句柄也会销毁,会走到mFlinger->onHandleDestroyed(),从相关集合中移除,如mOffscreenLayers集合
/*
* Trivial class, used to ensure that mFlinger->onLayerDestroyed(mLayer)
* is called.
*/
class LayerCleaner {
sp<SurfaceFlinger> mFlinger;
sp<Layer> mLayer;
BBinder* mHandle;
protected:
~LayerCleaner() {
// destroy client resources
mFlinger->onHandleDestroyed(mHandle, mLayer);
}
public:
LayerCleaner(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer, BBinder* handle)
: mFlinger(flinger), mLayer(layer), mHandle(handle) {}
};
/*
* The layer handle is just a BBinder object passed to the client
* (remote process) -- we don't keep any reference on our side such that
* the dtor is called when the remote side let go of its reference.
*
* LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
* this layer when the handle is destroyed.
*/
class Handle : public BBinder, public LayerCleaner {
public:
Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
: LayerCleaner(flinger, layer, this), owner(layer) {}
const String16& getInterfaceDescriptor() const override { return kDescriptor; }
static const String16 kDescriptor;
wp<Layer> owner;
};
**重点关注2:**addClientLayer(),将创建好的Layer进行添加:
- 记录到mCreatedLayers集合中
- 将其与Client绑定
代码位于:frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
status_t SurfaceFlinger::addClientLayer(const sp<Client>& client, const sp<IBinder>& handle,
const sp<Layer>& layer, const wp<Layer>& parent,
bool addToRoot, uint32_t* outTransformHint) {
if (mNumLayers >= ISurfaceComposer::MAX_LAYERS /* 4096 */) {
// 报错
return NO_MEMORY;
}
{
std::scoped_lock<std::mutex> lock(mCreatedLayersLock);
mCreatedLayers.emplace_back(layer, parent, addToRoot);
}
// attach this layer to the client
if (client != nullptr) {
client->attachLayer(handle, layer);
}
}
Client.cpp中维护Layer
- 关系是, 一个SurfaceComposerClient持有一个Client的BpBinder,一个Client下可能维护有多个Layer,场景是 client->mirrorSurface() \ 再次client->createSurface()
SurfaceControl的销毁与Layer的释放
SurfaceControl的销毁
java层销毁SurfaceControl
java层,通过SurfaceControl.Transaction的remove()方法,可以进行SurfaceControl的销毁:
- reparent到父亲为null
- release释放引用关系
这使得Layer成为游离态,将会在sf端的mOffscreenLayers集合中存在,并在Layer所有引用消失的时候,调用析构函数,从mOffscreenLayers中移除,真正销毁Layer。
代码位于:frameworks/base/core/java/android/view/SurfaceControl.java
// SurfaceControl.Transaction
public Transaction remove(@NonNull SurfaceControl sc) {
reparent(sc, null);
sc.release();
return this;
}
public Transaction reparent(@NonNull SurfaceControl sc,
@Nullable SurfaceControl newParent) {
checkPreconditions(sc);
long otherObject = 0;
if (newParent != null) {
newParent.checkNotReleased();
otherObject = newParent.mNativeObject;
}
nativeReparent(mNativeObject, sc.mNativeObject, otherObject);
mReparentedSurfaces.put(sc, newParent);
return this;
}
// SurfaceControl
public void release() {
if(LOG_SURFACE_CONTROL) {
Log.d(TAG, "release, mNativeObject:" + mNativeObject, new Throwable());
}
if (mNativeObject != 0) {
nativeRelease(mNativeObject);
mNativeObject = 0;
mNativeHandle = 0;
mCloseGuard.close();
}
}
native层销毁SurfaceControl
SurfaceControl.cpp继承于RefBase.cpp,它的析构函数会在强引用关系消失的时候调用
代码位于:frameworks/base/core/jni/android_view_SurfaceControl.cpp
static void nativeRelease(JNIEnv* env, jclass clazz, jlong nativeObject) {
sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(nativeObject));
// 强引用数 -1
ctrl->decStrong((void *)nativeCreate);
}
当其强引用关系消失的时候,调用deconstructor:
代码位于:system/core/libutils/RefBase.cpp
void RefBase::decStrong(const void* id) const
{
weakref_impl* const refs = mRefs;
refs->removeStrongRef(id);
const int32_t c = refs->mStrong.fetch_sub(1, std::memory_order_release);
LOG_ALWAYS_FATAL_IF(BAD_STRONG(c), "decStrong() called on %p too many times",
refs);
if (c == 1) {
std::atomic_thread_fence(std::memory_order_acquire);
refs->mBase->onLastStrongRef(id);
int32_t flags = refs->mFlags.load(std::memory_order_relaxed);
if ((flags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
delete this;
// The destructor does not delete refs in this case.
}
}
refs->decWeak(id);
}
Layer的销毁
Layer也继承自RefBase.cpp当其引用关系清空时,将会触发析构函数,进行Layer的销毁释放。Layer被handle持有,在SurfaceControl.cpp对象释放的时候,将会触发handle的释放:
SurfaceControl的析构
代码位于:frameworks/native/libs/gui/SurfaceControl.cpp
SurfaceControl::~SurfaceControl()
{
// Trigger an IPC now, to make sure things
// happen without delay, since these resources are quite heavy.
mClient.clear();
mHandle.clear();
mBbq.clear();
IPCThreadState::self()->flushCommands();
}
这里将Handle的引用进行了释放,来到sf端:
Handle触发析构,继承自LayerCleaner:
代码位于:frameworks/native/services/surfaceflinger/Layer.h
class LayerCleaner {
sp<SurfaceFlinger> mFlinger;
sp<Layer> mLayer;
BBinder* mHandle;
protected:
~LayerCleaner() {
// destroy client resources
mFlinger->onHandleDestroyed(mHandle, mLayer);
}
Layer引用清空
来到SurfaceFlinger.cpp,进行Handle销毁的回调,将Layer进行引用清空:
代码位于:frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::onHandleDestroyed(BBinder* handle, sp<Layer>& layer) {
Mutex::Autolock lock(mStateLock);
markLayerPendingRemovalLocked(layer);
mBufferCountTracker.remove(handle);
layer.clear();
if (mTransactionTracing) {
mTransactionTracing->onHandleRemoved(handle);
}
}
Layer引用清空后,Layer触发析构:
Layer::~Layer() {
sp<Client> c(mClientRef.promote());
if (c != 0) {
c->detachLayer(this);
}
mFlinger->onLayerDestroyed(this);
if (mHadClonedChild) {
mFlinger->mNumClones--;
}
}
在SurfaceFlinger.cpp中清空该Layer的记录:
- 从mOffscreenLayers集合中移除
- mNumLayers总Layer数记录-1
void SurfaceFlinger::onLayerDestroyed(Layer* layer) {
mNumLayers--;
removeHierarchyFromOffscreenLayers(layer);
if (!layer->isRemovedFromCurrentState()) {
mScheduler->deregisterLayer(layer);
}
if (mTransactionTracing) {
mTransactionTracing->onLayerRemoved(layer->getSequence());
}
}
至此完成Layer的销毁,和资源的释放。
TODO:
多个SurfaceControl(nativeCopy) 都指向一个Layer,只有所有SurfaceControl都销毁,才会将Layer的引用清空,触发析构。跟踪该流程。
实际案例
BugFix:
问题原因:进入过分屏的Task,其Layer都无法触发析构,当mOffscreenLayers数量过高,总Layer数超过4096后将会创建SurfaceControl失败。
跟踪发现,SystemUI会通过nativeCopy构造一个SurfaceControl,其中的handle就指向Task的Layer。
进入分屏后,该SurfaceControl会被StageTaskListener中的StageTaskUnfoldController持有,当该Task销毁vanished()时,StageTaskUnfoldController并没有将其引用释放。发生内存泄漏:
代码位置:frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskUnfoldController.java
public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
// 这里条件不符合,直接return,导致没有触发后续的remove
if (!taskInfo.hasParentTask()) return;
AnimationContext context = mAnimationContextByTaskId.get(taskInfo.taskId);
if (context != null) {
final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
resetSurface(transaction, context);
transaction.apply();
mTransactionPool.release(transaction);
}
mAnimationContextByTaskId.remove(taskInfo.taskId);
}
解决:
- 方案1:取消折叠屏特性,不触发StageTaskUnfoldController的onTaskAppeared和onTaskVanished
- 方案2: 调整逻辑,使得remove逻辑正常
方案3: ShellTaskOrganizer中收到onTaskVanished最后,主动对SurfaceControl调用release()
更多framework实战干货,请关注下面“千里马学框架”