Surface的创建涉及三个部分:
App 进程
App需要将自己的内容显示在屏幕上,所以App负责发起Surface创建请求,创建好Surface,在canvas上设置需要显示的信息,
保存到Surface里的buffer里,最后由SurfaceFlinger合成并显示。
System_Server进程
WindowManagerService负责接收APP请求,向SurfaceFlinger发起具体的请求创建Surface
WMS需要创建Surface的辅助管理类,如SurfaceControl。
SurfaceFlinger
为App进程创建具体的Surface, 在SurfaceFlinger里对应成Layer, 然后负责管理、合成显示。
** 以Activity启动为例,surface生成过程 **
Zygote在收到启动请求的时候,会fork一个子进程,这个子进程就是app的对应的进程
它的入口函数就是ActivityThread类的main函数,这个类里面有一个handleLaunchActivity函数,它就是创建Activity的地方。
ActivityThread.java 通过反射创建了一个Activity,并且调用这个Activity的OnCreate
private void handleLaunchActivity(ActivityClientRecord r
, Intent customIntent, String reason) {
...
// 1. --- attach oncreate ---
Activity a = performLaunchActivity(r, customIntent);
...
if (a != null) {
...
// 2. --- on resume ---
handleResumeActivity(r.token, false, r.isForward
,!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
...
}
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
...
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
// 1.1 --- attach ---
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.voiceInteractor);
// 1.2 --- callActivityOnCreate调用到Activity的oncreate ---
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
r.activity = activity;
r.stopped = true;
...
mActivities.put(r.token, r);
...
return activity;
}
final void handleResumeActivity(IBinder token,
boolean clearHide, boolean isForward, boolean reallyResume) {
.......
if (r.window == null && !a.mFinished && willBeVisible) {
// r 是ActivityClinetRecord 是Activity描述的类,
// 对Activity进行了高度抽象,记录了Activity的各种信息
r.window = r.activity.getWindow();
//2.1 --- get DecorView ---
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
//2.2 --- 获得viewManager ---
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (a.mVisibleFromClient) {
a.mWindowAdded = true;
//2.3 --- 将view加入viewmanager ---
//实际调用到 WindowManagerImpl.java --在下面
wm.addView(decor, l);
}
}
}
Activity.java
ActivityThread 中调到 Activity.java
public void callActivityOnCreate(Activity activity, Bundle icicle,
PersistableBundle persistentState) {
prePerformCreate(activity);
activity.performCreate(icicle, persistentState);
postPerformCreate(activity);
}
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
//我们继承Activity 重写了onCreate,在onCreate方法里调用setContentView,
//----这个时候就会创建DecorView-----
onCreate(icicle, persistentState);
mActivityTransitionState.readState(icicle);
performCreateCommon();
}
public void setContentView(View view, ViewGroup.LayoutParams params) {
//这里的getWindow就是创建的PhoneWindow对象, 调用到 phoneWindow.setContentView()
getWindow().setContentView(view, params);
initWindowDecorActionBar();
}
public Window getWindow() {
return mWindow; //返回一个类型为Window的对象
}
//Activity创建时就创建了PhoneWindow,通过父类Window的setCallback接口让PhoneWindow保存了对Activity的引用
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, IVoiceInteractor voiceInteractor) {
......
mWindow = new PhoneWindow(this,xx,xx);
//window 与 activity 关联
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
......
//通过mToken设置了WindowManager
//--- setWindowManager由PhoneWindow父类window.java实现 ----
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
mWindowManager = mWindow.getWindowManager();
...
}
}
调用到 PhoneWinodw.java中, 由于phoneWinodw 继承winodw 所以进入 Window.java
framework/base/core/java/android/view/Window.java
public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
boolean hardwareAccelerated) {
mAppToken = appToken;
mAppName = appName;
mHardwareAccelerated = hardwareAccelerated
|| SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false);
if (wm == null) {
wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
}
//---- 进入 WindowManagerImpl.java-----------------------
mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
}
framework/base/core/java/android/view/WindowManagerImpL.java
//创建的WindowManager 是实现类 WindowManagerImpl 对象
public final class WindowManagerImpl implements WindowManager{
//获取全局对象 WindowManagerGlobal
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
private WindowManagerImpl(Display display, Window parentWindow) {
mDisplay = display;
mParentWindow = parentWindow;
}
// WindowManagerGlobal 全局对象添加 View
@Override
public void addView(View view, ViewGroup.LayoutParams params) {
mGlobal.addView(view, params, mDisplay, mParentWindow);
}
public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
return new WindowManagerImpl(mDisplay, parentWindow);
}
}
WindowManagerGlobal.java (AcvitityThread的 --2.3 --addView就调用到这里)
public final class WindowManagerGlobal {
...
private static WindowManagerGlobal sDefaultWindowManager;
private static IWindowManager sWindowManagerService;
private static IWindowSession sWindowSession;
...
public static WindowManagerGlobal getInstance() {
synchronized (WindowManagerGlobal.class) {
if (sDefaultWindowManager == null) {
sDefaultWindowManager = new WindowManagerGlobal();
}
return sDefaultWindowManager;
}
}
...
//--- 上面 AcvitityThread的 --2.3 --addView就调用到这里,开始添加View --
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
...
//---------------进入 ViewRootImpl-----------------------------
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
}
// do this last because it fires off messages to start doing things
try {
//---------------- ViewRootImpl.setView ----------------------------------------
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
// BadTokenException or InvalidDisplayException, clean up.
synchronized (mLock) {
final int index = findViewLocked(view, false);
if (index >= 0) {
removeViewLocked(index, true);
}
...
...
}
/frameworks/base/core/java/android/view/ViewRootImpl.java
public final class ViewRootImpl implements ViewParent,
View.AttachInfo.Callbacks, HardwareRenderer.HardwareDrawCallbacks {
//创建了一个 final Surface
private final Surface mSurface = new Surface();
...
static class W extends IWindow.Stub {
private final WeakReference mViewAncestor;
private final IWindowSession mWindowSession;
}
public ViewRootImpl(Context context, Display display) {
//Display.java Provides information about the size and density of a logical display.
mDisplay = display;
//IWindowSession AIDLmWindo w = new W(this); //内部W对象,实际是与window通信的AIDL static class W extends IWindow.Stub
mWindowSession = WindowManagerGlobal.getWindowSession();
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
}
public ViewRootImpl(Context context, Display display) {
mContext = context;
//Display.java Provides information about the size and density of a logical display.
mDisplay = display;
//IWindowSession AIDLmWindow = new W(this); 内部W对象,实际是与window通信的AIDL static class W extends IWindow.Stub
mWindowSession = WindowManagerGlobal.getWindowSession();
...
}
//----------------------- 主要方法 ---------------------------------------------
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
if (mView == null) {
mView = view;
...
//-------------流程1---请求layout。先添加到待渲染队列中-----------
// 调用了requestLayout(),这个方法会引起ViewRootImpl所管理的整个view tree的重新渲染。它最终会调用到scheduleTraversals():
requestLayout();
//-------------流程2---WindowManagerService创建mWindow对应的WindowState---------
//mWindowSession是一个aidl,ViewRootImpl利用它来和WindowManagerService交互
//mWindow是一个aidl,WindowManagerService可以利用这个对象与服务端交互
//mAttachInfo可以理解为是一个data bean,可以跨进程传递
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(),
mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
mAttachInfo.mOutsets, mInputChannel);
...
}
}
}
@Override
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
checkThread();
mLayoutRequested = true;
scheduleTraversals();
}
}
//---------- 判断当前是否在 UI线程 ----------------
void checkThread() {
if (mThread != Thread.currentThread()) {
throw new CalledFromWrongThreadException(
"Only the original thread that created a view hierarchy can touch its views.");
}
}
/* scheduleTraversals()会通过Choreographer来post一个mTraversalRunnable,Choreographer接收显示系统的时间脉冲(垂直同步信号-VSync信号,16ms发出一次),在下一个frame渲染时控制执行这个mTraversalRunnable。
但是mTraversalRunnable的执行至少要在应用程序与SurfaceFlinger建立连接之后。这是因为渲染操作是由SurfaceFlinger负责调度了,如果应用程序还没有与SurfaceFlinger创建连接,那SurfaceFlinger当然不会渲染这个应用程序。所以在执行完mWindowSession.addToDisplay(mWindow, ...)之后,才会执行mTraversalRunnable:*/
void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
mTraversalBarrier = mHandler.getLooper().postSyncBarrier();
// UI线程执行TraversalRunnable的run函数
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
if (!mUnbufferedInputDispatch) {
scheduleConsumeBatchedInput();
}
notifyRendererOfFramePending();
}
}
final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal();
}
}
final TraversalRunnable mTraversalRunnable = new TraversalRunnable();
void doTraversal() {
if (mTraversalScheduled) {
mTraversalScheduled = false;
mHandler.getLooper().removeSyncBarrier(mTraversalBarrier);
...
try {
//----------------------------
performTraversals();
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
...
}
}
//-----------------流程1---android 绘制的入口 -------------------------------
private void performTraversals() {
//mSurface是 surface.java 对象, final Surface mSurface = new Surface();
// surface.java 通过jni 可以操作Surface.cpp 中surface对象 Surface::Surface(
// const sp& bufferProducer,
// bool controlledByApp)
//--------------流程1.1--------加载 window -------------------------------
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
...
// Ask host how big it wants to be 计算测量
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
...
// layout
performLayout(lp, desiredWindowWidth, desiredWindowHeight);
...
// -------------流程1.2----------绘制 Draw (surface draw)----------------------
performDraw();
...
}
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
boolean insetsPending) throws RemoteException {
//通过代理 sWindowSession 调用到 WindowManagerService
//-------------------流程1-----------------------------
int relayoutResult = sWindowSession.relayout(
mWindow, params,
(int) (mView.mMeasuredWidth * appScale + 0.5f),
(int) (mView.mMeasuredHeight * appScale + 0.5f),
viewVisibility, insetsPending, mWinFrame,
mPendingContentInsets, mPendingVisibleInsets,
//------------- 重要--- 传递了创建的 mSurface
mPendingConfiguration, mSurface);
}
/frameworks/base/services/core/java/com/android/server/wm/Session.java
final class Session extends IWindowSession.Stub
implements IBinder.DeathRecipient {
final WindowManagerService mService;
final IWindowSessionCallback mCallback;
final IInputMethodClient mClient;
}
public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewFlags,
int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
//WindowManagerService
int res = mService.relayoutWindow(this, window, seq, attrs,
requestedWidth, requestedHeight, viewFlags, flags,
outFrame, outOverscanInsets, outContentInsets, outVisibleInsets,
outConfig, outSurface);
return res;
}
Surface
的具体创建就由relayoutWindow(params, viewVisibility, insetsPending)
这个方法来完成的。这个方法会通过IPC
调用到WindowManagerService.relayoutWindow()
:
/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
Surface相关的操作主要由WMS完成
//这里的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);
}
//WindowSurfaceController.java
void getSurface(Surface outSurface) {
outSurface.copyFrom(mSurfaceControl);
}
winAnimator.createSurfaceLocked
实际上是创建了一个SurfaceControl
。即上面是先构造SurfaceControl
,然后在构造Surface
。
/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;
}
winAnimator.createSurfaceLocked
其实是通过SurfaceControl
的构造函数创建了一个SurfaceControl
对象,这个对象的作用其实就是负责维护Surface
,Surface
其实也是由这个对象负责创建的
/frameworks/base/core/java/android/view/SurfaceControl.java
long mNativeObject; //存储native 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);
...
}
/frameworks/native/libs/gui/SurfaceControl.cpp
static jlong nativeCreate(JNIEnv* env, ...) {
//client- SurfaceComposerClinent
sp client(android_view_SurfaceSession_getClient(env, sessionObj));
sp surface;
//创建
status_t err = client->createSurfaceChecked(String8(name.c_str()), w, h, format, &surface, flags, parent, windowType, ownerUid);
...
//返回这个SurfaceControl的指针
return reinterpret_cast(surface.get());
}
SurfaceComposerClient对象。并返回它的指针。这个对象一个应用程序就有一个,它是应用程序与SurfaceFlinger沟通的桥梁
进入 SurfaceComposerClient.cpp
/frameworks/native/libs/gui/SurfaceComposerClient.cpp
//outSurface会指向新创建的SurfaceControl
status_t SurfaceComposerClient::createSurfaceChecked(...sp* outSurface..)
{
sp gbp; //这个对象很重要
...
err = mClient->createSurface(name, w, h, format, flags, parentHandle, windowType, ownerUid, &handle, &gbp);
if (err == NO_ERROR) {
//SurfaceControl创建成功, 指针赋值
*outSurface = new SurfaceControl(this, handle, gbp, true);
}
return err;
}
调用Client.createSurface()
来创建一个Surface
。在创建时有一个很重要的参数sp
,在下面源码分析中我们也要重点注意它。这是因为应用所渲染的每一帧,实际上都会添加到IGraphicBufferProducer
中,来等待SurfaceFlinger
的渲染。
/frameworks/native/services/surfaceflinger/Client.cpp
Client实现了ISurfaceComposerClient接口。是一个可以跨进程通信的aidl对象。即SurfaceComposerClient可以通过它来和SurfaceFlinger通信
status_t Client::createSurface(...)
{
...
//gbp 直接透传到了SurfaceFlinger
return mFlinger->createLayer(name, this, w, h, format, flags, windowType, ownerUid, handle, gbp, &parent);
}
总结
WindowManagerService创建了一个WindowState。用来表示客户端的一个Window
WindowManagerService创建了一个SurfaceSession,SurfaceSession会与SurfaceFlinger构建链接,创建了一个SurfaceComposerClient对象,一个应用程序只具有一个这个对象。
SurfaceComposerClient创建了一个Client, 这个对象十分重要,它维护这应用程序的渲染核心数据,并负责与SurfaceFlinger通信。
SurfaceFlinger可以说是Android UI渲染体系的核心,在Android系统启动时会启动SurfaceFlinger服务,它的主要作用就是被Android应用程序调用,
把绘制(测量,布局,绘制)后的窗口(Surface)渲染到手机屏幕上。
Surface
在SurfaceFlinger中对应的 实体是 Layer
mFlinger->createLayer()
/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
status_t SurfaceFlinger::createLayer(const String8& name,const sp& client...)
{
status_t result = NO_ERROR;
sp layer; //将要创建的layer
switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
case ISurfaceComposerClient::eFXSurfaceNormal:
result = createBufferLayer(client,
uniqueName, w, h, flags, format,
handle, gbp, &layer); // gbp
break;
...
}
...
result = addClientLayer(client, *handle, *gbp, layer, *parent); //这个layer和client相关联, 添加到Client的mLayers集合中。
...
return result;
}
//--------BufferLayer的创建做一下分析,看createBufferLayer():-------------
status_t SurfaceFlinger::createBufferLayer(const sp& client... sp* outLayer)
{
...
sp 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(); //创建handle
*gbp = layer->getProducer(); //创建 gbp IGraphicBufferProducer
*outLayer = layer; //把新建的layer的指针拷贝给outLayer,这样outLayer就指向了新建的BufferLayer
}
return err;
}
getProducer() 的解释说明 IGraphicBufferProducer(gbp)
是一个很重要的对象,它涉及到SurfaceFlinger
的渲染逻辑,
IGraphicBufferProducer(gbp)的创建
应用所渲染的每一帧,实际上都会添加到IGraphicBufferProducer中
sp BufferLayer::getProducer() const {
return mProducer;
}
//Layer第一次被使用时 创建 mProducer
void BufferLayer::onFirstRef() {
...
BufferQueue::createBufferQueue(&producer, &consumer, true);
// create procucer
mProducer = new MonitoredProducer(producer, mFlinger, this);
...
}
所以mProducer
的实例是MonitoredProducer
,但其实它只是一个装饰类,它实际功能都委托给构造它的参数producer
:
BufferQueue.cpp
void BufferQueue::createBufferQueue(sp* outProducer,
...
//创建 producer -> 实例是 BufferQueueProducer
sp producer(new BufferQueueProducer(core, consumerIsSurfaceFlinger));
//创建 consumer -> 实例是 BufferQueueConsumer
sp consumer(new BufferQueueConsumer(core));
...
*outProducer = producer;
*outConsumer = consumer;
}
总结:
构造一个SurfaceControl
1. Java SurfaceControl 创建一个 native SurfaceControl 并绑定
2. native SurfaceControl 获取到 client 对象 与 SurfaceFlinger 通信,创建Surface对象(实例为Layer)
3. 调用到 SurfaceFlinger 中 createBufferLayer, layer-创建重要的IGraphicBufferProducers 实例是 BufferQueueProducer 并返回 layer对象
可以用下面这个图来描述SurfaceControl
的创建过程:
所以构造一个SurfaceControl
所做的工作就是创建了一个SurfaceControl
,并让SurfaceFlinger
创建了一个对应的Layer
,Layer
中有一个IGraphicBufferProducer
,它的实例是BufferQueueProducer
。
可以用下面这个图来描述SurfaceControl
的创建过程:
从SurfaceControl中获取Surface
在上面 WindowManagerService.java 类中 调用到 getSurface
//Surface.javaSurface.copyFrom()
方法调用nativeGetFromSurfaceControl()
来获取一个指针,这个指针是根据前面创建的SurfaceControl
的指针来寻找的,即传入的参数surfaceControlPtr
:
public void copyFrom(SurfaceControl other) {
...
long surfaceControlPtr = other.mNativeObject;
...
long newNativeObject = nativeGetFromSurfaceControl(surfaceControlPtr);
...
mNativeObject = ptr; // mNativeObject指向native创建的Surface
}
android_view_Surface.cpp
static jlong nativeGetFromSurfaceControl(JNIEnv* env, jclass clazz, jlong surfaceControlNativeObj) {
sp ctrl(reinterpret_cast(surfaceControlNativeObj)); //把java指针转化内native指针
sp surface(ctrl->getSurface()); //直接构造一个Surface,指向 ctrl->getSurface()
if (surface != NULL) {
surface->incStrong(&sRefBaseOwner); //强引用
}
// 将Surface的指针返回 与 java对象绑定
return reinterpret_cast(surface.get());
}
new了一个nativie的Surface
,java层的Surface
指向的就是native层的Surface
。
sp SurfaceControl::getSurface() const
{
Mutex::Autolock _l(mLock);
if (mSurfaceData == 0) {
return generateSurfaceLocked();
}
return mSurfaceData;
}
sp SurfaceControl::generateSurfaceLocked() const
{
//这个mGraphicBufferProducer其实就是上面分析的BufferQueueProducer
mSurfaceData = new Surface(mGraphicBufferProducer, false);
return mSurfaceData;
}
所以Surface
的实际创建可以用下图表示: