ViewRootImpl内部有两个成员变量:
// These can be accessed by any thread, must be protected with a lock.
// Surface can never be reassigned or cleared (use Surface.clear()).
@UnsupportedAppUsage
public final Surface mSurface = new Surface();
private final SurfaceControl mSurfaceControl = new SurfaceControl();
跟踪一下向mSurface和mSurfaceControl初始化的流程。
一、SurfaceControl的初始化
1 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) {p n
mSurface.transferFrom(blastSurface);
}
}
// ......
} else {
destroySurface();
}
// ......
}
mWindowSession是IWindowSession的Binder远程代理对象,服务端的实现是Session,那么成员变量mSurfaceControl是通过Binder IPC,在系统进程中加载其中的内容的。
2 Session.relayout
@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) {
if (false) Slog.d(TAG_WM, ">>>>>> ENTERED relayout from "
+ Binder.getCallingPid());
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mRelayoutTag);
int res = mService.relayoutWindow(this, window, attrs,
requestedWidth, requestedHeight, viewFlags, flags, frameNumber,
outFrames, mergedConfiguration, outSurfaceControl, outInsetsState,
outActiveControls, outSurfaceSize);
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
if (false) Slog.d(TAG_WM, "<<<<<< EXITING relayout to "
+ Binder.getCallingPid());
return res;
}
这里继续调用了WindowManagerService.relayoutWindow。
3 WindowManagerService.relayoutWindow
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) {
// ......
// 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);
}
// ......
}
// ......
}
}
只关注outSurfaceControl的数据是如何填充的,这里继续调用WindowManagerService.createSurfaceControl方法。
4 WindowManagerService.createSurfaceControl
private int createSurfaceControl(SurfaceControl outSurfaceControl, int result,
WindowState win, WindowStateAnimator winAnimator) {
if (!win.mHasSurface) {
result |= RELAYOUT_RES_SURFACE_CHANGED;
}
WindowSurfaceController surfaceController;
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "createSurfaceControl");
surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type);
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
if (surfaceController != null) {
surfaceController.getSurfaceControl(outSurfaceControl);
ProtoLog.i(WM_SHOW_TRANSACTIONS, "OUT SURFACE %s: copied", outSurfaceControl);
} else {
// For some reason there isn't a surface. Clear the
// caller's object so they see the same state.
ProtoLog.w(WM_ERROR, "Failed to create surface control for %s", win);
outSurfaceControl.release();
}
return result;
}
有两个流程:
-
调用WindowStateAnimator.createSurfaceLocked方法来创建一个WindowSurfaceController对象。
-
调用WindowSurfaceController.getSurfaceControl来对outSurfaceControl赋值。
流程1涉及到Native层SurfaceControl的创建,需要跟踪完流程1才能知道流程2中的outSurfaceControl是怎么得到数据的。
5 WindowStateAnimator.createSurfaceLocked
WindowSurfaceController createSurfaceLocked(int windowType) {
// ......
int flags = SurfaceControl.HIDDEN;
final WindowManager.LayoutParams attrs = w.mAttrs;
if (w.isSecureLocked()) {
flags |= SurfaceControl.SECURE;
}
if ((mWin.mAttrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0) {
flags |= SurfaceControl.SKIP_SCREENSHOT;
}
// ......
// Set up surface control with initial size.
try {
// ......
mSurfaceController = new WindowSurfaceController(attrs.getTitle().toString(), width,
height, format, flags, this, windowType);
// ......
}
// ......
return mSurfaceController;
}
忽略非相关的内容,这里根据一些窗口的基本信息,如窗口名字、窗口宽高、窗口类型等,来创建一个WindowSurfaceController对象,并且赋值给WindowStateAnimator的mSurfaceController成员变量。
6 WindowSurfaceController.constructor
WindowSurfaceController(String name, int w, int h, 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())
.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();
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
这里先调用WindowState.makeSurface方法生成了一个SurfaceControl.Builder对象,然后提前设置了一些SurfaceControl.Builder的属性,这些属性最终是要应用给SurfaceControl的。接着调用SurfaceControl.Builder.build方法来生成一个SurfaceControl对象,并且赋值给WindowSurfaceController的成员变量mSurfaceControl。
7 SurfaceControl.Builder.build
/**
* Construct a new {@link SurfaceControl} with the set parameters. The builder
* remains valid.
*/
@NonNull
public SurfaceControl build() {
if (mWidth < 0 || mHeight < 0) {
throw new IllegalStateException(
"width and height must be positive or unset");
}
if ((mWidth > 0 || mHeight > 0) && (isEffectLayer() || isContainerLayer())) {
throw new IllegalStateException(
"Only buffer layers can set a valid buffer size.");
}
if ((mFlags & FX_SURFACE_MASK) == FX_SURFACE_NORMAL) {
setBLASTLayer();
}
return new SurfaceControl(
mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mMetadata,
mLocalOwnerView, mCallsite);
}
先对这个即将创建的新的SurfaceControl的相关属性进行有效性检查,接着基于之前传入SurfaceControl.Builder的相关信息创建一个SurfaceControl对象。
另外在创建这里看到有一个设置flag的操作:
if ((mFlags & FX_SURFACE_MASK) == FX_SURFACE_NORMAL) {
setBLASTLayer();
}
首先先看一下FX_SURFACE_MASK的相关信息,FX_SURFACE_MASK这一位的相关flag的定义如下:
/**
* Surface creation flag: Creates a normal surface.
* This is the default.
*
* @hide
*/
public static final int FX_SURFACE_NORMAL = 0x00000000;
/**
* Surface creation flag: Creates a effect surface which
* represents a solid color and or shadows.
*
* @hide
*/
public static final int FX_SURFACE_EFFECT = 0x00020000;
/**
* Surface creation flag: Creates a container surface.
* This surface will have no buffers and will only be used
* as a container for other surfaces, or for its InputInfo.
* @hide
*/
public static final int FX_SURFACE_CONTAINER = 0x00080000;
/**
* @hide
*/
public static final int FX_SURFACE_BLAST = 0x00040000;
/**
* Mask used for FX values above.
*
* @hide
*/
public static final int FX_SURFACE_MASK = 0x000F0000;
这里看到FX_SURFACE_MASK代表的这一位把Surface分成了几种类型:
- FX_SURFACE_NORMAL,代表了一个标准Surface,这个是默认设置。
- FX_SURFACE_EFFECT,代表了一个有纯色或者阴影效果的Surface。
- FX_SURFACE_CONTAINER,代表了一个容器类Surface,这种Surface没有缓冲区,只是用来作为其他Surface的容器,或者是它自己的InputInfo的容器。
- FX_SURFACE_BLAST,结合这里的分析可以看到,FX_SURFACE_BLAST应该是等同于FX_SURFACE_NORMAL。
如果SurfaceControl.Builder的mFlags中的FX_SURFACE_MASK这一位是FX_SURFACE_NORMAL,那么调用SurfaceControl.setBLASTLayer方法:
/**
* @hide
*/
public Builder setBLASTLayer() {
return setFlags(FX_SURFACE_BLAST, FX_SURFACE_MASK);
}
将FX_SURFACE_MASK代表的这一位设置为FX_SURFACE_BLAST。
SurfaceControl.Builder的mFlags的值是从WindowStateAnimator.createSurfaceLocked中获取的,WindowStateAnimator.createSurfaceLocked方法中没有针对FX_SURFACE_MASK这一位进行特殊处理,那么也就是说,这里会调用setBLASTLayer方法将mFlags的FX_SURFACE_MASK代表的这一位设置为FX_SURFACE_BLAST。
8 Java层SurfaceControl.constructor
/**
* Create a surface with a name.
* <p>
* The surface creation flags specify what kind of surface to create and
* certain options such as whether the surface can be assumed to be opaque
* and whether it should be initially hidden. Surfaces should always be
* created with the {@link #HIDDEN} flag set to ensure that they are not
* made visible prematurely before all of the surface's properties have been
* configured.
* <p>
* Good practice is to first create the surface with the {@link #HIDDEN} flag
* specified, open a transaction, set the surface layer, layer stack, alpha,
* and position, call {@link Transaction#show(SurfaceControl)} if appropriate, and close the
* transaction.
* <p>
* Bounds of the surface is determined by its crop and its buffer size. If the
* surface has no buffer or crop, the surface is boundless and only constrained
* by the size of its parent bounds.
*
* @param session The surface session, must not be null.
* @param name The surface name, must not be null.
* @param w The surface initial width.
* @param h The surface initial height.
* @param flags The surface creation flags.
* @param metadata Initial metadata.
* @param callsite String uniquely identifying callsite that created this object. Used for
* leakage tracking.
* @throws throws OutOfResourcesException If the SurfaceControl cannot be created.
*/
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 {
// ......
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);
}
渣翻:
这个方法用来生成一个有名字的Surface。
Surface创建标志明确了要创建哪种Surface和特定的选项,比如Surface可以被认为是不透明的,是否应该在初始的时候隐藏。Surface应该总是在创建的时候带着HIDDEN标志,以确保在Surface的属性配置好之前,Surface不会过早显示。
一个好的实践是,首先使用HIDDEN标志创建Surface,接着打开一个Transactionn,设置Surface的layer、layer堆栈、透明度、位置,然后再合适的时机调用Transaction.show,最后关闭Transactoin。
Surface的界限由它的crop和buffer尺寸决定。如果这个Surface没有buffer或者是crop,那么这个Surface就是无边界的,只被它的父Surface的界限尺寸所限制。
这里调用了nativeCreate来创建native层的SurfaceControl。
9 android_view_SurfaceControl.nativeCreate
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;
// ......
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());
}
这里的sessionObj是一个Java层的SurfaceSession对象,之前分析App到SurfaceFlinger的连接时候有分析到,App在第一次添加窗口的时候,会创建一个SurfaceSession对象,然后在JNI层的SurfaceSession对象创建的时候,会创建一个SurfaceComposerClient对象来连接到SurfaceFlinger。
那么这里先根据传入的sessionObj对象获取到一个SurfaceComposerClient对象,然后调用SurfaceComposerClient.createSurfaceChecked生成一个Native层的SurfaceControl对象,最后调用incStrong将SurfaceControl的强引用计数增加1,这会导致SurfaceControl的onFirstRef函数被调用,最后将这个创建的Native层的SurfaceControl的地址转换成一个整型返回给上层的SurfaceControl对象。
10 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;
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;
}
1)、根据之前分析App到SurfaceFlinger的连接,知道SurfaceComposerClient的成员变量mClient是一个BpSurfaceComposerClient类型的Binder代理对象,它的服务端实现是在SurfaceFlinger服务的Client类,那么这里最终是调用了服务端Client.createSurface函数。
2)、基于从服务端返回的信息,创建一个surfaceControl对象,这部分要等分析完服务端的内容后才能继续分析。
11 Client.createSurface
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);
}
已知在Client内部是通过一个sp<SurfaceFlinger>类型的成员变量mFlinger是一个SurfaceFlinger类型的强指针,那么这里调用的即是SurfaceFlinger.createLayer。
12 SurfaceFlinger.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;
}
这里的getUniqueLayerName函数保证每一个Layer都有一个独一无二的名字,名字的格式为:
uniqueName = base::StringPrintf("%s#%u", name, ++dupeCounter);
保证了即使是同一个Activity的两个窗口,也能根据“#0”,“#1”等序号进行区分。
12.1 Layer的几种类型
这里根据传入的flags参数的ISurfaceComposerClient::eFXSurfaceMask这一位去创建不同类型的Layer对象。这里的ISurfaceComposerClient中的定义的:
eFXSurfaceBufferQueue = 0x00000000,
eFXSurfaceEffect = 0x00020000,
eFXSurfaceBufferState = 0x00040000,
eFXSurfaceContainer = 0x00080000,
eFXSurfaceMask = 0x000F0000,
这些flag和我们在分析SurfaceControl.Builder.build方法的内容的时候介绍的flag是一一对应的,这里看到:
- eFXSurfaceBufferQueue和eFXSurfaceBufferState,对应BufferStateLayer。
- eFXSurfaceEffect,对应EffectLayer。
- eFXSurfaceContainer,对应ContainerLayer。
还有一种BufferQueueLayer,但是到Android 12这种BufferQueueLayer的相关代码虽然还保留,但是没有创建BufferQueueLayer的地方了。
上一张简单的类图看下这些Layer的关系:

