Android的Surface的创建
ViewRootImpl管理著整個view tree。 對于ViewRootImpl.setView(),我們可以簡單的把它當做一個UI渲染操作的入口。
http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/view/WindowManagerImpl.java
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
...
//mWindowSession是一個aidl,ViewRootImpl利用它來和WindowManagerService交互
//mWindow是一個aidl,WindowManagerService可以利用這個對象與服務端交互
//mAttachInfo可以理解為是一個data bean,可以跨進程傳遞
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(), mWinFrame,
mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel);
...
}
ViewRootImpl.setView()方法會向WindowManagerService請求添加一個Window,mWindowSession.addToDisplay()跨進程最終調用到了WindowManagerService.addWindow():
http://androidxref.com/6.0.1_r10/xref/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public int addWindow(Session session, IWindow client...) {
...
//WindowState用來描述一個Window
final WindowState win = new WindowState(this, session, client, token, parentWindow,
appOp[0], seq, attrs, viewVisibility, session.mUid,
session.mCanAddInternalSystemWindow);
...
win.attach(); //會創(chuàng)建一個SurfaceSession
mWindowMap.put(client.asBinder(), win); //mWindowMap是WindowManagerService用來保存當前所有Window新的的集合
...
win.mToken.addWindow(win); //一個token下會有多個win state。 其實token與PhoneWindow是一一對應的。
...
}
http://androidxref.com/6.0.1_r10/xref/frameworks/base/services/core/java/com/android/server/wm/WindowState.java
void attach() {
if (WindowManagerService.localLOGV) Slog.v(
TAG, "Attaching " + this + " token=" + mToken
+ ", list=" + mToken.windows);
mSession.windowAddedLocked();
}
WindowState是WindowManagerService用來描述應用程序的一個Window的對象。上面注釋我標注了win.attach(),這個方法可以說是Window與SurfaceFlinger鏈接的起點,它最終會調用到Session.windowAddedLocked():
http://androidxref.com/6.0.1_r10/xref/frameworks/base/services/core/java/com/android/server/wm/Session.java
void windowAddedLocked(String packageName) {
...
if (mSurfaceSession == null) {
...
mSurfaceSession = new SurfaceSession();
...
}
}
http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/view/SurfaceSession.java
//SurfaceSession類的構造方法
public final class SurfaceSession {
private long mNativeClient; // SurfaceComposerClient*
public SurfaceSession() {
mNativeClient = nativeCreate();
}
這里調用了native方法nativeCreate(),這個方法其實是返回了一個SurfaceComposerClient指針。那這個對象是怎么創(chuàng)建的呢?
SurfaceComposerClient的創(chuàng)建
http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/jni/android_view_SurfaceSession.cpp
static jlong nativeCreate(JNIEnv* env, jclass clazz) {
SurfaceComposerClient* client = new SurfaceComposerClient(); //構造函數其實并沒有做什么
client->incStrong((void*)nativeCreate);
return reinterpret_cast<jlong>(client);
}
即構造了一個SurfaceComposerClient對象。并返回它的指針。這個對象一個應用程序就有一個,它是應用程序與SurfaceFlinger溝通的橋梁,為什么這么說呢?在SurfaceComposerClient指針第一次使用時會調用下面這個方法:
//這個方法在第一次使用SurfaceComposerClient的指針的時候會調用
void SurfaceComposerClient::onFirstRef() {
....
sp<ISurfaceComposerClient> conn;
//sf 就是SurfaceFlinger
conn = (rootProducer != nullptr) ? sf->createScopedConnection(rootProducer) :
sf->createConnection();
...
}
即通過SurfaceFlinger(它本身具有跨進程通信的能力)創(chuàng)建了一個ISurfaceComposerClient對象:
http://androidxref.com/6.0.1_r10/xref/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
return initClient(new Client(this)); //initClient這個方法其實并沒有做什么,
}
即構造了一個Client對象,Client實現了ISurfaceComposerClient接口。是一個可以跨進程通信的aidl對象。即SurfaceComposerClient可以通過它來和SurfaceFlinger通信。除此之外它還可以創(chuàng)建Surface,并且維護一個應用程序的所有Layer(下文會分析到它是什么)。它是一個十分重要的對象,我們先來看一下它的組成,它所涉及的其他東西在下文分析中都會講到:
http://androidxref.com/6.0.1_r10/xref/frameworks/native/services/surfaceflinger/Client.h
class Client : public BnSurfaceComposerClient
{
public:
...
void attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer);
void detachLayer(const Layer* layer);
...
private:
// ISurfaceComposerClient interface。 gbp很重要,它維護這一個應用程序的渲染 Buffer隊列
virtual status_t createSurface(...sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp);
virtual status_t destroySurface(const sp<IBinder>& handle);
//跨進程通信方法
virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
...
// constant
sp<SurfaceFlinger> mFlinger;
// protected by mLock
DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayers; // 一個應用程序的所有Layer
...
};
經過上面這一頓源碼分析,我們大概知道了ViewRootImpl.setView()所引發(fā)的主要操作:
WindowManagerService創(chuàng)建了一個WindowState。用來表示客戶端的一個Window
WindowManagerService創(chuàng)建了一個SurfaceSession,SurfaceSession會與SurfaceFlinger構建鏈接,創(chuàng)建了一個SurfaceComposerClient對象,一個應用程序只具有一個這個對象。
SurfaceComposerClient創(chuàng)建了一個Client, 這個對象十分重要,它維護這應用程序的渲染核心數據,并負責與SurfaceFlinger通信。
經過上面的步驟,應用程序的ViewRootImpl已經被WindowManagerService識別,并且應用程序已經與SurfaceFlinger建立連接。即創(chuàng)建了SurfaceComposerClient和Client對象
文章開始就已經說了Surface是Window(ViewRootImpl)的UI載體,那Surface是在哪里創(chuàng)建的呢?
Surface的創(chuàng)建
其實一個ViewRootImpl就對應一個Surface。
http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/view/Surface.java
這點可以通過ViewRootImpl的源碼看出:
即ViewRootImpl在構造的時候就new 了一個 Surface。但其實這個新new的Surface并沒有什么邏輯,它的構造函數是空的。
http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/view/ViewRootImpl.java
public final class ViewRootImpl implements ViewParent,
View.AttachInfo.Callbacks, HardwareRenderer.HardwareDrawCallbacks {
//...
public final Surface mSurface = new Surface();
//...
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
...
requestLayout(); //susion 請求layout。先添加到待渲染隊列中
...
res = mWindowSession.addToDisplay(mWindow, ...); //WindowManagerService會創(chuàng)建mWindow對應的WindowState
...
}
@Override
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
checkThread();
mLayoutRequested = true;
scheduleTraversals();
}
}
}
即在向WindowManagerService請求創(chuàng)建WindowState之前,調用了requestLayout(),這個方法會引起ViewRootImpl所管理的整個view tree的重新渲染。它最終會調用到scheduleTraversals():
http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/view/ViewRootImpl.java
void scheduleTraversals() {
...
mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
...
}
scheduleTraversals()會通過Choreographer來post一個mTraversalRunnable,Choreographer接收顯示系統(tǒng)的時間脈沖(垂直同步信號-VSync信號,16ms發(fā)出一次),在下一個frame渲染時控制執(zhí)行這個mTraversalRunnable。
但是mTraversalRunnable的執(zhí)行至少要在應用程序與SurfaceFlinger建立連接之后。這是因為渲染操作是由SurfaceFlinger負責調度了,如果應用程序還沒有與SurfaceFlinger創(chuàng)建連接,那SurfaceFlinger當然不會渲染這個應用程序。所以在執(zhí)行完mWindowSession.addToDisplay(mWindow, ...)之后,才會執(zhí)行mTraversalRunnable:
final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal();
}
}
doTraversal()會調用到ViewRootImpl.performTraversals(),大部分同學可能知道這個方法是一個view tree的measure/layout/draw的控制方法:
private void performTraversals() {
finalView host = mView; //mView是一個Window的根View,對于Activity來說就是DecorView
...
relayoutWindow(params, viewVisibility, insetsPending);
...
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
...
performLayout(lp, mWidth, mHeight);
...
performDraw();
...
}
Surface的具體創(chuàng)建就由relayoutWindow(params, viewVisibility, insetsPending)這個方法來完成的。這個方法會通過IPC調用到WindowManagerService.relayoutWindow():
http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/view/ViewRootImpl.java
private int relayoutWindow(WindowManager.LayoutParams params, ...) throws RemoteException {
...
int relayoutResult = mWindowSession.relayout(mWindow,..., mSurface);
...
}
mWindowSession.relayout()方法的很多參數,不過有一個十分重要的參數我沒有省略,就是mSurface。前面已經分析了它就是一個空的Surface對象。其實:
真正的Surface創(chuàng)建是由SurfaceControl完成的,應用程序ViewRootImpl的Surface只是一個指針,指向這個Surface
下面就來看一下SurfaceControl是如何創(chuàng)建Surface的:
mWindowSession.relayout()會調用到WindowManagerService.relayoutWindow():
http://androidxref.com/6.0.1_r10/xref/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
//這里的outSurface其實就是ViewRootImpl中的那個Surface
public int relayoutWindow(Session session, IWindow client....Surface outSurface){
...
result = createSurfaceControl(outSurface, result, win, winAnimator);
...
}
private int createSurfaceControl(Surface outSurface, int result, WindowState win,WindowStateAnimator winAnimator) {
...
surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type, win.mOwnerUid);
...
surfaceController.getSurface(outSurface);
}
winAnimator.createSurfaceLocked實際上是創(chuàng)建了一個SurfaceControl。即上面是先構造SurfaceControl,然后在構造Surface。
http://androidxref.com/6.0.1_r10/xref/frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java
SurfaceControl createSurfaceLocked() {
final WindowState w = mWin;
if (mSurfaceControl == null) {
//...
mSurfaceFormat = format;
if (DEBUG_SURFACE_TRACE) {
mSurfaceControl = new SurfaceTrace(
mSession.mSurfaceSession,
attrs.getTitle().toString(),
width, height, format, flags);
} else {
mSurfaceControl = new SurfaceControl(
mSession.mSurfaceSession,
attrs.getTitle().toString(),
width, height, format, flags);
}
//...
}
return mSurfaceControl;
}
SurfaceControl的創(chuàng)建
winAnimator.createSurfaceLocked其實是通過SurfaceControl的構造函數創(chuàng)建了一個SurfaceControl對象,這個對象的作用其實就是負責維護Surface,Surface其實也是由這個對象負責創(chuàng)建的,我們看一下這個對象的構造方法:
http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/view/SurfaceControl.java
long mNativeObject; //成員指針變量,指向native創(chuàng)建的SurfaceControl
private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,
SurfaceControl parent, int windowType, int ownerUid){
...
mNativeObject = nativeCreate(session, name, w, h, format, flags,
parent != null ? parent.mNativeObject : 0, windowType, ownerUid);
...
}
即調用了nativeCreate()并返回一個SurfaceControl指針:
http://androidxref.com/6.0.1_r10/xref/frameworks/native/libs/gui/SurfaceControl.cpp
static jlong nativeCreate(JNIEnv* env, ...) {
//這個client其實就是前面創(chuàng)建的SurfaceComposerClinent
sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj));
sp<SurfaceControl> surface; //創(chuàng)建成功之后,這個指針會指向新創(chuàng)建的SurfaceControl
status_t err = client->createSurfaceChecked(String8(name.c_str()), w, h, format, &surface, flags, parent, windowType, ownerUid);
...
return reinterpret_cast<jlong>(surface.get()); //返回這個SurfaceControl的地址
}
即調用到SurfaceComposerClient.createSurfaceChecked():
http://androidxref.com/6.0.1_r10/xref/frameworks/native/libs/gui/SurfaceComposerClient.cpp
//outSurface會指向新創(chuàng)建的SurfaceControl
status_t SurfaceComposerClient::createSurfaceChecked(...sp<SurfaceControl>* outSurface..)
{
sp<IGraphicBufferProducer> gbp; //這個對象很重要
...
err = mClient->createSurface(name, w, h, format, flags, parentHandle, windowType, ownerUid, &handle, &gbp);
if (err == NO_ERROR) {
//SurfaceControl創(chuàng)建成功, 指針賦值
*outSurface = new SurfaceControl(this, handle, gbp, true);
}
return err;
}
上面這個方法實際上是調用Client.createSurface()來創(chuàng)建一個Surface。在創(chuàng)建時有一個很重要的參數sp<IGraphicBufferProducer> gbp,在下面源碼分析中我們也要重點注意它。這是因為應用所渲染的每一幀,實際上都會添加到IGraphicBufferProducer中,來等待SurfaceFlinger的渲染。
http://androidxref.com/6.0.1_r10/xref/frameworks/native/services/surfaceflinger/Client.cpp
status_t Client::createSurface(...)
{
...
//gbp 直接透傳到了SurfaceFlinger
return mFlinger->createLayer(name, this, w, h, format, flags, windowType, ownerUid, handle, gbp, &parent);
}
Surface在SurfaceFlinger中對應的實體其實是Layer
我們繼續(xù)看一下mFlinger->createLayer()
http://androidxref.com/6.0.1_r10/xref/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
status_t SurfaceFlinger::createLayer(const String8& name,const sp<Client>& client...)
{
status_t result = NO_ERROR;
sp<Layer> layer; //將要創(chuàng)建的layer
switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
case ISurfaceComposerClient::eFXSurfaceNormal:
result = createBufferLayer(client,
uniqueName, w, h, flags, format,
handle, gbp, &layer); // 注意gbp,這時候還沒有構造呢!
break;
... //Layer 分為好幾種,這里不全部列出
}
...
result = addClientLayer(client, *handle, *gbp, layer, *parent); //這個layer和client相關聯, 添加到Client的mLayers集合中。
...
return result;
}
從SurfaceFlinger.createLayer()方法可以看出Layer分為好幾種。我們這里只對普通的BufferLayer的創(chuàng)建做一下分析,看createBufferLayer():
http://androidxref.com/6.0.1_r10/xref/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
status_t SurfaceFlinger::createBufferLayer(const sp<Client>& client... sp<Layer>* outLayer)
{
...
sp<BufferLayer> layer = new BufferLayer(this, client, name, w, h, flags);
status_t err = layer->setBuffers(w, h, format, flags); //設置layer的寬高
if (err == NO_ERROR) {
*handle = layer->getHandle(); //創(chuàng)建handle
*gbp = layer->getProducer(); //創(chuàng)建 gbp IGraphicBufferProducer
*outLayer = layer; //把新建的layer的指針拷貝給outLayer,這樣outLayer就指向了新建的BufferLayer
}
return err;
}
前面我說過IGraphicBufferProducer(gbp)是一個很重要的對象,它涉及到SurfaceFlinger的渲染邏輯,下面我們就看一下這個對象的創(chuàng)建邏輯:
IGraphicBufferProducer(gbp)的創(chuàng)建
sp<IGraphicBufferProducer> BufferLayer::getProducer() const {
return mProducer;
}
即mProducer其實是Layer的成員變量,它的創(chuàng)建時機是Layer第一次被使用時:
void BufferLayer::onFirstRef() {
...
BufferQueue::createBufferQueue(&producer, &consumer, true);
mProducer = new MonitoredProducer(producer, mFlinger, this);
...
}
所以mProducer的實例是MonitoredProducer,但其實它只是一個裝飾類,它實際功能都委托給構造它的參數producer:
BufferQueue.cpp
void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
...
sp<IGraphicBufferProducer> producer(new BufferQueueProducer(core, consumerIsSurfaceFlinger));
sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core)); //注意這個consumer
...
*outProducer = producer;
*outConsumer = consumer;
}
所以實際實現mProducer的工作的queueProducer是BufferQueueProducer。
所以構造一個SurfaceControl所做的工作就是創(chuàng)建了一個SurfaceControl,并讓SurfaceFlinger創(chuàng)建了一個對應的Layer,Layer中有一個IGraphicBufferProducer,它的實例是BufferQueueProducer。
可以用下面這個圖來描述SurfaceControl的創(chuàng)建過程:
從SurfaceControl中獲取Surface
我們回看WindowManagerService.createSurfaceControl(), 來看一下java層的Surface對象到底是個什么:
http://androidxref.com/6.0.1_r10/xref/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
private int createSurfaceControl(Surface outSurface, int result, WindowState win,WindowStateAnimator winAnimator) {
...
surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type, win.mOwnerUid);
...
surfaceController.getSurface(outSurface);
}
上面我們已經了解了winAnimator.createSurfaceLocked的整個過程,我們看一下surfaceController.getSurface(outSurface), surfaceController是WindowSurfaceController的實例:
//WindowSurfaceController.java
void getSurface(Surface outSurface) {
outSurface.copyFrom(mSurfaceControl);
}
//Surface.java
public void copyFrom(SurfaceControl other) {
...
long surfaceControlPtr = other.mNativeObject;
...
long newNativeObject = nativeGetFromSurfaceControl(surfaceControlPtr);
...
mNativeObject = ptr; // mNativeObject指向native創(chuàng)建的Surface
}
即Surface.copyFrom()方法調用nativeGetFromSurfaceControl()來獲取一個指針,這個指針是根據前面創(chuàng)建的SurfaceControl的指針來尋找的,即傳入的參數surfaceControlPtr:
android_view_Surface.cpp
static jlong nativeGetFromSurfaceControl(JNIEnv* env, jclass clazz, jlong surfaceControlNativeObj) {
sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj)); //把java指針轉化內native指針
sp<Surface> surface(ctrl->getSurface()); //直接構造一個Surface,指向 ctrl->getSurface()
if (surface != NULL) {
surface->incStrong(&sRefBaseOwner); //強引用
}
return reinterpret_cast<jlong>(surface.get());
}
這里的ctrl指向前面創(chuàng)建的SurfaceControl,繼續(xù)追溯ctrl->getSurface():
sp<Surface> SurfaceControl::getSurface() const
{
Mutex::Autolock _l(mLock);
if (mSurfaceData == 0) {
return generateSurfaceLocked();
}
return mSurfaceData;
}
sp<Surface> SurfaceControl::generateSurfaceLocked() const
{
//這個mGraphicBufferProducer其實就是上面分析的BufferQueueProducer
mSurfaceData = new Surface(mGraphicBufferProducer, false);
return mSurfaceData;
}
即直接new了一個nativie的Surface返回給java層,java層的Surface指向的就是native層的Surface。
所以Surface的實際創(chuàng)建可以用下圖表示:
經過上面這個圖,也可以理解SurfaceControl為什么叫SurfaceControl了。
總結
以上是生活随笔為你收集整理的Android的Surface的创建的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: reg类型变量综合电路_2014年PLD
- 下一篇: hbase集群之间数据迁移_hbase数