前面View绘制原理中Vsync流程基本上已经分析完毕。前文分析了performTraversals的四个重要流程,第一步就是relayoutWindow,它的作用之一就是为界面生成Surface。本文将详细介绍这个relayoutWindow关于生成Surface的部分原理。
1. SurfaceControl.
这是一个稍微有一点难理解的类,而且的创建过程也非常晦涩。我们来看一下它的原理
首先在ViewRootImpl初始化的时候,就会调用SurfaceControl和Surface的构造函数生成它们的实例
frameworks/base/core/java/android/view/ViewRootImpl.java
public final Surface mSurface = new Surface();
private final SurfaceControl mSurfaceControl = new SurfaceControl();
frameworks/base/core/java/android/view/SurfaceControl.java
public SurfaceControl() {
}
frameworks/base/core/java/android/view/Surface.java
public Surface() {
}
这个里虽然生成了Surface和SurfaceControl对象,但是因为它没有生成底层的对应的对象,所以是无效的,还不能用于绘制
2. ViewRootImpl.relayoutWindow.
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility, boolean insetsPending) throws RemoteException {
...
int relayoutResult = mWindowSession.relayout(mWindow, params,
(int) (mView.getMeasuredWidth() * appScale + 0.5f),
(int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility,
insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber,
mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
mTempControls, mSurfaceSize);
mPendingBackDropFrame.set(mTmpFrames.backdropFrame);
if (mSurfaceControl.isValid()) {
if (!useBLAST()) {
mSurface.copyFrom(mSurfaceControl);
} else {
final Surface blastSurface = getOrCreateBLASTSurface();
// If blastSurface == null that means it hasn't changed since the last time we
// called. In this situation, avoid calling transferFrom as we would then
// inc the generation ID and cause EGL resources to be recreated.
if (blastSurface != null) {
mSurface.transferFrom(blastSurface);
}
}
if (mAttachInfo.mThreadedRenderer != null) {
if (HardwareRenderer.isWebViewOverlaysEnabled()) {
addPrepareSurfaceControlForWebviewCallback();
addASurfaceTransactionCallback();
}
mAttachInfo.mThreadedRenderer.setSurfaceControl(mSurfaceControl);
}
} else {
destroySurface();
}
...
}
这个方法内部,调用了mWindowSession.relayoutWindow方法,并且传入了mSurfaceControl, 这是一个IPC方法,因为SurfaceControl也实现了Parcelable接口,所以可以跨进程传递。当方法返回来之后,接着判断mSurfaceControl.isValid()
public boolean isValid() {
return mNativeObject != 0;
}
就是看看mNativeObject是否为0, 初始化时时空函数,因此肯定为0, 如果此时不为零,它就是在mWindowSession.relayout内赋值了。因此我们来看看mWindowSeesion.relayout作了什么操作。
3 APP与WMS通信
ViewRootImpl有一个mWindowSeesion成员,是构造ViewRootImpl的时候通过调用WindowManagerGlobal.getWindowSession获取的
public ViewRootImpl(Context context, Display display) {
this(context, display, WindowManagerGlobal.getWindowSession(),
false /* useSfChoreographer */);
}
public ViewRootImpl(@UiContext Context context, Display display, IWindowSession session,
boolean useSfChoreographer) {
mContext = context;
mWindowSession = session;
...
}
@UnsupportedAppUsage
public static IWindowSession getWindowSession() {
...
IWindowManager windowManager = getWindowManagerService();
sWindowSession = windowManager.openSession(
new IWindowSessionCallback.Stub() {
@Override
public void onAnimatorScaleChanged(float scale) {
ValueAnimator.setDurationScale(scale);
}
});
return sWindowSession;
}
}
于是IPC呼叫到到WindowManagerService.openSession方法
frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
@Override
public IWindowSession openSession(IWindowSessionCallback callback) {
return new Session(this, callback);
}
返回一个Session对象,它继承自IWindowSession.Stub ,所以是工作在服务端的实际干活的对象,传送到客户端后,客户端可以获取到句柄并转换成IWindowSession接口,然后远程呼叫这个Session的addToDisplay和relayout等方法, 这些方法内部,会调用WMS的相对应的方法,
frameworks/base/services/core/java/com/android/server/wm/Session.java
class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
@Override
public int relayout(IWindow window, WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewFlags, int flags, long frameNumber,
ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
SurfaceControl outSurfaceControl, InsetsState outInsetsState,
InsetsSourceControl[] outActiveControls, Point outSurfaceSize) {
...
int res = mService.relayoutWindow(this, window, attrs,
requestedWidth, requestedHeight, viewFlags, flags, frameNumber,
outFrames, mergedConfiguration, outSurfaceControl, outInsetsState,
outActiveControls, outSurfaceSize);
....
return res;
}
...
}
4. WindowManagerService
WindnowManagerServicec初始化的时候会和SurfaceFlinger服务建立会话,这样后面就可以直接调用SurfaceFlinger的方法。
frameworks/base/core/java/android/view/ViewRootImpl.java
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,
int userId) {
...
res = mWindowSession.addToDisplayAsUser(mWindow, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(), userId,
mInsetsController.getRequestedVisibility(), inputChannel, mTempInsets,
mTempControls);
...
}
这是上面介绍过的App与WMS的远程调用
frameworks/base/services/core/java/com/android/server/wm/Session.java
@Override
public int addToDisplay(IWindow window, WindowManager.LayoutParams attrs,
int viewVisibility, int displayId, InsetsState requestedVisibility,
InputChannel outInputChannel, InsetsState outInsetsState,
InsetsSourceControl[] outActiveControls) {
return mService.addWindow(this, window, attrs, viewVisibility, displayId,
UserHandle.getUserId(mUid), requestedVisibility, outInputChannel, outInsetsState,
outActiveControls);
}
frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public int addWindow(Session session, IWindow client, LayoutParams attrs, int viewVisibility,
int displayId, int requestUserId, InsetsState requestedVisibility,
InputChannel outInputChannel, InsetsState outInsetsState,
InsetsSourceControl[] outActiveControls) {
...
final DisplayContent displayContent = getDisplayContentOrCreate(displayId, attrs.token);
...
}
private DisplayContent getDisplayContentOrCreate(int displayId, IBinder token) {
if (token != null) {
final WindowToken wToken = mRoot.getWindowToken(token);
if (wToken != null) {
return wToken.getDisplayContent();
}
}
return mRoot.getDisplayContentOrCreate(displayId);
}
调用RootWindowContainer创建一个DisplayContent,并调用addChild将其加入到RootWindowContainer的下一级。
frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
DisplayContent getDisplayContentOrCreate(int displayId) {
DisplayContent displayContent = getDisplayContent(displayId);
if (displayContent != null) {
return displayContent;
}
...
displayContent = new DisplayContent(display, this);
addChild(displayContent, POSITION_BOTTOM);
return displayContent;
}
DisplayContent有一个成员变量mSession是SurfaceSession类型,它是在申明时初始化的,因此调用构造函数即可以初始化mSession,它就代表和SurfaceFlinger的会话。它实际持有一个mNativeClient指针,指向一个SurfaceComposerClient对象,即SurfaceFlinger的客户端。
frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.DisplayContentInfo {
...
private final SurfaceSession mSession = new SurfaceSession();
...
}
frameworks/base/core/java/android/view/SurfaceSession.java
public final class SurfaceSession {
private long mNativeClient; // SurfaceComposerClient*
private static native long nativeCreate();
private static native void nativeDestroy(long ptr);
public SurfaceSession() {
mNativeClient = nativeCreate();
}
frameworks/base/core/jni/android_view_SurfaceSession.cpp
static jlong nativeCreate(JNIEnv* env, jclass clazz) {
SurfaceComposerClient* client = new SurfaceComposerClient();
client->incStrong((void*)nativeCreate);
return reinterpret_cast<jlong>(client);
}
frameworks/native/libs/gui/SurfaceComposerClient.cpp
SurfaceComposerClient::SurfaceComposerClient()
: mStatus(NO_INIT)
{
}
SurfaceComposerClient::SurfaceComposerClient(const sp<ISurfaceComposerClient>& client)
: mStatus(NO_ERROR), mClient(client)
{
}
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;
}
}
}
到这里就生成了一个SurfaceComposerClient对象,通过这个对象可以和ComposerService的实现者SurfaceFlinger通信,并调用了createConnection这个远程函数来创建一个连接conn后赋值给mClient。生成的这个SurfaceComposerClient的指针返回给JAVA层,保存在SurfaceSession.mNativeClient.
到这里就具备了和SurfaceFlinger通信的能力。
5 创建SurfaceControl
在ViewRootImpl里面构造了一个SurfaceControl,但是它只是一个空白的对象,不能使用,现在来看看有效的SurfaceControl是怎么生成的。我们把app远程调用部分省略了,直接进入到WMS的relayoutWindow方法,它的内容非常多,这里仅仅介绍一下创建SurfaceControl的逻辑
public int relayoutWindow(Session session, IWindow client, LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewVisibility, int flags,
long frameNumber, ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
SurfaceControl outSurfaceControl, InsetsState outInsetsState,
InsetsSourceControl[] outActiveControls, Point outSurfaceSize) {
...
synchronized (mGlobalLock) {
final WindowState win = windowForClientLocked(session, client, false);
...
win.setViewVisibility(viewVisibility);
...
if (shouldRelayout) {
try {
result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
}
}
...
return result;
}
首先找到这个WindowState对象(它在WMS代表一个window,在次之前,已经通过session.addToDisplay添加进来),然后调用createSurfaceControl方法来创建一个WindowSurfaceController对象
private int createSurfaceControl (SurfaceControl outSurfaceControl, int result,
WindowState win, WindowStateAnimator winAnimator) {
WindowSurfaceController surfaceController;
...
surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type);
...
surfaceController.getSurfaceControl(outSurfaceControl);
....
return result;
}
内部调用winAnimator来创建一个WindowSurfaceController对象,然后,将该对象复制给outSurfaceControl,而这个outSurfaceControl就是ViewRootImpl中创建的对象。此后,ViewRootImpl的mSurfaceControl变成有效可用。 但是如何生成这个可用对象的,还需要继续分析。
WindowSurfaceController createSurfaceLocked(int windowType) {
...
mSurfaceController = new WindowSurfaceController(attrs.getTitle().toString(), width,
height, format, flags, this, windowType);
return mSurfaceController;
}
生成WindowSurfaceController返回给回去。在构造这个对象时,内部会生成一个新的SurfaceControl
frameworks/base/services/core/java/com/android/server/wm/WindowSurfaceController.java
WindowSurfaceController(String name, int w, int h, int format,
int flags, WindowStateAnimator animator, int windowType) {
...
final SurfaceControl.Builder b = win.makeSurface()
.setParent(win.getSurfaceControl())
.setName(name)
.setBufferSize(w, h)
.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();
}
这里调用WindowState生成了一个SurfaceControl.Builder ,通过它的build来生成SurfaceControl,但是逻辑有一点绕:
SurfaceControl.Builder makeSurface() {
final WindowContainer p = getParent();
return p.makeChildSurface(this);
}
SurfaceControl.Builder makeChildSurface(WindowContainer child) {
final WindowContainer p = getParent();
// Give the parent a chance to set properties. In hierarchy v1 we rely
// on this to set full-screen dimensions on all our Surface-less Layers.
return p.makeChildSurface(child)
.setParent(mSurfaceControl);
}
这里存在多态的情况.win的类型是WindowState,它继承自WindowContainer,它调用getParent返回的也是一个WindowContainer,好像会无限循环找到根,但是因为在父容器里有一级是我们上面分析过的DisplayContent,它重写了makeChildSurface方法
frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
SurfaceControl.Builder makeChildSurface(WindowContainer child) {
SurfaceSession s = child != null ? child.getSession() : getSession();
final SurfaceControl.Builder b = mWmService.makeSurfaceBuilder(s).setContainerLayer();
if (child == null) {
return b;
}
return b.setName(child.getName())
.setParent(mSurfaceControl);
}
在这里它阻断了这个递归,并且调用了mWmService.makeSurfaceBuilder(s)来生成Builder对象。 这个DisplayContent我们上面也介绍过,它持有一个SurfaceSession成员,这里正好用它来生成SurfaceControl。生成了Builder之后调用build生成SurfaceControl对象。
frameworks/base/core/java/android/view/SurfaceControl.java
public SurfaceControl build() {
...
if ((mFlags & FX_SURFACE_MASK) == FX_SURFACE_NORMAL) {
setBLASTLayer();
}
return new SurfaceControl(
mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mMetadata,
mLocalOwnerView, mCallsite);
}
这里调用的构造方法和ViewRootImpl中调用的不同,传了非常多的参数包括用于和SurfaceFling通信的session,生成layer类型的flags等,这表示它将生成一个有效的SurfaceControl。
private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,
SurfaceControl parent, SparseIntArray metadata, WeakReference<View> localOwnerView,
String callsite) {
...
mNativeObject = nativeCreate(session, name, w, h, format, flags, parent != null ? parent.mNativeObject : 0, metaParcel);
...
mNativeHandle = nativeGetHandle(mNativeObject);
mCloseGuard.openWithCallSite("release", callsite);
}
这里会进入到了SurfaceControl的JNI层
frameworks/base/core/jni/android_view_SurfaceControl.cpp
static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
jstring nameStr, jint w, jint h, jint format, jint flags, jlong parentObject,
jobject metadataParcel) {
sp<SurfaceControl> surface;
sp<SurfaceComposerClient> client;
if (sessionObj != NULL) {
client = android_view_SurfaceSession_getClient(env, sessionObj);
} else {
client = SurfaceComposerClient::getDefault();
}
...
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的参数sessionOb是一个SurfaceSession,它来自DisplayContent,在其初始化时生成了这个对象,并连接SurfaceFlinger创建回话。
这里先调用 android_view_SurfaceSession_getClient(env, sessionObj)获取到SurfaceSession对象client,它是一个SurfaceComposerClient类型的对象,然后在调用它的createSurfaceChecked方法,
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;
sp<IBinder> handle;
sp<IGraphicBufferProducer> gbp;
...
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;
}
于是就远程呼叫Client的createSurface方法,同时会传入一个handle的地址,这个handle将存放即将创建的Layer的handle,以及gbp的地址用于保存producer。最后经这个handle为参数,构造SurfaceControl对象。也就是说SurfaceControl的handle是指向一个Layer的handle。在JAVA层,SurfaceControl的构造方法调用nativeCreate之后,也调用了nativeGetHandle方法,就是来获取Layer的handle指针,并保存到JAVA层的mNativeHandle
mNativeObject = nativeCreate(session, name, w, h, format, flags,
parent != null ? parent.mNativeObject : 0, metaParcel);
static jlong nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) {
SurfaceControl *surfaceControl = reinterpret_cast<SurfaceControl*>(nativeObject);
return reinterpret_cast<jlong>(surfaceControl->getHandle().get());
}
接着我们继续看看mClient->createSurface是如何生成Layer的。
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>* 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);
}
进一步调用mFlinger->createLayer
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) {
...
status_t result = NO_ERROR;
sp<Layer> layer;
std::string uniqueName = getUniqueLayerName(name.string());
switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
case ISurfaceComposerClient::eFXSurfaceBufferQueue:
case ISurfaceComposerClient::eFXSurfaceBufferState: {
result = createBufferStateLayer(client, std::move(uniqueName), w, h, flags, std::move(metadata), handle, &layer);
...
} break;
case ISurfaceComposerClient::eFXSurfaceEffect:
result = createEffectLayer(client, std::move(uniqueName), w, h, flags,
std::move(metadata), handle, &layer);
break;
case ISurfaceComposerClient::eFXSurfaceContainer:
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();
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;
}
上层创建一个SurfaceConftrol实质上是在SurfaceFlinger创建一个Layer,这里会根据Layer的flag生成不同的Layer,通常情况传入的flag包含的是eFXSurfaceBufferState(blast)这个位开关。因此将进入createBufferStateLayer这个方法:
status_t SurfaceFlinger::createBufferStateLayer(const sp<Client>& client, std::string name,
uint32_t w, uint32_t h, uint32_t flags,
LayerMetadata metadata, sp<IBinder>* handle,
sp<Layer>* outLayer) {
LayerCreationArgs args(this, client, std::move(name), w, h, flags, std::move(metadata));
args.textureName = getNewTexture();
sp<BufferStateLayer> layer = getFactory().createBufferStateLayer(args);
*handle = layer->getHandle();
*outLayer = layer;
return NO_ERROR;
}
这里调用getFactory().createBufferStateLayer()去创建,创建完之后即那个layer的handler赋值给handle,layer赋值为outLayer。
这样就构造好了Layer,并返回回去。
frameworks/native/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
sp<BufferStateLayer> DefaultFactory::createBufferStateLayer(const LayerCreationArgs& args) {
return new BufferStateLayer(args);
}
frameworks/native/services/surfaceflinger/BufferQueueLayer.cpp
BufferQueueLayer::BufferQueueLayer(const LayerCreationArgs& args) : BufferLayer(args) {}
BufferQueueLayer::~BufferQueueLayer() {
mContentsChangedListener->abandon();
mConsumer->abandon();
}
继承自BufferLayer, frameworks/native/services/surfaceflinger/BufferLayer.cpp
BufferLayer::BufferLayer(const LayerCreationArgs& args)
: Layer(args),
mTextureName(args.textureName),
mCompositionState{mFlinger->getCompositionEngine().createLayerFECompositionState()} {
ALOGV("Creating Layer %s", getDebugName());
mPremultipliedAlpha = !(args.flags & ISurfaceComposerClient::eNonPremultiplied);
mPotentialCursor = args.flags & ISurfaceComposerClient::eCursorWindow;
mProtectedByApp = args.flags & ISurfaceComposerClient::eProtectedByApp;
}
继承自Layer frameworks/native/services/surfaceflinger/Layer.cpp
Layer::Layer(const LayerCreationArgs& args)
: mFlinger(args.flinger),
mName(args.name),
mClientRef(args.client),
mWindowType(static_cast<InputWindowInfo::Type>(
args.metadata.getInt32(METADATA_WINDOW_TYPE, 0))) {
...
}
void Layer::onFirstRef() {
mFlinger->onLayerFirstRef(this);
}
引用到Layer的时候,会调用mFlinger->onLayerFirstRef(this);
void SurfaceFlinger::onLayerFirstRef(Layer* layer) {
mNumLayers++;
if (!layer->isRemovedFromCurrentState()) {
mScheduler->registerLayer(layer);
}
}
再调用mScheduler->registerLayer(layer)
frameworks/native/services/surfaceflinger/Scheduler/Scheduler.cpp
void Scheduler::registerLayer(Layer* layer) {
scheduler::LayerHistory::LayerVoteType voteType;
...
voteType = scheduler::LayerHistory::LayerVoteType::Heuristic;
}
mLayerHistory->registerLayer(layer, voteType);
}
frameworks/native/services/surfaceflinger/Scheduler/LayerHistory.cpp
void LayerHistory::registerLayer(Layer* layer, LayerVoteType type) {
std::lock_guard lock(mLock);
for (const auto& info : mLayerInfos) {
LOG_ALWAYS_FATAL_IF(info.first == layer, "%s already registered", layer->getName().c_str());
}
auto info = std::make_unique<LayerInfo>(layer->getName(), layer->getOwnerUid(), type);
mLayerInfos.emplace_back(layer, std::move(info));
}
将生成layer记录到历史。
当Layer创建好了之后,会去获取这个Layer的handle
sp<IBinder> Layer::getHandle() {
Mutex::Autolock _l(mLock);
if (mGetHandleCalled) {
ALOGE("Get handle called twice" );
return nullptr;
}
mGetHandleCalled = true;
return new Handle(mFlinger, this);
}
frameworks/native/services/surfaceflinger/Layer.h
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;
};
这handle里保存了surface 和 layer的引用,它也是一个IBinder类型的对象。
到这里SurfaceControl的nativeCreate方法就结束了,它通过SurfaceSession连接SurfaceFlingger,然后远程呼叫SurfaceFlinger创建一个Client连接,之后远程调用这个client的createLayer方法,进而调用到SurfaceFlinger的Factory创建一个BufferQueueLayer对象,然后将这个Layer的handle赋值到surfacecontrol.handle指针,然后将surfacecontrol的指针至返回到JAVA层,保存到SurfaceControl的mNativeObject。
至此创建有效的SurfaceControl的流程结束,它在SurfaceFlinger端创建了一个Layer,并在surfaceControl中保存了这个Layer的远程句柄。
6. BLASTBufferQueue
如果mWindowSession.relayout之后,mSurfaceControl将会变成有效的,此时会判断blast是否开启(blast特性时12新推出的,它默认开启的),所以进入到getOrCreateBLASTSurface,在这里将会生成一个BLASTBufferQueue, 。而原来的 mSurface.copyFrom(mSurfaceControl),我们将在最后来对比分析一下。
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
...
int relayoutResult = mWindowSession.relayout(mWindow, ..., mSurfaceControl, ...);
if (mSurfaceControl.isValid()) {
if (!useBLAST()) {
mSurface.copyFrom(mSurfaceControl);
} else {
final Surface blastSurface = getOrCreateBLASTSurface();
...
if (blastSurface != null) {
mSurface.transferFrom(blastSurface);
}
}
...
}
Surface getOrCreateBLASTSurface() {
if (!mSurfaceControl.isValid()) {
return null;
}
Surface ret = null;
if (mBlastBufferQueue == null) {
mBlastBufferQueue = new BLASTBufferQueue(mTag, mSurfaceControl,
mSurfaceSize.x, mSurfaceSize.y,
mWindowAttributes.format);
// We only return the Surface the first time, as otherwise
// it hasn't changed and there is no need to update.
ret = mBlastBufferQueue.createSurface();
} else {
mBlastBufferQueue.update(mSurfaceControl,
mSurfaceSize.x, mSurfaceSize.y,
mWindowAttributes.format);
}
return ret;
}
如果mBlastBufferQueue == null,则传入mSurfaceControl新创建一个mBlastBufferQueue,然后调用这个 BufferQueue.createSurface()来创建一个Surface;如果已经存在了,则进行更新操作mBlastBufferQueue.update(mSurfaceControl,…)。分析一下这个create的逻辑
frameworks/base/graphics/java/android/graphics/BLASTBufferQueue.java
public BLASTBufferQueue(String name, SurfaceControl sc, int width, int height,
@PixelFormat.Format int format) {
mNativeObject = nativeCreate(name, sc.mNativeObject, width, height, format);
}
构造方法调用nativeCreate创建底层数据,它传入了sc.mNativeObject,,在JNI层就可通过这个指针访问这个SurfaceControl对象
frameworks/base/core/jni/android_graphics_BLASTBufferQueue.cpp
static jlong nativeCreate(JNIEnv* env, jclass clazz, jstring jName, jlong surfaceControl,
jlong width, jlong height, jint format) {
...
std::string name = str8.string();
sp<BLASTBufferQueue> queue =
new BLASTBufferQueue(name, reinterpret_cast<SurfaceControl*>(surfaceControl), width, height, format);
queue->incStrong((void*)nativeCreate);
return reinterpret_cast<jlong>(queue.get());
}
nativeCreate函数将surfaceControl指针转换成SurfaceControl*指针,然后以此为参数生成了一个BLASTBufferQueue的对象queue,然后返回这个queue的指针给JAVA层并保存在mNativeObject。所以在JAVA层,BLASTBufferQueue的mNativeObject实质是指向一个BLASTBufferQueue对象,其持有一个SurfaceControl。
frameworks/native/libs/gui/BLASTBufferQueue.cpp
BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface,
int width, int height, int32_t format)
: mSurfaceControl(surface),
...{
createBufferQueue(&mProducer, &mConsumer);
...
// safe default, most producers are expected to override this
mProducer->setMaxDequeuedBufferCount(2);
...
}
createBufferQueue,并且传入了mProducer和mConsumer的地址,表示这个方法在内容生成对应的对象,并将值用这个两个指针指向他们。
void BLASTBufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
sp<IGraphicBufferConsumer>* outConsumer) {
LOG_ALWAYS_FATAL_IF(outProducer == nullptr, "BLASTBufferQueue: outProducer must not be NULL");
LOG_ALWAYS_FATAL_IF(outConsumer == nullptr, "BLASTBufferQueue: outConsumer must not be NULL");
sp<BufferQueueCore> core(new BufferQueueCore());
LOG_ALWAYS_FATAL_IF(core == nullptr, "BLASTBufferQueue: failed to create BufferQueueCore");
sp<IGraphicBufferProducer> producer(new BBQBufferQueueProducer(core));
LOG_ALWAYS_FATAL_IF(producer == nullptr,
"BLASTBufferQueue: failed to create BBQBufferQueueProducer");
sp<BufferQueueConsumer> consumer(new BufferQueueConsumer(core));
consumer->setAllowExtraAcquire(true);
LOG_ALWAYS_FATAL_IF(consumer == nullptr,
"BLASTBufferQueue: failed to create BufferQueueConsumer");
*outProducer = producer;
*outConsumer = consumer;
}
首先生成一个BufferQueueCore对象core,然后以这个core分别生成producer和consumer。最后将producer和consumer存入的指针指向他们。
这个core相当于一个容器,里面管理存放buffer,producer和consuer都持有这个core,这就是一个典型的生产者-消费者模型,core就是缓存仓库
BBQBufferQueueProducer继承自BufferQueueProducer,间接就继承自BnGraphicBufferProducer 说明它工作在服务端,是真正干活的对象。它是buffer的生产者,它会从core中取空闲的buffer出来绘制,绘制完后再放回去core。即dequeueBuffer 和queueBuffer 两个方法。
frameworks/native/libs/gui/BLASTBufferQueue.cpp
class BBQBufferQueueProducer : public BufferQueueProducer {
public:
BBQBufferQueueProducer(const sp<BufferQueueCore>& core)
: BufferQueueProducer(core, false /* consumerIsSurfaceFlinger*/) {}
frameworks/native/libs/gui/include/gui/BufferQueueProducer.h
class BufferQueueProducer : public BnGraphicBufferProducer {
frameworks/native/libs/gui/BufferQueueProducer.cpp
BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core,
bool consumerIsSurfaceFlinger) :
mCore(core),
mSlots(core->mSlots),
...
再来看看消费者,它是继承自BnGraphicBufferConsumer,因此也是工作的服务端直接干活的对象
frameworks/native/libs/gui/include/gui/BufferQueueConsumer.h
class BufferQueueConsumer : public BnGraphicBufferConsumer {
frameworks/native/libs/gui/BufferQueueConsumer.cpp
BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) :
mCore(core),
mSlots(core->mSlots),
mConsumerName() {}
这里的producer和consumer同时依赖core这个仓库,并直接操作它的slots。consumer的主要方法就是acquireBuffer和releaseBuffer。
到这里ViewRootImpl的mBlastBufferQueue就初始化完成了。
7. BBQSurface
生成了BLASTBufferQueue之后会调用createSurface或者update来创建或者更新surface。我们来看一下createSurface的流程
frameworks/base/graphics/java/android/graphics/BLASTBufferQueue.java
public Surface createSurface() {
return nativeGetSurface(mNativeObject, false /* includeSurfaceControlHandle */);
}
直接进入JNI 的nativeGetSurface函数
frameworks/base/core/jni/android_graphics_BLASTBufferQueue.cpp
static jobject nativeGetSurface(JNIEnv* env, jclass clazz, jlong ptr,
jboolean includeSurfaceControlHandle) {
sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
return android_view_Surface_createFromSurface(env,
queue->getSurface(includeSurfaceControlHandle));
}
通过传入的ptr指针转换成BLASTBufferQueue对象queue,然后调用getSurface方法
frameworks/native/libs/gui/BLASTBufferQueue.cpp
sp<Surface> BLASTBufferQueue::getSurface(bool includeSurfaceControlHandle) {
std::unique_lock _lock{mMutex};
sp<IBinder> scHandle = nullptr;
if (includeSurfaceControlHandle && mSurfaceControl) {
scHandle = mSurfaceControl->getHandle();
}
return new BBQSurface(mProducer, true, scHandle, this);
}
此处的参数includeSurfaceControlHandle == flase,所以scHandle为null,然后传入mProducer生成一个BBQSurface
class BBQSurface : public Surface {
private:
std::mutex mMutex;
sp<BLASTBufferQueue> mBbq;
bool mDestroyed = false;
public:
BBQSurface(const sp<IGraphicBufferProducer>& igbp, bool controlledByApp,
const sp<IBinder>& scHandle, const sp<BLASTBufferQueue>& bbq)
: Surface(igbp, controlledByApp, scHandle), mBbq(bbq) {
...
}
};
Surface是继承自ANativeWindow,代表一个nativewindow,它的定义在如下,这种继承关系表达有一些费解。
class Surface : public ANativeObjectBase<ANativeWindow, Surface, RefBase>
构造方法:
Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp, const sp<IBinder>& surfaceControlHandle)
: mGraphicBufferProducer(bufferProducer),
...{
...
mSurfaceControlHandle = surfaceControlHandle;
}
可以看到构建的Surface其实是它的子类BBQSurface,这里传入参数controledByApp == true,说明它是由APP自己控制的,surfaceControlHandle == nullptr, 同时接受一个producer,说这Surface的角色是producer,由surface来产生buffer数据。 surface的dequeueBuffer和enqueueBuffer最终会调用到producer对应的方法。
int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
...
status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, dqInput.width,
dqInput.height, dqInput.format,
dqInput.usage, &mBufferAge,
dqInput.getTimestamps ?
&frameTimestamps : nullptr);
...
}
int Surface::dequeueBuffers(std::vector<BatchBuffer>* buffers) {
...
status_t result = mGraphicBufferProducer->dequeueBuffers(dequeueInput, &dequeueOutput);
...
}
具体的逻辑就不在详细展开。我需要记住的是如何生成者个Surface对象,它实质上是一个BBQSurface,代表者生产者。最后通过调用一个JNI函数android_view_Surface_createFromSurface来获构建一个Surface个对象,返回给JAVA层。
jobject android_view_Surface_createFromSurface(JNIEnv* env, const sp<Surface>& surface) {
jobject surfaceObj = env->NewObject(gSurfaceClassInfo.clazz,
gSurfaceClassInfo.ctor, (jlong)surface.get());
if (surfaceObj == NULL) {
if (env->ExceptionCheck()) {
ALOGE("Could not create instance of Surface from IGraphicBufferProducer.");
LOGE_EX(env);
env->ExceptionClear();
}
return NULL;
}
surface->incStrong(&sRefBaseOwner);
return surfaceObj;
}
gSurfaceClassInfo.ctor = GetMethodIDOrDie(env, gSurfaceClassInfo.clazz, "<init>", "(J)V");
这里将反射调用Surface的私有构造方法:并将BBQSurface的指针保存到Surface.mNativeObject.
frameworks/base/core/java/android/view/Surface.java
private Surface(long nativeObject) {
synchronized (mLock) {
setNativeObjectLocked(nativeObject);
}
}
创建好这个Surface之后,需要将它保存到ViewRootImpl的mSurface中去,可以理解为将blastSurface的nativeObject赋值给mSurface
if (blastSurface != null) {
mSurface.transferFrom(blastSurface);
}
8. 不开启Blast的情况.
虽然现在默认是开始blast的,但是我们也可以分析一下不开始blast的情况,它调用的是一个copyFrom方法,从mSurfaceControl中来创建一个surface。
if (!useBLAST()) {
mSurface.copyFrom(mSurfaceControl);
}
frameworks/base/core/java/android/view/Surface.java
public void copyFrom(SurfaceControl other) {
if (other == null) {
throw new IllegalArgumentException("other must not be null");
}
long surfaceControlPtr = other.mNativeObject;
if (surfaceControlPtr == 0) {
throw new NullPointerException(
"null SurfaceControl native object. Are you using a released SurfaceControl?");
}
long newNativeObject = nativeGetFromSurfaceControl(mNativeObject, surfaceControlPtr);
updateNativeObject(newNativeObject);
}
这个里通过调用一个native方法nativeGetFromSurfaceControl返回一个surface的指针给上层保存,然后将新的newNativeObject保存到mNativeObject, 从而完成创建。我们看一下这个native方法.
static jlong nativeGetFromSurfaceControl(JNIEnv* env, jclass clazz,
jlong nativeObject,
jlong surfaceControlNativeObj) {
Surface* self(reinterpret_cast<Surface *>(nativeObject));
sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
// If the underlying IGBP's are the same, we don't need to do anything.
if (self != nullptr &&
IInterface::asBinder(self->getIGraphicBufferProducer()) ==
IInterface::asBinder(ctrl->getIGraphicBufferProducer())) {
return nativeObject;
}
sp<Surface> surface(ctrl->getSurface());
if (surface != NULL) {
surface->incStrong(&sRefBaseOwner);
}
return reinterpret_cast<jlong>(surface.get());
}
入参有一个surfaceControlNativeObj,获取到它指向的SurfaceControl对象,然后调用它的getSurface方法返回一个surface
frameworks/native/libs/gui/SurfaceControl.cpp
sp<Surface> SurfaceControl::getSurface()
{
Mutex::Autolock _l(mLock);
if (mSurfaceData == nullptr) {
return generateSurfaceLocked();
}
return mSurfaceData;
}
sp<Surface> SurfaceControl::generateSurfaceLocked()
{
uint32_t ignore;
auto flags = mCreateFlags & (ISurfaceComposerClient::eCursorWindow |
ISurfaceComposerClient::eOpaque);
mBbqChild = mClient->createSurface(String8("bbq-wrapper"), 0, 0, mFormat,
flags, mHandle, {}, &ignore);
mBbq = sp<BLASTBufferQueue>::make("bbq-adapter", mBbqChild, mWidth, mHeight, mFormat);
// This surface is always consumed by SurfaceFlinger, so the
// producerControlledByApp value doesn't matter; using false.
mSurfaceData = mBbq->getSurface(true);
return mSurfaceData;
}
这个再其次调用了mClient->createSurface,这个mClient是一个SurfaceComposerClient对象,这个前面分析过,它将与SurfaceFlinger的Client进行远程通信。
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>* 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);
}
但是这里调用的方法直接返回一个对象赋给mBbqChild,而mBbqChild是一个SurfaceControl类型的成员。因此不是单纯的IPC调用。看看定义:
sp<SurfaceControl> SurfaceComposerClient::createSurface(const String8& name, uint32_t w, uint32_t h,
PixelFormat format, uint32_t flags,
const sp<IBinder>& parentHandle,
LayerMetadata metadata,
uint32_t* outTransformHint) {
sp<SurfaceControl> s;
createSurfaceChecked(name, w, h, format, &s, flags, parentHandle, std::move(metadata),
outTransformHint);
return s;
}
原来是调用createSurfaceChecked,它内部生成了一个SurfaceControl,保存到s然后返回。
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返回回去
然后生成一个BLASTBufferQueue,之后再调用它的getSurface来创建surface,但是传入的参数是true
mBbq = sp<BLASTBufferQueue>::make("bbq-adapter", mBbqChild, mWidth, mHeight, mFormat);
// This surface is always consumed by SurfaceFlinger, so the
// producerControlledByApp value doesn't matter; using false.
mSurfaceData = mBbq->getSurface(true);
p<Surface> BLASTBufferQueue::getSurface(bool includeSurfaceControlHandle) {
std::unique_lock _lock{mMutex};
sp<IBinder> scHandle = nullptr;
if (includeSurfaceControlHandle && mSurfaceControl) {
scHandle = mSurfaceControl->getHandle();
}
return new BBQSurface(mProducer, true, scHandle, this);
}
此时的includeSurfaceControlHandle == true,mSurfaceControl 是上面创建的child。因此scHandle是指向Layer的Handle,然后生成的BBQSurface也将持有该Handle。
9. 总结
- 通过分析APP与WMS和SurfaceFlinger的IPC通信,详细介绍了创建SurfaceControl以及Surface的流程
- SurfaceControl持有SurfaceFlinger进程中创建的Layer的handle
- Surface是通过BlastBufferQueue生成的一个BBQSurface,它继承自Surface,Surface是ANativeWindow的子类,它持有一个生产者,主要有dequeueBuffer和enqueueBuffer方法。