12.2 BufferStateLayer的创建
根据之前的分析,我们这里要创建的是BufferStateLayer类型的Layer,那么走的是SurfaceFlinger.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;
}
SurfaceFlinger创建createBufferStateLayer的流程比较简单,所以就不详细分析了,这里看下我觉得需要注意的几个点。
12.2.1 Layer向SurfaceFlinger进行注册
SurfaceFlinger.createBufferStateLayer中,在我们创建了一个BufferStateLayer对象后,将一个BufferStateLayer类型的强指针指向这个对象,
sp<BufferStateLayer> layer = getFactory().createBufferStateLayer(args);
后续在Layer的onFirstRef函数中:
void Layer::onFirstRef() {
mFlinger->onLayerFirstRef(this);
}
调用了SurfaceFlinger.onLayerFirstRef:
void SurfaceFlinger::onLayerFirstRef(Layer* layer) {
mNumLayers++;
if (!layer->isRemovedFromCurrentState()) {
mScheduler->registerLayer(layer);
}
}
这里看到SurfaceFlinger内部有一个成员变量
std::atomic<size_t> mNumLayers = 0;
负责对所有创建的Layer进行计数。
如果当前Layer有父Layer,那么继续调用Scheduler.registerLayer函数对新创建的Layer进行记录。
12.2.2 Layer句柄的创建
SurfaceFlinger.createBufferStateLayer在创建了BufferStateLayer对象后,这里又调用了Layer.getHandle函数:
*handle = layer->getHandle();
Layer.getHandle函数定义是:
// Creates a new handle each time, so we only expect
// this to be called once.
sp<IBinder> getHandle();
Layer.getHandle函数只被期望在Layer创建的时候调用一次:
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类的定义如下:
/*
* 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), owner(layer) {}
wp<Layer> owner;
};
Layer句柄只是一个传递给客户端进程的BBinder对象,我们不在本地保存任何引用,以便客户端在释放它的引用的时候析构函数可以被调用。最终这个句柄是要传给客户端,也就是SurfaceComposerClient处,然后SurfaceComposerClient基于这个Layer句柄创建一个SurfaceControl对象。那么我暂时像理解token一样,理解Layer句柄的作用为跨进程标识一个唯一的Layer。
LayerCleaner保证了当这个句柄销毁的时候SurfaceFlinger.onLayerDestroyed函数可以被调用,SurfaceFlinger.onLayerDestroyed函数即和我们上面讲的Layer创建的时候调用SurfaceFlinger.onLayerFirstRef这个函数相对。
13 SurfaceFlinger.addClientLayer
SurfaceFlinger.createLayer函数在创建了Layer后,继续调用了SurfaceFlinger.addClientLayer。
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);
// ......
// 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 */);
}
目前看到这个函数有两个作用:
- 将<Handle, Layer>对记录到Client中
- 将<Handle, Layer>对记录到SurfaceFlinger中
下面逐个分析。
13.1 将<Handle, Layer>对记录到Client中
这一步对应的是SurfaceFlinger.addClientLayer的如下内容:
// attach this layer to the client
client->attachLayer(handle, lbc);
Client.attachLayer函数很简单:
void Client::attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer)
{
Mutex::Autolock _l(mLock);
mLayers.add(handle, layer);
}
这里通过Client的成员变量mLayers:
// protected by mLock
DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayers;
将新创建的Layer和相应的Layer句柄保存在Client中,这样,每一个Client都维护了一个属于自己的Layer的表。
Layer句柄在SurfaceFlinger创建完Layer后,会返回给SurfaceComposerClient。那么后续SurfaceComposerClient发送Layer句柄到Client的时候,Client就可以通过该Layer句柄找到相应的Layer,就像下面的代码一样:
sp<Layer> Client::getLayerUser(const sp<IBinder>& handle) const
{
Mutex::Autolock _l(mLock);
sp<Layer> lbc;
wp<Layer> layer(mLayers.valueFor(handle));
if (layer != 0) {
lbc = layer.promote();
ALOGE_IF(lbc==0, "getLayerUser(name=%p) is dead", handle.get());
}
return lbc;
}
13.2 将<Handle, Layer>对记录到SurfaceFlinger中
SurfaceFlinger.addClientLayer还有一部分内容没讲到:
// 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);
// ......
return setTransactionState(FrameTimelineInfo{}, states, displays, 0 /* flags */, nullptr,
InputWindowCommands{}, -1 /* desiredPresentTime */,
true /* isAutoTimestamp */, {}, false /* hasListenerCallbacks */, {},
0 /* Undefined transactionId */);
这里首先初始化了一个ComposerState类型和DisplayState类型的Vector,接着创建了一个ComposerState类型的对象。
ComposerState和DisplayState这两个类型都定义在LayerState.h中:
struct ComposerState {
layer_state_t state;
status_t write(Parcel& output) const;
status_t read(const Parcel& input);
};
struct DisplayState {
// ......
status_t write(Parcel& output) const;
status_t read(const Parcel& input);
};
这里主要关注ComposerState类型。
ComposerState结构体中又有一个layer_state_t类型的成员:
/*
* Used to communicate layer information between SurfaceFlinger and its clients.
*/
struct layer_state_t {
// ......
sp<IBinder> surface;
// ......
uint64_t what;
// ......
}
layer_state_t用来在SurfaceFlinger和它的客户端,也就是SurfaceComposerClient,交流Layer信息。
这里主要做了以下几件事:
1)、设置了该ComposerState对象中的layer_state_t对象的what成员为layer_state_t::eLayerCreated。
2)、设置了该ComposerState对象中的layer_state_t对象的surface成员为handle,那么这个layer_state_t里就保存了Layer的句柄。
3)、然后把这个创建的ComposerState添加到上面的ComposerState向量中。
4)、最后调用SurfaceFlinger.setTransactionState。
SurfaceFlinger.setTransactionStat调用后,中间的步骤暂不去考虑,最终在SurfaceFlinger.setClientStateLocked函数中,可以看到:
uint32_t SurfaceFlinger::setClientStateLocked(
const FrameTimelineInfo& frameTimelineInfo, const ComposerState& composerState,
int64_t desiredPresentTime, bool isAutoTimestamp, int64_t postTime, uint32_t permissions,
std::unordered_set<ListenerCallbacks, ListenerCallbacksHash>& outListenerCallbacks) {
const layer_state_t& s = composerState.state;
// ......
const uint64_t what = s.what;
uint32_t flags = 0;
sp<Layer> layer = nullptr;
if (s.surface) {
if (what & layer_state_t::eLayerCreated) {
layer = handleLayerCreatedLocked(s.surface);
if (layer) {
// put the created layer into mLayersByLocalBinderToken.
mLayersByLocalBinderToken.emplace(s.surface->localBinder(), layer);
flags |= eTransactionNeeded | eTraversalNeeded;
mLayersAdded = true;
}
} else {
layer = fromHandleLocked(s.surface).promote();
}
}
// ......
}
当检测到layer_state_t的what包含layer_state_t::eLayerCreated时,会调用以下代码:
layer = handleLayerCreatedLocked(s.surface);
if (layer) {
// put the created layer into mLayersByLocalBinderToken.
mLayersByLocalBinderToken.emplace(s.surface->localBinder(), layer);
flags |= eTransactionNeeded | eTraversalNeeded;
mLayersAdded = true;
}
主要内容为:
1)、调用handleLayerCreatedLocked,从传入的composerState对象的layer_state_t类型的state中,拿到Layer句柄中保存的Layer对象,再根据Layer的parent情况选择是添加还是移除:
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加入到父Layer之中,那么这个Layer才算真正加入到了Layer的层级结构中。
2)、将<Handle, Layer>记录到SurfaceFlinger的成员变量mLayersByLocalBinderToken中:
std::unordered_map<BBinder*, wp<Layer>> mLayersByLocalBinderToken GUARDED_BY(mStateLock);
这样SurfaceFlinger也可以直接通过Layer句柄找到对应的Layer。
14 C++层SurfaceControl.constructor
SurfaceFlinger这边分析完了,再回到客户端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;
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 (err == NO_ERROR) {
*outSurface =
new SurfaceControl(this, handle, gbp, id, w, h, format, transformHint, flags);
}
}
// ......
}
通过跨进程调用Client.createSurface,我们最终是在SurfaceFlinger服务端生成了一个Layer,并且返回了一个Layer的句柄,接着我们基于这些信息创建一个SurfaceControl对象:
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) {
}
在SurfaceControl内部,则保存了SurfaceComposerClient、Layer句柄等相关信息:
sp<SurfaceComposerClient> mClient;
sp<IBinder> mHandle;
sp<IGraphicBufferProducer> mGraphicBufferProducer;
这样客户端的SurfaceControl便和服务端中的一个具体的Layer通过Layer句柄联系起来了。
15 WindowSurfaceController.getSurfaceControl
回看Java层SurfaceControl的构造方法:
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 {
// .......
try {
// ......
mNativeObject = nativeCreate(session, name, w, h, format, flags,
parent != null ? parent.mNativeObject : 0, metaParcel);
} finally {
metaParcel.recycle();
}
// ......
mNativeHandle = nativeGetHandle(mNativeObject);
}
其内部的两个成员变量:
/**
* @hide
*/
public long mNativeObject;
private long mNativeHandle;
分别保存了Native层的SurfaceControl对象的地址和Layer句柄的地址。
然后回看WindowManagerService.createSurfaceControl方法,是调用了WindowSurfaceController.getSurfaceControl方法来为outSurfaceControl进行赋值:
void getSurfaceControl(SurfaceControl outSurfaceControl) {
outSurfaceControl.copyFrom(mSurfaceControl, "WindowSurfaceController.getSurfaceControl");
}
这里调用了SurfaceControl的copyFrom方法,copyFrom方法内部又调用了SurfaceControl的assignNativeObject方法:
private void assignNativeObject(long nativeObject, String callsite) {
if (mNativeObject != 0) {
release();
}
if (nativeObject != 0) {
mCloseGuard.openWithCallSite("release", callsite);
}
mNativeObject = nativeObject;
mNativeHandle = mNativeObject != 0 ? nativeGetHandle(nativeObject) : 0;
}
/**
* @hide
*/
public void copyFrom(@NonNull SurfaceControl other, String callsite) {
mName = other.mName;
mWidth = other.mWidth;
mHeight = other.mHeight;
mLocalOwnerView = other.mLocalOwnerView;
assignNativeObject(nativeCopyFromSurfaceControl(other.mNativeObject), callsite);
}
那么最终的结果是,WindowManagerService(WindowSurfaceController)和ViewRootImpl分别持有的Java层的SurfaceControl对象都指向同一个Native层的SurfaceControl。
经评论区提醒这里的分析有误,看copyForm这里会继续调用nativeCopyFromSurfaceControl:
那么拷贝的时候也会创建一个native的SurfaceControl对象。
所以最终结果应该是ViewRootImpl在拷贝系统进程的java层SurfaceControl时,会同步拷贝native层的SurfaceControl,并非之前所说的指向同一个native层的SurfaceControl,并且拷贝的时候layerId以及layer句柄都是直接拷贝的,因此他们指向的仍是同一个Layer。
16 小结

