前言
一個(gè)窗口里面的所有的普通View都會(huì)共享一個(gè)Surface,這個(gè)Surface保存在ViewRootImpl里面捆等。但是SurfaceView不同降铸,SurfaceView自己獨(dú)享一個(gè)Surface住拭,也就意味著每次刷新SurfaceViewUI的時(shí)候潭袱,可以不必通知ViewRootImpl柱嫌,這樣會(huì)大大提高繪制效率。
當(dāng)然SurfaceView本身也是繼承View的屯换,都在一個(gè)View Hierarchy中编丘,所以自然也會(huì)遵循View的繪制流程。不過(guò)SurfaceView自身調(diào)用了setWillNotDraw(true)方法彤悔,所以本身是不會(huì)調(diào)用onDraw的嘉抓。接下來(lái)我們就開始往下探究SurfaceView的Surface到底是怎么創(chuàng)建的:
public final class ViewRootImpl implements ViewParent,
View.AttachInfo.Callbacks, ThreadedRenderer.DrawCallbacks {
private void performTraversals() {
// cache mView since it is used so much below...
final View host = mView;
...代碼省略...
if (viewVisibilityChanged) {
mAttachInfo.mWindowVisibility = viewVisibility;
host.dispatchWindowVisibilityChanged(viewVisibility);
if (viewUserVisibilityChanged) {
host.dispatchVisibilityAggregated(viewVisibility == View.VISIBLE);
}
if (viewVisibility != View.VISIBLE || mNewSurfaceNeeded) {
endDragResizing();
destroyHardwareResources();
}
if (viewVisibility == View.GONE) {
// After making a window gone, we will count it as being
// shown for the first time the next time it gets focus.
mHasHadWindowFocus = false;
}
}
...代碼省略...
}
}
ViewRootImpl#performTraversals這個(gè)方法應(yīng)該都比較熟悉了,每次View請(qǐng)求重新測(cè)量或者繪制的時(shí)候都會(huì)執(zhí)行這個(gè)方法蜗巧,另外View剛被添加到ViewTree的時(shí)候也會(huì)執(zhí)行一次。
這里當(dāng)當(dāng)前窗口的可見性發(fā)生了變化蕾盯,就會(huì)執(zhí)行host.dispatchWindowVisibilityChanged方法幕屹,這里的host是ViewRootImpl 的mView成員變量,也就是一個(gè)窗口中最頂層的View——DecorView级遭,DecorView繼承了ViewGroup望拖,自身并沒有重寫dispatchWindowVisibilityChanged方法,所以進(jìn)入ViewGroup看下:
@Override
public void dispatchWindowVisibilityChanged(int visibility) {
super.dispatchWindowVisibilityChanged(visibility);
final int count = mChildrenCount;
final View[] children = mChildren;
for (int i = 0; i < count; i++) {
children[i].dispatchWindowVisibilityChanged(visibility);
}
}
這里面就是調(diào)用了所有子View的dispatchWindowVisibilityChanged:
/**
* Dispatch a window visibility change down the view hierarchy.
* ViewGroups should override to route to their children.
*
* @param visibility The new visibility of the window.
*
* @see #onWindowVisibilityChanged(int)
*/
public void dispatchWindowVisibilityChanged(@Visibility int visibility) {
onWindowVisibilityChanged(visibility);
}
View中調(diào)用的onWindowVisibilityChanged方法挫鸽,既然我們今天的主角是SurfaceView说敏,那就去看SurfaceView是如何重寫這個(gè)方法的:
@Override
protected void onWindowVisibilityChanged(int visibility) {
super.onWindowVisibilityChanged(visibility);
mWindowVisibility = visibility == VISIBLE;
updateRequestedVisibility();
updateSurface();
}
這里需要重點(diǎn)說(shuō)下updateSurface這個(gè)核心方法:
/** @hide */
protected void updateSurface() {
//判斷SurfaceView的宿主窗口的大小是否已經(jīng)計(jì)算好了,
//SurfaceView必須在宿主窗口大小計(jì)算完畢之后才能更新
if (!mHaveFrame) {
return;
}
ViewRootImpl viewRoot = getViewRootImpl();
...代碼省略...
//檢查surfaceview是否存在變化
if (creating || formatChanged || sizeChanged || visibleChanged || windowVisibleChanged) {
getLocationInWindow(mLocation);
if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
+ "Changes: creating=" + creating
+ " format=" + formatChanged + " size=" + sizeChanged
+ " visible=" + visibleChanged
+ " left=" + (mWindowSpaceLeft != mLocation[0])
+ " top=" + (mWindowSpaceTop != mLocation[1]));
try {
...代碼省略...
if (creating) {
//創(chuàng)建SurfaceSession
mSurfaceSession = new SurfaceSession(viewRoot.mSurface);
mDeferredDestroySurfaceControl = mSurfaceControl;
updateOpaqueFlag();
通過(guò)SurfaceSession創(chuàng)建SurfaceControl
mSurfaceControl = new SurfaceControlWithBackground(mSurfaceSession,
"SurfaceView - " + viewRoot.getTitle().toString(),
mSurfaceWidth, mSurfaceHeight, mFormat,
mSurfaceFlags);
} else if (mSurfaceControl == null) {
return;
}
boolean realSizeChanged = false;
mSurfaceLock.lock();
try {
mDrawingStopped = !visible;
if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
+ "Cur surface: " + mSurface);
SurfaceControl.openTransaction();
try {
//設(shè)置Layer屬性
mSurfaceControl.setLayer(mSubLayer);
...代碼省略...
} finally {
SurfaceControl.closeTransaction();
}
if (sizeChanged || creating) {
redrawNeeded = true;
}
...代碼省略...
} finally {
mSurfaceLock.unlock();
}
try {
...代碼省略...
if (creating) {
//mSurface從mSurfaceControl中拷貝出GraphicBufferProducer
mSurface.copyFrom(mSurfaceControl);
}
...代碼省略...
} catch (Exception ex) {
Log.e(TAG, "Exception configuring surface", ex);
}
...代碼省略...
}
}
- 這里我們首先從創(chuàng)建SurfaceSession開始:
public final class SurfaceSession {
// Note: This field is accessed by native code.
private long mNativeClient; // SurfaceComposerClient*
private static native long nativeCreate();
private static native long nativeCreateScoped(long surfacePtr);
private static native void nativeDestroy(long ptr);
private static native void nativeKill(long ptr);
/** Create a new connection with the surface flinger. */
public SurfaceSession() {
mNativeClient = nativeCreate();
}
public SurfaceSession(Surface root) {
mNativeClient = nativeCreateScoped(root.mNativeObject);
}
/* no user serviceable parts here ... */
@Override
protected void finalize() throws Throwable {
try {
if (mNativeClient != 0) {
nativeDestroy(mNativeClient);
}
} finally {
super.finalize();
}
}
/**
* Forcibly detach native resources associated with this object.
* Unlike destroy(), after this call any surfaces that were created
* from the session will no longer work.
*/
public void kill() {
nativeKill(mNativeClient);
}
}
SurfaceSession本身代碼量非常少丢郊,在構(gòu)造方法中調(diào)用了nativeCreateScoped(root.mNativeObject)方法盔沫,那么就進(jìn)入對(duì)應(yīng)的cpp文件看下具體實(shí)現(xiàn):
frameworks/base/core/jni/android_view_SurfaceSession.cpp
static jlong nativeCreateScoped(JNIEnv* env, jclass clazz, jlong surfaceObject) {
Surface *parent = reinterpret_cast<Surface*>(surfaceObject);
SurfaceComposerClient* client = new SurfaceComposerClient(parent->getIGraphicBufferProducer());
client->incStrong((void*)nativeCreate);
return reinterpret_cast<jlong>(client);
}
這里創(chuàng)建了SurfaceComposerClient對(duì)象,調(diào)用了SurfaceComposerClient的父類方法IncStrong医咨,內(nèi)部會(huì)調(diào)用SurfaceComposerClient#onFirstRef方法
/frameworks/native/libs/gui/SurfaceComposerClient.cpp
void SurfaceComposerClient::onFirstRef() {
//獲取SurfacFlinger的代理BpSurfaceComposer
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
if (sf != 0 && mStatus == NO_INIT) {
auto rootProducer = mParent.promote();
sp<ISurfaceComposerClient> conn;
conn = (rootProducer != nullptr) ? sf->createScopedConnection(rootProducer) :
sf->createConnection();
if (conn != 0) {
mClient = conn;
mStatus = NO_ERROR;
}
}
}
調(diào)用BpSurfaceComposer的createScopedConnection方法,然后通過(guò)Binder調(diào)用SurfaceFlinger的createScopedConnection
sp<ISurfaceComposerClient> SurfaceFlinger::createScopedConnection(
const sp<IGraphicBufferProducer>& gbp) {
if (authenticateSurfaceTexture(gbp) == false) {
return nullptr;
}
const auto& layer = (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
if (layer == nullptr) {
return nullptr;
}
return initClient(new Client(this, layer));
}
創(chuàng)建對(duì)應(yīng)的BpSurfaceComposerClient架诞,然后將Client返回給Java層的SurfaceSession拟淮,并賦值給mNativeClient.
- 然后我們?cè)賮?lái)看下SurfaceControl的創(chuàng)建過(guò)程
mSurfaceControl = new SurfaceControlWithBackground(mSurfaceSession,
"SurfaceView - " + viewRoot.getTitle().toString(),
mSurfaceWidth, mSurfaceHeight, mFormat,
mSurfaceFlags);
咱們重新回到updateSurface方法中,此處初始化了SurfaceControl谴忧,將SurfaceSession傳進(jìn)去很泊,再來(lái)看下構(gòu)造方法里面都做了什么操作
public SurfaceControlWithBackground(SurfaceSession s,
String name, int w, int h, int format, int flags)
throws Exception {
super(s, name, w, h, format, flags);
mBackgroundControl = new SurfaceControl(s, "Background for - " + name, w, h,
PixelFormat.OPAQUE, flags | SurfaceControl.FX_SURFACE_DIM);
mOpaque = (flags & SurfaceControl.OPAQUE) != 0;
}
public SurfaceControl(SurfaceSession session,
String name, int w, int h, int format, int flags)
throws OutOfResourcesException {
this(session, name, w, h, format, flags, null, INVALID_WINDOW_TYPE, Binder.getCallingUid());
}
public SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,
SurfaceControl parent, int windowType, int ownerUid)
throws OutOfResourcesException {
if (session == null) {
throw new IllegalArgumentException("session must not be null");
}
if (name == null) {
throw new IllegalArgumentException("name must not be null");
}
if ((flags & SurfaceControl.HIDDEN) == 0) {
Log.w(TAG, "Surfaces should always be created with the HIDDEN flag set "
+ "to ensure that they are not made visible prematurely before "
+ "all of the surface's properties have been configured. "
+ "Set the other properties and make the surface visible within "
+ "a transaction. New surface name: " + name,
new Throwable());
}
mName = name;
mNativeObject = nativeCreate(session, name, w, h, format, flags,
parent != null ? parent.mNativeObject : 0, windowType, ownerUid);
if (mNativeObject == 0) {
throw new OutOfResourcesException(
"Couldn't allocate SurfaceControl native object");
}
mCloseGuard.open("release");
}
SurfaceControlWithBackground的構(gòu)造方法主要調(diào)用了父類的構(gòu)造方法,然后父類SurfaceControl中調(diào)用了nativeCreate方法沾谓,那么再次進(jìn)入C++層看下那提測(cè)Create的處理邏輯:
frameworks\native\services\surfaceflinger\ android_view_SurfaceControl.cpp
static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
jstring nameStr, jint w, jint h, jint format, jint flags, jlong parentObject,
jint windowType, jint ownerUid) {
ScopedUtfChars name(env, nameStr);
sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj));
SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject);
//client為SurfaceComposerClient對(duì)象
sp<SurfaceControl> surface;
status_t err = client->createSurfaceChecked(
String8(name.c_str()), w, h, format, &surface, flags, parent, windowType, ownerUid);
...代碼省略...
//增加SurfaceControl的引用計(jì)數(shù)
surface->incStrong((void *)nativeCreate);
//獲取IGraphicBufferProducer對(duì)象
return reinterpret_cast<jlong>(surface.get());
}
首先通過(guò)sessionObj獲取SurfaceComposerClient的代理對(duì)象BpSurfaceComposerClient委造,然后通過(guò)SurfaceComposerClient創(chuàng)建Surface
frameworks\native\libs\gui\SurfaceComposerClient.cpp
status_t SurfaceComposerClient::createSurfaceChecked(
const String8& name,
uint32_t w,
uint32_t h,
PixelFormat format,
sp<SurfaceControl>* outSurface,
uint32_t flags,
SurfaceControl* parent,
int32_t windowType,
int32_t ownerUid)
{
sp<SurfaceControl> sur;
status_t err = mStatus;
if (mStatus == NO_ERROR) {
sp<IBinder> handle;
sp<IBinder> parentHandle;
sp<IGraphicBufferProducer> gbp;
if (parent != nullptr) {
parentHandle = parent->getHandle();
}
err = mClient->createSurface(name, w, h, format, flags, parentHandle,
windowType, ownerUid, &handle, &gbp);
ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
if (err == NO_ERROR) {
*outSurface = new SurfaceControl(this, handle, gbp, true /* owned */);
}
}
return err;
}
此處mClient是在剛才創(chuàng)建SurfaceSession的時(shí)候生成的,SurfaceFlinger為BnSurfaceComposerClient創(chuàng)建的一個(gè)代理對(duì)象即BpSurfaceComposerClient對(duì)象均驶。然后調(diào)用對(duì)應(yīng)的createSurface方法昏兆,如果沒有出現(xiàn)錯(cuò)誤,那么就直接創(chuàng)建出SurfaceControl辣恋。那么我們?cè)倏聪耤reateSurface的邏輯:
frameworks\native\services\surfaceflinger\Client.cpp
status_t Client::createSurface(
const String8& name,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
const sp<IBinder>& parentHandle, int32_t windowType, int32_t ownerUid,
sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp)
{
...代碼省略...
sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),
name, this, w, h, format, flags, handle,
windowType, ownerUid, gbp, &parent);
mFlinger->postMessageSync(msg);
return static_cast<MessageCreateLayer*>( msg.get() )->getResult();
}
這里通過(guò)跨進(jìn)程的RPC通信亮垫,調(diào)用SurfaceFlinger進(jìn)程的createLayer方法:
frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp
status_t SurfaceFlinger::createLayer(
const String8& name,
const sp<Client>& client,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
int32_t windowType, int32_t ownerUid, sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp, sp<Layer>* parent)
{
...代碼省略...
status_t result = NO_ERROR;
sp<Layer> layer;
String8 uniqueName = getUniqueLayerName(name);
switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
case ISurfaceComposerClient::eFXSurfaceNormal:
result = createBufferLayer(client,
uniqueName, w, h, flags, format,
handle, gbp, &layer);
break;
case ISurfaceComposerClient::eFXSurfaceColor:
result = createColorLayer(client,
uniqueName, w, h, flags,
handle, &layer);
break;
default:
result = BAD_VALUE;
break;
}
...代碼省略...
//將client和Layer關(guān)聯(lián)起來(lái),把Layer添加到client的mLayers集合里面去
result = addClientLayer(client, *handle, *gbp, layer, *parent);
if (result != NO_ERROR) {
return result;
}
mInterceptor->saveSurfaceCreation(layer);
setTransactionFlags(eTransactionNeeded);
return result;
}
此處調(diào)用createNormalLayer創(chuàng)建layer伟骨,然后將Layer與client關(guān)聯(lián)起來(lái)饮潦。SurfaceFlinger里的Layer對(duì)應(yīng)的就是Java層的Surface。
所以初始化SurfaceControl的時(shí)候就是創(chuàng)建了一個(gè)SurfaceControl,并讓SurfaceFlinger創(chuàng)建了一個(gè)對(duì)應(yīng)的Layer携狭。
- 接下來(lái)就重新回到j(luò)ava層继蜡,再來(lái)看下初始化完SurfaceControl以后,就將SurfaceControl的GraphicBufferProducer copy給mSurface對(duì)象
if (creating) {
mSurface.copyFrom(mSurfaceControl);
}
至此逛腿,Surface就創(chuàng)建完畢了稀并,下一節(jié)再講SurfaceView是如何"挖洞"的
總結(jié)
SurfaceView創(chuàng)建Surface主要的過(guò)程如下:
- 首先創(chuàng)建SurfaceSession,這個(gè)時(shí)候返回一個(gè)SurfaceComposeClient的指針給java層
- SurfaceComposeClient在創(chuàng)建的時(shí)候单默,會(huì)獲取SurfaceFlinger的代理對(duì)象BpSurfaceComposer碘举,通過(guò)該對(duì)象在SurfaceFlinger中創(chuàng)建BnSurfaceComposerClient對(duì)象。并且將該對(duì)象創(chuàng)建BpSurfaceComposerClient對(duì)象賦值給了SurfaceComposeClient的mClient
- 然后創(chuàng)建SurfaceControl搁廓,獲取SurfaceComposeClient的代理對(duì)象BpSurfaceComposeClient,由改對(duì)象調(diào)用createSurface通過(guò)RPC通信調(diào)用到SurfaceFlinger的createSurface方法
- 創(chuàng)建Layer對(duì)象
- 將SurfaceControl拷貝給mSurface對(duì)象引颈,copy過(guò)程中創(chuàng)建對(duì)應(yīng)的Surface對(duì)象,然后將C++層的Surface賦值給Java層的Surface對(duì)象的mNativeObject