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。
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仍然为空,这一点暂时还不太懂是什么状况。