1)、Java层创建了两个SurfaceControl对象,分别由ViewRootImpl和WindowSurfaceController持有。
2)、C++层创建了一个SurfaceControl对象,它的指针地址被转为long型保存在Java层的SurfaceControl的mNativeObject中,那么C++层就可以通过从Java传来的long型变量得到C++层的SurfaceControl指针。
3)、每一个客户端的SurfaceControl对象持有一个IBinder类型的Layer句柄,该Layer句柄跨进程标识了一个SurfaceFlinger服务端的Layer对象,可以向SurfaceFlinger传入该Layer句柄从而找到该SurfaceControl对应的Layer对象。
二、BLASTBufferQueue的创建
回看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);
}
}
// ......
} else {
destroySurface();
}
// ......
}
不管是通过启动Activity的方式来创建App类型的窗口,还是通过主动调用WindowManager.addView的方式来创建非App类型的窗口,流程都是一样,最终都是通过ViewRootImpl与WMS通信来创建一个窗口。
boolean useBLAST() {
return mUseBLASTAdapter && !mForceDisableBLAST;
}
mUseBLASTAdapter受以下Settings数据库字段控制,默认是true。mForceDisableBLAST只有ViewRootImpl.forceDisableBLAST显式调用才会被设置为true,这里是false。
/**
* If true, submit buffers using blast in ViewRootImpl.
* (0 = false, 1 = true)
* @hide
*/
@Readable
public static final String DEVELOPMENT_USE_BLAST_ADAPTER_VR =
"use_blast_adapter_vr";
那么这里走的逻辑是先通过ViewRootImpl.getOrCreateBLASTSurface方法得到一个Surface对象,然后调用Surface.transferFrom完成对mSurface的内容填充。
1 ViewRootImpl.getOrCreateBLASTSurface
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。另外一提,mBlastBufferQueue唯一赋值的地方就是这里。
先看下BLASTBufferQueue对象的创建流程。
2 BLASTBufferQueue.constructor
/** Create a new connection with the surface flinger. */
public BLASTBufferQueue(String name, SurfaceControl sc, int width, int height,
@PixelFormat.Format int format) {
mNativeObject = nativeCreate(name, sc.mNativeObject, width, height, format);
}
调用JNI的nativeCreate函数,long型的mNativeObject保存Native层的BLASTBufferQueue对象的指针。
3 android_graphics_BLASTBufferQueue.nativeCreate
static jlong nativeCreate(JNIEnv* env, jclass clazz, jstring jName, jlong surfaceControl,
jlong width, jlong height, jint format) {
String8 str8;
if (jName) {
const jchar* str16 = env->GetStringCritical(jName, nullptr);
if (str16) {
str8 = String8(reinterpret_cast<const char16_t*>(str16), env->GetStringLength(jName));
env->ReleaseStringCritical(jName, str16);
str16 = nullptr;
}
}
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());
}
创建一个Native层的BLASTBufferQueue对象,并且触发它的onFirstRef函数。
4 BLASTBufferQueue.constructor
BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface,
int width, int height, int32_t format)
: mSurfaceControl(surface),
mSize(width, height),
mRequestedSize(mSize),
mFormat(format),
mNextTransaction(nullptr) {
createBufferQueue(&mProducer, &mConsumer);
// since the adapter is in the client process, set dequeue timeout
// explicitly so that dequeueBuffer will block
mProducer->setDequeueTimeout(std::numeric_limits<int64_t>::max());
// safe default, most producers are expected to override this
// 设置生产者执行一次dequeue可以获得的最大缓冲区数。
mProducer->setMaxDequeuedBufferCount(2);
mBufferItemConsumer = new BLASTBufferItemConsumer(mConsumer,
GraphicBuffer::USAGE_HW_COMPOSER |
GraphicBuffer::USAGE_HW_TEXTURE,
1, false);
static int32_t id = 0;
mName = name + "#" + std::to_string(id);
auto consumerName = mName + "(BLAST Consumer)" + std::to_string(id);
mQueuedBufferTrace = "QueuedBuffer - " + mName + "BLAST#" + std::to_string(id);
id++;
mBufferItemConsumer->setName(String8(consumerName.c_str()));
// 设置当一个新的帧变为可用后会被通知的监听器对象。
mBufferItemConsumer->setFrameAvailableListener(this);
// 设置当一个旧的缓冲区被释放后会被通知的监听器对象。
mBufferItemConsumer->setBufferFreedListener(this);
// 设置当宽度和高度被请求为0时从dequeueBuffer返回的缓冲区的大小。默认是1x1。
mBufferItemConsumer->setDefaultBufferSize(mSize.width, mSize.height);
mBufferItemConsumer->setDefaultBufferFormat(convertBufferFormat(format));
// 将BlastBufferItemConsumer的成员变量mBLASTBufferQueue指向当前BlastBufferQueue对象。
mBufferItemConsumer->setBlastBufferQueue(this);
// 得到SurfaceFlinger需要获取的缓冲区的数量。
ComposerService::getComposerService()->getMaxAcquiredBufferCount(&mMaxAcquiredBuffers);
// 设置消费者可以一次获取的缓冲区的最大值(默认为1)。
mBufferItemConsumer->setMaxAcquiredBufferCount(mMaxAcquiredBuffers);
mTransformHint = mSurfaceControl->getTransformHint();
mBufferItemConsumer->setTransformHint(mTransformHint);
SurfaceComposerClient::Transaction()
.setFlags(surface, layer_state_t::eEnableBackpressure,
layer_state_t::eEnableBackpressure)
.setApplyToken(mApplyToken)
.apply();
mNumAcquired = 0;
mNumFrameAvailable = 0;
BQA_LOGV("BLASTBufferQueue created width=%d height=%d format=%d mTransformHint=%d", width,
height, format, mTransformHint);
}
4.1 BLASTBufferQueue.createBufferQueue
// Similar to BufferQueue::createBufferQueue but creates an adapter specific bufferqueue producer.
// This BQP allows invoking client specified ProducerListeners and invoke them asynchronously,
// emulating one way binder call behavior. Without this, if the listener calls back into the queue,
// we can deadlock.
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;
}
类似于BufferQueue::createBufferQueue,但是创建了一个适配器专用的BufferQueue生产者。这个BQP允许调用客户端指定的ProducerListener并异步调用它们,模拟单向Binder调用行为。如果ProducerListener在没有它的情况下回调进入BLASTBufferQueue,我们就会死锁。
这个函数创建了三个对象,BufferQueueCore、BBQBufferQueueProducer和BufferQueueConsumer。暂时还不清楚这几个对象的作用,先从为数不多的注释去了解。
4.1.1 BufferQueueCore
sp<BufferQueueCore> core(new BufferQueueCore());
创建了一个BufferQueueCore对象。
4.1.1.1 BufferQueueCore的继承关系
BufferQueueCore对象继承自:
class BufferQueueCore : public virtual RefBase {
没有什么太值得关注的。
4.1.1.2 BufferQueueCore的构造函数
BufferQueueCore的定义可以从它的构造函数的注释中去理解:
// BufferQueueCore manages a pool of gralloc memory slots to be used by
// producers and consumers.
BufferQueueCore();
BufferQueueCore管理一个由生产者和消费者使用的gralloc内存槽池。Gralloc查阅google文档:
Gralloc 内存分配器会进行缓冲区分配,并通过两个特定于供应商的 HIDL 接口来进行实现(请参阅 hardware/interfaces/graphics/allocator/ 和 hardware/interfaces/graphics/mapper/)。allocate() 函数采用预期的参数(宽度、高度、像素格式)以及一组用法标志。
构造函数是:
BufferQueueCore::BufferQueueCore()
: mMutex(),
// ......
{
// getMaxBufferCountLocked返回一次可以分配的缓冲区的最大数量。
int numStartingBuffers = getMaxBufferCountLocked();
for (int s = 0; s < numStartingBuffers; s++) {
// mFreeSlots包含了所有的处于FREE状态并且当前没有缓冲区附着的槽。
mFreeSlots.insert(s);
}
for (int s = numStartingBuffers; s < BufferQueueDefs::NUM_BUFFER_SLOTS;
s++) {
// mUnusedSlots包含了当前没有被使用的所有槽。它们应该是空闲且没有附着一个缓冲区的。
mUnusedSlots.push_front(s);
}
}
4.1.2 BBQBufferQueueProducer
sp<IGraphicBufferProducer> producer(new BBQBufferQueueProducer(core));
创建了一个BBQBufferQueueProducer对象。
4.1.2.1 BBQBufferQueueProducer的继承关系
BBQBufferQueueProducer继承BufferQueueProducer:
// Extends the BufferQueueProducer to create a wrapper around the listener so the listener calls
// can be non-blocking when the producer is in the client process.
class BBQBufferQueueProducer : public BufferQueueProducer {
BBQBufferQueueProducer创建一层对listener(IProducerListener)的封装,以便当生产者在客户端进程的时候listener调用可以是非阻塞的。
暂时不太清楚BufferQueueProducer的作用,只看到是BufferQueueProducer是继承BnGraphicBufferProducer的:
class BufferQueueProducer : public BnGraphicBufferProducer {
BnGraphicBufferProducer又是继承IGraphicBufferProducer的:
class BnGraphicBufferProducer : public IGraphicBufferProducer {
IGraphicBufferProducer的定义是:
/*
* This class defines the Binder IPC interface for the producer side of
* a queue of graphics buffers. It's used to send graphics data from one
* component to another. For example, a class that decodes video for
* playback might use this to provide frames. This is typically done
* indirectly, through Surface.
*
* The underlying mechanism is a BufferQueue, which implements
* BnGraphicBufferProducer. In normal operation, the producer calls
* dequeueBuffer() to get an empty buffer, fills it with data, then
* calls queueBuffer() to make it available to the consumer.
*
* This class was previously called ISurfaceTexture.
*/
#ifndef NO_BINDER
class IGraphicBufferProducer : public IInterface {
DECLARE_HYBRID_META_INTERFACE(GraphicBufferProducer,
HGraphicBufferProducerV1_0,
HGraphicBufferProducerV2_0)
#else
class IGraphicBufferProducer : public RefBase {
这个类为图形缓冲区队列的生产者端定义了Binder IPC接口。它用于将图形数据从一个组件发送到另一个组件。例如,一个用作回放的解码视频的类可以使用它来提供帧。这通常是通过Surface间接完成的。
底层机制是一个BufferQueue,它实现了BnGraphicBufferProducer。在通常操作中,生产者调用dequeueBuffer()来获得一个空缓冲区,用数据填充它,然后调用queueBuffer()使消费者可以使用它。
这个类以前被称为ISurfaceTexture。
4.1.2.2 BBQBufferQueueProducer的构造函数
BBQBufferQueueProducer(const sp<BufferQueueCore>& core)
: BufferQueueProducer(core, false /* consumerIsSurfaceFlinger*/) {}
再看BufferQueueProducer的构造函数:
BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core,
bool consumerIsSurfaceFlinger) :
mCore(core),
mSlots(core->mSlots),
mConsumerName(),
mStickyTransform(0),
mConsumerIsSurfaceFlinger(consumerIsSurfaceFlinger),
mLastQueueBufferFence(Fence::NO_FENCE),
mLastQueuedTransform(0),
mCallbackMutex(),
mNextCallbackTicket(0),
mCurrentCallbackTicket(0),
mCallbackCondition(),
mDequeueTimeout(-1),
mDequeueWaitingForAllocation(false) {}
将sp<BufferQueueCore>类型的成员变量mCore指向上面创建的BufferQueueCore对象。
4.1.3 BufferQueueConsumer
sp<BufferQueueConsumer> consumer(new BufferQueueConsumer(core));
创建了一个BufferQueueConsumer对象。
4.1.3.1 BufferQueueConsumer的继承关系
BufferQueueConsumer继承自BnGraphicBufferConsumer:
class BufferQueueConsumer : public BnGraphicBufferConsumer {
BnGraphicBufferConsumer又继承自IGraphicBufferConsumer:
class BnGraphicBufferConsumer : public IGraphicBufferConsumer {
目前从BufferQueueConsumer的继承关系中无法得知BufferQueueConsumer的具体作用。
4.1.3.2 BufferQueueConsumer的构造函数
BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) :
mCore(core),
mSlots(core->mSlots),
mConsumerName() {}
将sp<BufferQueueCore>类型的成员变量mCore指向上面创建的BufferQueueCore对象。
4.2 BLASTBufferItemConsumer
mBufferItemConsumer = new BLASTBufferItemConsumer(mConsumer,
GraphicBuffer::USAGE_HW_COMPOSER |
GraphicBuffer::USAGE_HW_TEXTURE,
1, false);
static int32_t id = 0;
mName = name + "#" + std::to_string(id);
auto consumerName = mName + "(BLAST Consumer)" + std::to_string(id);
mQueuedBufferTrace = "QueuedBuffer - " + mName + "BLAST#" + std::to_string(id);
id++;
mBufferItemConsumer->setName(String8(consumerName.c_str()));
// 设置当一个新的帧变为可用后会被通知的监听器对象。
mBufferItemConsumer->setFrameAvailableListener(this);
// 设置当一个旧的缓冲区被释放后会被通知的监听器对象。
mBufferItemConsumer->setBufferFreedListener(this);
// 设置当宽度和高度被请求为0时从dequeueBuffer返回的缓冲区的大小。默认是1x1。
mBufferItemConsumer->setDefaultBufferSize(mSize.width, mSize.height);
mBufferItemConsumer->setDefaultBufferFormat(convertBufferFormat(format));
// 将BlastBufferItemConsumer的成员变量mBLASTBufferQueue指向当前BlastBufferQueue对象。
mBufferItemConsumer->setBlastBufferQueue(this);
这里看到,基于上一步得到的sp<IGraphicBufferConsumer>类型的成员变量mConsumer,创建了一个BLASTBufferItemConsumer对象。
4.2.1 BufferItemConsumer
BLASTBufferItemConsumer继承自BufferItemConsumer:
class BLASTBufferItemConsumer : public BufferItemConsumer {
BufferItemConsumer继承自ConsumerBase:
/**
* BufferItemConsumer is a BufferQueue consumer endpoint that allows clients
* access to the whole BufferItem entry from BufferQueue. Multiple buffers may
* be acquired at once, to be used concurrently by the client. This consumer can
* operate either in synchronous or asynchronous mode.
*/
class BufferItemConsumer: public ConsumerBase
BufferItemConsumer是一个BufferQueue消费者端点,允许客户端从BufferQueue访问整个BufferItem条目。多个缓冲区可以被同时获取,供客户端并发使用。此消费者可以以同步或异步模式操作。
构造函数是:
BufferItemConsumer::BufferItemConsumer(
const sp<IGraphicBufferConsumer>& consumer, uint64_t consumerUsage,
int bufferCount, bool controlledByApp) :
ConsumerBase(consumer, controlledByApp)
{
// setConsumerUsageBits将为dequeueBuffer打开额外的使用位。它们与传递给dequeueBuffer的位合并。
status_t err = mConsumer->setConsumerUsageBits(consumerUsage);
LOG_ALWAYS_FATAL_IF(err != OK,
"Failed to set consumer usage bits to %#" PRIx64, consumerUsage);
if (bufferCount != DEFAULT_MAX_BUFFERS) {
// setMaxAcquiredBufferCount设置消费者一次可以取得的缓冲区的最大数量。
err = mConsumer->setMaxAcquiredBufferCount(bufferCount);
LOG_ALWAYS_FATAL_IF(err != OK,
"Failed to set max acquired buffer count to %d", bufferCount);
}
}
4.2.2 ConsumerBase
// ConsumerBase is a base class for BufferQueue consumer end-points. It
// handles common tasks like management of the connection to the BufferQueue
// and the buffer pool.
class ConsumerBase : public virtual RefBase,
protected ConsumerListener {
ConsumerBase是BufferQueue消费者端点的基类。它处理一些常见的任务,比如管理到BufferQueue和缓冲池的连接。
再看它的构造函数的定义:
// ConsumerBase constructs a new ConsumerBase object to consume image
// buffers from the given IGraphicBufferConsumer.
// The controlledByApp flag indicates that this consumer is under the application's
// control.
explicit ConsumerBase(const sp<IGraphicBufferConsumer>& consumer, bool controlledByApp = false);
ConsumerBase构造一个新的ConsumerBase对象来消费来自给定的IGraphicBufferConsumer的图像缓冲区。controlledByApp标志表明该消费者处于应用程序的控制之下。
最后看下构造函数里的具体内容:
ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue, bool controlledByApp) :
mAbandoned(false),
mConsumer(bufferQueue),
mPrevFinalReleaseFence(Fence::NO_FENCE) {
// Choose a name using the PID and a process-unique ID.
mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
// Note that we can't create an sp<...>(this) in a ctor that will not keep a
// reference once the ctor ends, as that would cause the refcount of 'this'
// dropping to 0 at the end of the ctor. Since all we need is a wp<...>
// that's what we create.
wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this);
sp<IConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener);
status_t err = mConsumer->consumerConnect(proxy, controlledByApp);
if (err != NO_ERROR) {
CB_LOGE("ConsumerBase: error connecting to BufferQueue: %s (%d)",
strerror(-err), err);
} else {
mConsumer->setConsumerName(mName);
}
}
1)、将上面创建的BLASTBufferQueue的成员变量mConsumer赋值给ConsumerBase的sp<IGraphicBufferConsumer>类型的成员变量mConsumer。
2)、将当前ConsumerBase转为一个ConsumerListener的弱引用,然后封装到ProxyConsumerListener中。ProxyConsumerListener是IConsumerListener的实现,保存了真正的消费者对象的弱引用。所有对ProxyConsumerListener的调用都会转为对这个消费者对象的调用。
3)、接着调用consumerConnect将消费者连接到BufferQueue。只有一个消费者可以连接,当这个消费者断开连接时,BufferQueue就会被置为“abandoned”状态,导致生产者与BufferQueue的大多数交互都失败。controlledByApp指示使用者是否被应用程序控制。
看到BufferQueueConsumer.h中的定义:
virtual status_t consumerConnect(const sp<IConsumerListener>& consumer,
bool controlledByApp) {
return connect(consumer, controlledByApp);
}
接着调用BufferQueueConsumer.connect函数:
status_t BufferQueueConsumer::connect(
const sp<IConsumerListener>& consumerListener, bool controlledByApp) {
// ......
mCore->mConsumerListener = consumerListener;
mCore->mConsumerControlledByApp = controlledByApp;
return NO_ERROR;
}
最终是将BufferQueueConsumer的sp<BufferQueueCore>类型的成员变量mCore,中的sp<IConsumerListener>类型的成员变量mConsumerListener指向了一个封装了BLASTBufferItemConsumer对象的ProxyConsumerListener对象,即完成了从BLASTBufferItemConsumer到BufferQueue的连接。
5 小结
由于对这一部分不熟悉,所以一下子出现的这么多新的类感觉有点乱,先简单总结一下各个类之间的关系:

三、Surface的初始化
回看ViewRootImpl.getOrCreateBLASTSurface方法:
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;
}
创建了一个BLASTBufferQueue对象后,接着就是调用BLASTBufferQueue.createSurface创建一个Surface对象。
1 BLASTBufferQueue.createSurface
/**
* @return a new Surface instance from the IGraphicsBufferProducer of the adapter.
*/
public Surface createSurface() {
return nativeGetSurface(mNativeObject, false /* includeSurfaceControlHandle */);
}
从适配器的IGraphicsBufferProducer处返回一个新的Surface实例。
2 android_graphics_BLASTBufferQueue.nativeGetSurface
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后,从C++层返回给Java层的BLASTBufferQueue指针,所以这里我们可以拿到上一节创建的BLASTBufferQueue对象。
接着调用BLASTBufferQueue.getSurface函数。
3 BLASTBufferQueue.getSurface
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是false,所以这里的handle为空。上面分析SurfaceControl的创建流程的时候,知道SurfaceControl保存的handle是其在SurfaceFlinger处对应的Layer的句柄。
接着创建了一个BBQSurface对象。
4 BBQSurface
class BBQSurface : public Surface {
private:
sp<BLASTBufferQueue> mBbq;
public:
BBQSurface(const sp<IGraphicBufferProducer>& igbp, bool controlledByApp,
const sp<IBinder>& scHandle, const sp<BLASTBufferQueue>& bbq)
: Surface(igbp, controlledByApp, scHandle), mBbq(bbq) {}
// ......
}
BBQSurface继承Surface,内部有一个sp<BLASTBufferQueue>类型的成员变量mBbq指向一个BLASTBufferQueue对象。还是要去看Surface的构造函数。
5 Surface
1)、Surface类继承ANativeObjectBase:
/*
* An implementation of ANativeWindow that feeds graphics buffers into a
* BufferQueue.
*
* This is typically used by programs that want to render frames through
* some means (maybe OpenGL, a software renderer, or a hardware decoder)
* and have the frames they create forwarded to SurfaceFlinger for
* compositing. For example, a video decoder could render a frame and call
* eglSwapBuffers(), which invokes ANativeWindow callbacks defined by
* Surface. Surface then forwards the buffers through Binder IPC
* to the BufferQueue's producer interface, providing the new frame to a
* consumer such as GLConsumer.
*/
class Surface
: public ANativeObjectBase<ANativeWindow, Surface, RefBase>
{
一个ANativeWindow的实现,它将图形缓冲区提供给BufferQueue。
这通常是由想要通过一些方法(可能是OpenGL,软件渲染器,或硬件解码器)渲染帧的程序使用,并且这些程序拥有它们创建的并且可以转发到SurfaceFlinger进行合成的帧。例如,视频解码器可以渲染一帧并调用eglSwapBuffers(),这个函数调用由Surface定义的ANativeWindow回调。然后,Surface通过Binder IPC将缓冲区转发到BufferQueue的生产者接口,并向GLConsumer等消费者提供新的帧。
再看到ANativeObjectBase的定义:
/*
* This helper class turns a ANativeXXX object type into a C++
* reference-counted object; with proper type conversions.
*/
template <typename NATIVE_TYPE, typename TYPE, typename REF,
typename NATIVE_BASE = android_native_base_t>
class ANativeObjectBase : public NATIVE_TYPE, public REF
{
那么这里NATIVE_TYPE的是ANativeWindow,即Surface实际继承的是ANativeWindow。
2)、再看Surface构造函数的定义:
/*
* creates a Surface from the given IGraphicBufferProducer (which concrete
* implementation is a BufferQueue).
*
* Surface is mainly state-less while it's disconnected, it can be
* viewed as a glorified IGraphicBufferProducer holder. It's therefore
* safe to create other Surfaces from the same IGraphicBufferProducer.
*
* However, once a Surface is connected, it'll prevent other Surfaces
* referring to the same IGraphicBufferProducer to become connected and
* therefore prevent them to be used as actual producers of buffers.
*
* the controlledByApp flag indicates that this Surface (producer) is
* controlled by the application. This flag is used at connect time.
*
* Pass in the SurfaceControlHandle to store a weak reference to the layer
* that the Surface was created from. This handle can be used to create a
* child surface without using the IGBP to identify the layer. This is used
* for surfaces created by the BlastBufferQueue whose IGBP is created on the
* client and cannot be verified in SF.
*/
explicit Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp = false,
const sp<IBinder>& surfaceControlHandle = nullptr);
从给定的IGraphicBufferProducer(具体实现是BufferQueue)创建一个Surface。
当它断开连接时,Surface主要是无状态的,它可以被视为美化的IGraphicBufferProducer持有者。因此,从同一个IGraphicBufferProducer中创建其他Surface是安全的。
然而,一旦一个Surface被连接,它将阻止其他引用相同的IGraphicBufferProducer的Surface被连接,从而防止它们被用作缓冲区的实际生产者。
controlledByApp标志表示这个Surface(生产者)由应用程序控制。此标志在连接时使用。
传入SurfaceControlHandle来存储创建Surface的Layer的弱引用。这个句柄可以用来创建子Surface,而不用IGBP来识别Layer。这用于由BlastBufferQueue创建的Surface,它的IGBP是在客户端创建的,不能在SF中验证。
3)、最后看下Surface的构造函数的具体内容:
Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp,
const sp<IBinder>& surfaceControlHandle)
: mGraphicBufferProducer(bufferProducer),
mCrop(Rect::EMPTY_RECT),
mBufferAge(0),
mGenerationNumber(0),
mSharedBufferMode(false),
mAutoRefresh(false),
mAutoPrerotation(false),
mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT),
mSharedBufferHasBeenQueued(false),
mQueriedSupportedTimestamps(false),
mFrameTimestampsSupportsPresent(false),
mEnableFrameTimestamps(false),
mFrameEventHistory(std::make_unique<ProducerFrameEventHistory>()) {
// ......
mSurfaceControlHandle = surfaceControlHandle;
}
这里传入的bufferProduer参数是BLASTBufferQueue的sp<IGraphicBufferProducer>类型的成员变量mProducer。
然后将成员变量mSurfaceControlHandle指向传入的surfaceControlHandle。
// Reference to the SurfaceFlinger layer that was used to create this
// surface. This is only populated when the Surface is created from
// a BlastBufferQueue.
sp<IBinder> mSurfaceControlHandle;
但是根据我们分析的这个流程,这里传入的surfaceControlHandle应该为空。
6 android_view_Surface.android_view_Surface_createFromSurface
回到android_graphics_BLASTBufferQueue.nativeGetSurface:
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));
}
此时我们已经通过BLASTBufferQueue.getSurface创建了一个新的Surface对象,接着调用android_view_Surface_createFromSurface函数:
jobject android_view_Surface_createFromSurface(JNIEnv* env, const sp<Surface>& surface) {
jobject surfaceObj = env->NewObject(gSurfaceClassInfo.clazz,
gSurfaceClassInfo.ctor, (jlong)surface.get());
// ......
return surfaceObj;
}
这里创建了Java层的Surface,将Surface的指针地址转化为了一个Java的long型,因此调用的是Surface的如下构造方法:
/* called from android_view_Surface_createFromIGraphicBufferProducer() */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
private Surface(long nativeObject) {
synchronized (mLock) {
setNativeObjectLocked(nativeObject);
}
}
最终调用Surface.setNativeObjectLocked将C++层的Surface的地址保存在了Java层的Surface的mNativeObject中。
7 Surface.transferFrom
再次回到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);
}
}
// ......
} else {
destroySurface();
}
// ......
}
此时经过ViewRootImpl.getOrCreateBLASTSurface方法,我们得到了一个Surface对象,接着调用Surface.transferFrom:
/**
* This is intended to be used by {@link SurfaceView#updateWindow} only.
* @param other access is not thread safe
* @hide
* @deprecated
*/
@Deprecated
@UnsupportedAppUsage
public void transferFrom(Surface other) {
if (other == null) {
throw new IllegalArgumentException("other must not be null");
}
if (other != this) {
final long newPtr;
synchronized (other.mLock) {
newPtr = other.mNativeObject;
other.setNativeObjectLocked(0);
}
synchronized (mLock) {
if (mNativeObject != 0) {
nativeRelease(mNativeObject);
}
setNativeObjectLocked(newPtr);
}
}
}
很简单,将other的mNativeObject赋值给当前Surface,并且将other的mNativeObject置为0,将other无效化。
8 小结

1)、Surface的创建的时候接受BLASTBufferQueue对象和BLASTBufferQueue的mProducer成员变量为参数,这使得Surface与BufferQueue建立起了关系。
2)、Surface与SurfaceControl关系的建立应该是靠它的成员变量mSurfaceControlHandle,通过这个句柄它可以和SurfaceControl指向同一个Layer图层,但是我们分析的这个流程,最终Surface初始化后mSurfaceControlHandle仍然为空,这一点暂时还不太懂是什么情况。