通过前面的知识我们知道了,Android 系统从按下开机键到桌面,从桌面点击 App 图标到 Activity 显示的过程。但是 Activity 是怎么显示在屏幕上的呢?下面我们就来讨论下这一过程。

SurfaceFlinger 启动过程

SurfaceFlinger 进程是由 init 进程创建的,运行在独立的 SurfaceFlinger 进程中。init 进程读取 init.rc 文件启动 SurfaceFlinger。

service surfaceflinger /system/bin/surfaceflingerclass coreuser systemgroup graphics drmrpconrestart restart zygotewritepid /dev/cpuset/system-background/tasks

SurfaceFlinger 的创建会执行 main() 方法:
main_surfaceflinger.cpp

int main(int, char**) {ProcessState::self()->setThreadPoolMaxThreadCount(4);sp<ProcessState> ps(ProcessState::self());ps->startThreadPool();//实例化 surfaceflingersp<SurfaceFlinger> flinger =  new SurfaceFlinger();setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);set_sched_policy(0, SP_FOREGROUND);//初始化flinger->init();//发布 surface flinger,注册到 ServiceManagersp<IServiceManager> sm(defaultServiceManager());sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);// 运行在当前线程flinger->run();return 0;
}

SurfaceFlinger 的实例化会执行到:onFirstRef()

void SurfaceFlinger::onFirstRef() {mEventQueue.init(this);
}

onFirstRef() 中会创建 Handler 并初始化。
MessageQueue.cpp:

void MessageQueue::init(const sp<SurfaceFlinger>& flinger) {mFlinger = flinger;mLooper = new Looper(true);mHandler = new Handler(*this);
}

然后会执行到 SurfaceFlinger::init():

void SurfaceFlinger::init() {Mutex::Autolock _l(mStateLock);//初始化 EGL,作为默认的显示mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);eglInitialize(mEGLDisplay, NULL, NULL);// 初始化硬件 composer 对象mHwc = new HWComposer(this, *static_cast<HWComposer::EventHandler *>(this));//获取 RenderEngine 引擎mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID());//检索创建的 EGL 上下文mEGLContext = mRenderEngine->getEGLContext();//初始化非虚拟显示屏for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);//建立已连接的显示设备if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {bool isSecure = true;createBuiltinDisplayLocked(type);wp<IBinder> token = mBuiltinDisplays[i];sp<IGraphicBufferProducer> producer;sp<IGraphicBufferConsumer> consumer;//创建 BufferQueue 的生产者和消费者BufferQueue::createBufferQueue(&producer, &consumer,new GraphicBufferAlloc());sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i, consumer);int32_t hwcId = allocateHwcDisplayId(type);//创建显示设备sp<DisplayDevice> hw = new DisplayDevice(this,type, hwcId, mHwc->getFormat(hwcId), isSecure, token,fbs, producer,mRenderEngine->getEGLConfig());if (i > DisplayDevice::DISPLAY_PRIMARY) {hw->setPowerMode(HWC_POWER_MODE_NORMAL);}mDisplays.add(token, hw);}}getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);//当应用和 sf 的 vsync 偏移量一致时,则只创建一个 EventThread 线程if (vsyncPhaseOffsetNs != sfVsyncPhaseOffsetNs) {sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,vsyncPhaseOffsetNs, true, "app");mEventThread = new EventThread(vsyncSrc);sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,sfVsyncPhaseOffsetNs, true, "sf");mSFEventThread = new EventThread(sfVsyncSrc);mEventQueue.setEventThread(mSFEventThread);} else {//创建 DispSyncSource 对象sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,vsyncPhaseOffsetNs, true, "sf-app");//创建线程 EventThreadmEventThread = new EventThread(vsyncSrc);//设置 EventThreadmEventQueue.setEventThread(mEventThread);}//创建 EventControlmEventControlThread = new EventControlThread(this);mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);//当不存在 HWComposer 时,则设置软件 vsyncif (mHwc->initCheck() != NO_ERROR) {mPrimaryDispSync.setPeriod(16666667);}//初始化绘图状态mDrawingState = mCurrentState;//初始化显示设备initializeDisplays();//启动开机动画startBootAnim();
}

该方法主要功能是:

1.初始化 EGL
2.创建 HWComposer
3.初始化非虚拟显示屏
4.启动 EventThread 线程
5.启动开机动画
6.创建 HWComposer:

HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger, EventHandler& handler):mFlinger(flinger), mFbDev(0), mHwc(0), mNumDisplays(1), mCBContext(new cb_context), mEventHandler(handler), mDebugForceFakeVSync(false) {...bool needVSyncThread = true;int fberr = loadFbHalModule(); //加载 framebuffer 的 HAL 层模块loadHwcModule(); //加载 HWComposer 模块//标记已分配的 display IDfor (size_t i=0 ; i<NUM_BUILTIN_DISPLAYS ; i++) {mAllocatedDisplayIDs.markBit(i);}if (mHwc) {if (mHwc->registerProcs) {mCBContext->hwc = this;mCBContext->procs.invalidate = &hook_invalidate;//VSYNC 信号的回调方法mCBContext->procs.vsync = &hook_vsync;if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))mCBContext->procs.hotplug = &hook_hotplug;elsemCBContext->procs.hotplug = NULL;memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));//注册回调函数mHwc->registerProcs(mHwc, &mCBContext->procs);}//进入此处,说明已成功打开硬件 composer 设备,则不再需要 vsync 线程needVSyncThread = false;eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);...}...if (needVSyncThread) {//不支持硬件的 VSYNC,则会创建线程来模拟定时 VSYNC 信号mVSyncThread = new VSyncThread(*this);}
}

HWComposer 代表着硬件显示设备,注册了 VSYNC 信号的回调。VSYNC 信号本身是由显示驱动产生的,在不支持硬件的 VSYNC,则会创建“VSyncThread”线程来模拟定时 VSYNC 信号。

当硬件产生VSYNC信号时,则会发送消息,handler 收到消息进行处理。当 SurfaceFlinger 进程收到 VSync 信号后经层层调用,最终调用到该对象的 handleMessageRefresh() 方法。

SurfaceFlinger.cpp:

void SurfaceFlinger::handleMessageRefresh() {ATRACE_CALL();preComposition();//处理显示设备与 layers 的改变,更新光标rebuildLayerStacks();//重建所有可见 Layer 列表,根据Z轴排序setUpHWComposer();//更新 HWComposer 图层doDebugFlashRegions(); doComposition();//生成 OpenGL 纹理图像postComposition();//将图像传递到物理屏幕
}

Surface 创建过程

Surface 创建的过程就是 Activity 显示的过程,在 ActivityThread.handleResumeActivity() 中调用了 Activity.makeVisible(),我们接着看下 Activity 是怎么显示出来的。

Activity.makeVisible:

void makeVisible() {if (!mWindowAdded) {ViewManager wm = getWindowManager();//此处 getWindowManager 获取的是 WindowManagerImpl 对象wm.addView(mDecor, getWindow().getAttributes());mWindowAdded = true;}mDecor.setVisibility(View.VISIBLE);
}

WindowManagerImpl.java:

public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {applyDefaultToken(params);mGlobal.addView(view, params, mDisplay, mParentWindow);
}

WindowManagerGlobal.java:

public void addView(View view, ViewGroup.LayoutParams params, Display display, Window parentWindow) {...final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;//创建 ViewRootImplViewRootImpl root = new ViewRootImpl(view.getContext(), display);view.setLayoutParams(wparams);mViews.add(view);mRoots.add(root);mParams.add(wparams);//设置 Viewroot.setView(view, wparams, panelParentView);...
}

创建 ViewRootImpl:public final class ViewRootImpl implements ViewParent,
        View.AttachInfo.Callbacks, ThreadedRenderer.DrawCallbacks {
    ...
    final Surface mSurface = new Surface(); //创建 Surface,此时 Surface 创建完什么都没有,详见下面分析
 

    public ViewRootImpl(Context context, Display display) {mContext = context;//获取 IWindowSession 的代理类mWindowSession = WindowManagerGlobal.getWindowSession();mDisplay = display;mThread = Thread.currentThread(); //主线程mWindow = new W(this);mChoreographer = Choreographer.getInstance();...}
}

WindowManagerGlobal.java:

public static IWindowSession getWindowSession() {synchronized (WindowManagerGlobal.class) {if (sWindowSession == null) {try {//获取 IMS 的代理类InputMethodManager imm = InputMethodManager.getInstance();//获取 WMS 的代理类IWindowManager windowManager = getWindowManagerService();//经过 Binder 调用,最终调用 WMSsWindowSession = windowManager.openSession(new IWindowSessionCallback.Stub() {...},imm.getClient(), imm.getInputContext());} catch (RemoteException e) {...}}return sWindowSession}
}

WindowManagerService.openSession:

public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client, IInputContext inputContext) {//创建 Session 对象Session session = new Session(this, callback, client, inputContext);return session;
}

再次经过 Binder 将数据写回 app 进程,则获取的便是 Session 的代理对象 IWindowSession。

创建完 ViewRootImpl 对象后,接下来调用该对象的 setView() 方法。
ViewRootImpl:

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {synchronized (this) {requestLayout(); //详见下面分析...//通过 Binder调用,进入 system 进程的 Sessionres = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,getHostVisibility(), mDisplay.getDisplayId(),mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,mAttachInfo.mOutsets, mInputChannel);...}
}
final class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, InputChannel outInputChannel) {//调用 WMS.addWindowreturn mService.addWindow(this, window, seq, attrs, viewVisibility, displayId,outContentInsets, outStableInsets, outOutsets, outInputChannel);}
}

WindowManagerService.java:

public int addWindow(Session session, IWindow client, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, InputChannel outInputChannel) {...WindowToken token = mTokenMap.get(attrs.token);//创建 WindowStateWindowState win = new WindowState(this, session, client, token,attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);...//调整 WindowManager 的 LayoutParams 参数mPolicy.adjustWindowParamsLw(win.mAttrs);res = mPolicy.prepareAddWindowLw(win, attrs);addWindowToListInOrderLocked(win, true);// 设置 inputmInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);//详见下面分析win.attach();mWindowMap.put(client.asBinder(), win);if (win.canReceiveKeys()) {//当该窗口能接收按键事件,则更新聚焦窗口focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,false /*updateInputWindows*/);}assignLayersLocked(displayContent.getWindowList());...
}//WindowState.java
void attach() {mSession.windowAddedLocked();
}

创建 SurfaceSession 对象,并将当前 Session 添加到 WMS.mSessions 成员变量。
Session.java:

void windowAddedLocked() {if (mSurfaceSession == null) {mSurfaceSession = new SurfaceSession();mService.mSessions.add(this);if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {mService.dispatchNewAnimatorScaleLocked(this);}}mNumWindow++;
}

SurfaceSession 的创建会调用 JNI,在 JNI 调用 nativeCreate()。
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() {//getComposerService() 将返回 SF 的 Binder 代理端的 BpSurfaceFlinger 对象sp<ISurfaceComposer> sm(getComposerService());//先调用 SF 的 createConnection(),再调用_init_init(sm, sm->createConnection());if(mClient != 0) {Mutex::Autolock _l(gLock);//gActiveConnections 是全局变量,把刚才创建的 client 保存到这个 map 中去gActiveConnections.add(mClient->asBinder(), this);}
}

SurfaceFlinger.cpp:

sp<ISurfaceFlingerClient>SurfaceFlinger::createConnection() {Mutex::Autolock _l(mStateLock);uint32_t token = mTokens.acquire();//先创建一个Clientsp<Client> client = new Client(token, this);//把这个Client对象保存到mClientsMap中,token是它的标识。status_t err = mClientsMap.add(token, client);/*创建一个用于 Binder 通信的 BClient,BClient 派生于 ISurfaceFlingerClient,它的作用是接受客户端的请求,然后把处理提交给 SF,注意,并不是提交给 Client。Client 会创建一块共享内存,该内存由 getControlBlockMemory 函数返回。*/sp<BClient> bclient = new BClient(this, token,client->getControlBlockMemory());return bclient;
}Client::Client(ClientID clientID, constsp<SurfaceFlinger>& flinger):ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger) {
const int pgsize = getpagesize();//下面这个操作会使 cblksize 为页的大小,目前是4096字节constint cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));mCblkHeap = new MemoryHeapBase(cblksize, 0, "SurfaceFlinger Clientcontrol-block");ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());if(ctrlblk) {new(ctrlblk) SharedClient;//原来 Surface 的 CB 对象就是在共享内存中创建的这个 SharedClient 对象}
}

SharedClient:

class SharedClient {public:SharedClient();~SharedClient();status_t validate(size_t token) const;uint32_t getIdentity(size_t token) const;private:Mutexlock;Condition cv; //支持跨进程的同步对象//NUM_LAYERS_MAX 为 31,SharedBufferStack 是什么?SharedBufferStack surfaces[ NUM_LAYERS_MAX ];};//SharedClient的构造函数,没什么新意,不如Audio的CB对象复杂
SharedClient::SharedClient():lock(Mutex::SHARED), cv(Condition::SHARED) {
}

一个 Client 最多支持 31 个显示层。每一个显示层的生产/消费步调都由会对应的 SharedBufferStack 来控制。而它内部就用了几个成员变量来控制读写位置。

SharedBufferStack.h:

class  SharedBufferStack{......//Buffer 是按块使用的,每个 Buffer 都有自己的编号,其实就是数组中的索引号。volatile int32_t head;     //FrontBuffer 的编号volatile int32_t available; //空闲 Buffer 的个数volatile int32_t queued;  //脏 Buffer 的个数,脏 Buffer 表示有新数据的 Buffervolatile int32_t inUse; //SF 当前正在使用的 Buffer 的编号   volatilestatus_t status; //状态码......}

SF 的一个 Client 分配一个跨进程共享的 SharedClient 对象。这个对象有31个 SharedBufferStack 元素,每一个 SharedBufferStack 对应于一个显示层。

一个显示层将创建两个 Buffer,后续的 PageFlipping 就是基于这两个 Buffer 展开的。

接着看 SurfaceComposerClient 中这个_init函数:

void SurfaceComposerClient::_init(const sp<ISurfaceComposer>& sm, constsp<ISurfaceFlingerClient>& conn) {mPrebuiltLayerState = 0;mTransactionOpen = 0;mStatus = NO_ERROR;mControl = 0;mClient = conn;// mClient 就是 BClient 的客户端mControlMemory =mClient->getControlBlock();mSignalServer = sm;// mSignalServer 就是 BpSurfaceFlinger//mControl 就是那个创建于共享内存之中的 SharedClientmControl = static_cast<SharedClient*>(mControlMemory->getBase());
}

创建完 ViewRootImpl 对象后,接下来调用该对象的 setView() 方法。在 setView() 中调用了 requestLayout() 方法我们来看下这个方法:

public void requestLayout() {checkThread();mLayoutRequested = true;scheduleTraversals();
}public void scheduleTraversals() {if(!mTraversalScheduled) {mTraversalScheduled = true;sendEmptyMessage(DO_TRAVERSAL); //发送 DO_TRAVERSAL 消息}
}public void handleMessage(Message msg) {switch (msg.what) {......case DO_TRAVERSAL:......performTraversals();//调用 performTraversals()......break;......}
}private void performTraversals() {finalView host = mView;//还记得这mView吗?它就是 DecorViewbooleaninitialized = false;booleancontentInsetsChanged = false;booleanvisibleInsetsChanged;try {relayoutResult= // 1. 关键函数relayoutWindowrelayoutWindow(params, viewVisibility,insetsPending);}......draw(fullRedrawNeeded);// 2. 开始绘制......
}private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility, boolean insetsPending)throws RemoteException {//原来是调用 IWindowSession 的 relayout(),暂且记住这个调用int relayoutResult = sWindowSession.relayout(mWindow, params, (int) (mView.mMeasuredWidth * appScale + 0.5f),  (int) (mView.mMeasuredHeight * appScale + 0.5f), viewVisibility, insetsPending, mWinFrame, mPendingContentInsets, mPendingVisibleInsets, mPendingConfiguration, mSurface); //mSurface 做为参数传进去了。}......
}private void draw(boolean fullRedrawNeeded) {Surface surface = mSurface;//mSurface 是 ViewRoot 的成员变量......Canvascanvas;try {int left = dirty.left;int top = dirty.top;int right = dirty.right;int bottom = dirty.bottom;//从 mSurface 中 lock 一块 Canvascanvas = surface.lockCanvas(dirty);......mView.draw(canvas);//调用 DecorView 的 draw 函数,canvas 就是画布......//unlock 画布,屏幕上马上就能看到 View 的样子了surface.unlockCanvasAndPost(canvas);}......
}

在 ViewRoot 构造时,会创建一个 Surface,它使用无参构造函数,代码如下所示:

final Surface mSurface = new Surface();
1
此时创建完的 Surface 是空的,什么都没有。接着继续分析 relayoutWindow(),在 relayoutWindow() 中会调用 IWindowSession 的 relayout(),这是一个跨进程方法会调用到 WMS 中的 Session.relayout(),最后调用到 WindowManagerService.relayoutWindow()。

public int relayoutWindow(Session session,IWindow client,WindowManager.LayoutParams attrs, int requestedWidth,int requestedHeight, int viewVisibility, boolean insetsPending,Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,Configuration outConfig, SurfaceoutSurface){.....try {//win 就是 WinState,这里将创建一个本地的 Surface 对象Surfacesurface = win.createSurfaceLocked();if(surface != null) {//先创建一个本地 surface,然后在 outSurface 的对象上调用 copyFrom//将本地 Surface 的信息拷贝到 outSurface 中,为什么要这么麻烦呢?outSurface.copyFrom(surface);......
}

WindowManagerService.java::WindowState:

Surface createSurfaceLocked() {......try {//mSurfaceSession 就是在 Session 上创建的 SurfaceSession 对象//这里,以它为参数,构造一个新的 Surface 对象mSurface = new Surface(mSession.mSurfaceSession, mSession.mPid, mAttrs.getTitle().toString(), 0, w, h, mAttrs.format, flags);}Surface.openTransaction();//打开一个事务处理......Surface.closeTransaction();//关闭一个事务处理......
}

构造 Surface 对象:

 public Surface(SurfaceSession s,//传入一个SurfaceSession对象int pid, String name, int display, int w, int h, int format, int flags) throws OutOfResourcesException {......mCanvas = new CompatibleCanvas();//又一个 native 函数init(s,pid,name,display,w,h,format,flags);mName = name;}
static void Surface_init(JNIEnv*env, jobject clazz, jobject session, jint pid, jstring jname, jint dpy, jint w, jint h, jint format, jintflags) {//从 SurfaceSession 对象中取出之前创建的那个 SurfaceComposerClient 对象SurfaceComposerClient* client = (SurfaceComposerClient*)env->GetIntField(session, sso.client);sp<SurfaceControl> surface;//注意它的类型是 SurfaceControlif (jname == NULL) {//调用 SurfaceComposerClient 的 createSurface 函数,返回的 surface 是一个 SurfaceControl 类型surface = client->createSurface(pid, dpy, w, h, format, flags);} else{......}//把这个 surfaceControl 对象设置到 Java 层的 Surface 对象中setSurfaceControl(env, clazz, surface);
}

在 createSurface 内部会使用 Binder 通信将请求发给 SurfaceFlinger:

sp<ISurface>SurfaceFlinger::createSurface(ClientID clientId, int pid, const String8& name, ISurfaceFlingerClient::surface_data_t* params, DisplayID d, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) {sp<LayerBaseClient> layer;//LayerBaseClient 是 Layer 家族的基类//这里又冒出一个 LayerBaseClient 的内部类,它也叫Surfacesp<LayerBaseClient::Surface> surfaceHandle;Mutex::Autolock _l(mStateLock);//根据 clientId 找到 createConnection 时加入的那个 Client 对象sp<Client> client = mClientsMap.valueFor(clientId);......//注意这个 id,它的值表示 Client 创建的是第几个显示层//同时也表示将使用 SharedBufferStatck 数组的第 id 个元素int32_t id = client->generateId(pid);//一个 Client 不能创建多于 NUM_LAYERS_MAX 个的Layerif(uint32_t(id) >= NUM_LAYERS_MAX) {return surfaceHandle;}//根据 flags 参数来创建不同类型的显示层switch(flags & eFXSurfaceMask) {case eFXSurfaceNormal:if (UNLIKELY(flags & ePushBuffers)) {//创建 PushBuffer 类型的显示层layer = createPushBuffersSurfaceLocked(client, d, id, w, h, flags);} else {//创建 Normal 类型的显示层layer = createNormalSurfaceLocked(client, d, id, w, h, flags, format);}break;case eFXSurfaceBlur://创建 Blur 类型的显示层layer = createBlurSurfaceLocked(client, d, id, w, h, flags);break;case eFXSurfaceDim://创建 Dim 类型的显示层layer = createDimSurfaceLocked(client, d, id, w, h, flags);break;}if(layer != 0) {layer->setName(name);setTransactionFlags(eTransactionNeeded);//从显示层对象中取出一个 ISurface 对象赋值给 SurfaceHandlesurfaceHandle = layer->getSurface();if(surfaceHandle != 0) {params->token = surfaceHandle->getToken();params->identity = surfaceHandle->getIdentity();params->width = w;params->height = h;params->format = format;}}return surfaceHandle;//ISurface 的 Bn 端就是这个对象
}
sp<LayerBaseClient>SurfaceFlinger::createNormalSurfaceLocked(const sp<Client>& client, DisplayID display, int32_t id, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format) {switch(format) { //一些图像方面的参数设置,可以不去管它case PIXEL_FORMAT_TRANSPARENT:case PIXEL_FORMAT_TRANSLUCENT:format = PIXEL_FORMAT_RGBA_8888;break;case PIXEL_FORMAT_OPAQUE:format = PIXEL_FORMAT_RGB_565;break;}//创建一个 Layer 类型的对象sp<Layer> layer = new Layer(this, display,client, id);//设置 Bufferstatus_t err = layer->setBuffers(w, h, format, flags);if (LIKELY(err == NO_ERROR)) {//初始化这个新 layer 的一些状态layer->initStates(w, h, flags);//下面这个函数把这个 layer 加入到 Z 轴集合中addLayer_l(layer);}
......return layer;
}

createNormalSurfaceLocked 函数有三个关键点,它们是:

构造一个Layer对象。
调用Layer对象的setBuffers函数。
调用SF的addLayer_l函数。
当跨进程的 createSurface() 执行完返回一个 ISurface 对象,接下来会创建 SurfaceControl 对象:

SurfaceControl::SurfaceControl(const sp<SurfaceComposerClient>& client,const sp<ISurface>& surface,const ISurfaceFlingerClient::surface_data_t& data,uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)//mClient 为 SurfaceComposerClient,而 mSurface 指向跨进程 createSurface() 调用返回的 ISurface 对象:mClient(client), mSurface(surface),mToken(data.token), mIdentity(data.identity),mWidth(data.width), mHeight(data.height), mFormat(data.format),mFlags(flags){......
}

SurfaceControl 类可以看作是一个 wrapper 类,它封装了一些函数,通过这些函数可以方便地调用 mClient 或 ISurface 提供的函数。

最后会执行 copyFrom() 返回给 App 客户端:

static void Surface_copyFrom(JNIEnv* env,jobject clazz, jobject other) {//根据JNI函数的规则,clazz 是 copyFrom 的调用对象,而 other 是 copyFrom 的参数。//目标对象此时还没有设置 SurfaceControl,而源对象在前面已经创建了 SurfaceControlconstsp<SurfaceControl>& surface = getSurfaceControl(env, clazz);constsp<SurfaceControl>& rhs = getSurfaceControl(env, other);if (!SurfaceControl::isSameSurface(surface, rhs)) {//把源 SurfaceControl 对象设置到目标 Surface 中setSurfaceControl(env, clazz, rhs);}
}

copyFrom 期间一共有三个关键对象,它们分别是:

SurfaceComposerClient
SurfaceControl
Surface,这个 Surface 对象属于 Native 层,和 Java 层的 Surface 相对应
其中转移到 ViewRoot 成员变量 mSurface 中的,就是最后这个 Surface 对象了。

在 SurfaceFlinger 进程中,Client 的一个 Layer 将使用 SharedBufferStack 数组中的一个成员,并通过 SharedBufferServer 结构来控制这个成员,我们知道 SurfaceFlinger 是消费者,所以可由 SharedBufferServer 来控制数据的读取。

与之相对应,客户端的进程也会有一个对象来使用这个 SharedBufferStack,可它是通过另外一个叫 SharedBufferClient 的结构来控制的。客户端为 SurfaceFlinger 提供数据,所以可由 SharedBufferClient 控制数据的写入。

Surface 显示过程


如图所示,在 App 进程中创建 PhoneWindow 后会创建 ViewRoot。ViewRoot 的创建会创建一个 Surface,这个 Surface 其实是空的,通过与 WindowManagerService 通信 copyFrom() 一个 NativeSurface。在与 SurfaceFlinger 通信时,会创建 SharedClient 一段共享内存,里面存放的是 SharedBufferStack 对应 SurfaceFlinger 中的 SurfaceLayer 每个 Layer 其实是一个 FrameBuffer,每个 FrameBuffer 中有两个 GraphicBuffer 记作 FrontBuffer 和 BackBuffer。

在 SurfaceFlinger 中 SharedBufferServer 来管理 FrameBuffer。同时在 App 端 copyFrom() 出来 NativeSurface 时会创建一个 SharedBufferClient 与 SharedClient 这块共享内存关联。当客户端 addView() 或者需要更新 View 时,会通过 SharedBufferClient 写入数据到 ShareClient 中,SurfaceFlinger 中的 SharedBufferServer 接收到通知会将 FrameBuffer 中的数据传输到屏幕上。

HWComposer 是基于硬件来产生 VSync 信号的,来通知 SurfaceFlinger 重绘控制显示的帧率。

Android之Surface 与 SurfaceFlinger关系相关推荐

  1. 一篇文章看明白 Android 图形系统 Surface 与 SurfaceFlinger 之间的关系

    Android - SurfaceFlinger 图形系统 相关系列 一篇文章看明白 Android 系统启动时都干了什么 一篇文章了解相见恨晚的 Android Binder 进程间通讯机制 一篇文 ...

  2. Android系统Surface机制的SurfaceFlinger服务的线程模型分析

    在前面两篇文章中,我们分析了SurfaceFlinger服务的启动过程以及SurfaceFlinger服务初始化硬件帧缓冲区的过程.从这两个过程可以知道,SurfaceFlinger服务在启动的过程中 ...

  3. Android系统Surface机制的SurfaceFlinger服务渲染应用程序UI的过程分析

    出自:http://blog.csdn.net/luoshengyang/article/details/8079456 在前面的一系列文章中,我们学习了Android应用程序与SurfaceFlin ...

  4. Android系统Surface机制的SurfaceFlinger服务对帧缓冲区(Frame Buffer)的管理分析

    在前文中,我们分析了SurfaceFlinger服务的启动过程.SurfaceFlinger服务在启动的过程中,会对系统的硬件帧缓冲区进行初始化.由于系统的硬件帧缓冲区一般只有一个,并且不是谁都可以随 ...

  5. Android应用程序与SurfaceFlinger服务的关系概述和学习计划

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/7846923 SurfaceFlinger服务负 ...

  6. Android应用程序请求SurfaceFlinger服务渲染Surface的过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/7932268 在前面一篇文章中,我们分析了And ...

  7. Android应用程序请求SurfaceFlinger服务创建Surface的过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/7884628 前面我们已经学习过Android应 ...

  8. Android系统Surface机制的SurfaceFlinger服务简要介绍和学习计划

    前面我们从Android应用程序与SurfaceFlinger服务的关系出发,从侧面简单学习了SurfaceFlinger服务.有了这些预备知识之后,我们就可以从正面来分析SurfaceFlinger ...

  9. Android系统Surface机制的SurfaceFlinger服务的启动过程分析

    在前面一篇文章中,我们简要介绍了Android系统Surface机制中的SurfaceFlinger服务.SurfaceFlinger服务是在System进程中启动的,并且负责统一管理设备的帧缓冲区. ...

最新文章

  1. C语言 字符型操作(就自己做个笔记储存一下)
  2. TODO:macOS编译PHP7.1
  3. undefined reference to `__android_log_print'
  4. 我终于搞清楚了和String有关的那点事儿。
  5. 地平线后端开发实习面经
  6. java 蓝桥杯算法训练 P1102
  7. php格式化输出字_PHP 输出格式化字符串
  8. python3 解析 base64 数据
  9. 【Linux】关于Linux操作系统的配置步骤
  10. 一道求因子之和面试算法题
  11. 【ASP.NET】swfuplod图片上传
  12. Android反编译工具合集
  13. 英语每日听写练习 Day 19
  14. Pairwise(FCC算法)
  15. 雨听 | 英语学习笔记(六)~作文范文:公务员考试的热潮
  16. 深圳大学计算机刘霖,深圳大学传播学院
  17. 软件测试(四)--提交一个标准的BUG应该包含的项
  18. 设置 IIS下虚拟目录或应用程序不继承主站点的web.config
  19. 2023最新前端面试题3(持续更新)
  20. 一种电子病历系统软件框架思想——B/S与C/S混合架构

热门文章

  1. 进阶必学之微服务架构下分布式事务解决方案,你不知道的58同城
  2. 获取当前登录用户的用户名
  3. __imp____iob_func和__imp__fprintf
  4. LaTeX的正负号写法
  5. 2020十大最佳大数据分析工具,果断收藏
  6. GMS2(Gamemaker Studio 2)运行工程时遇到的问题解决
  7. 微信公众号的开发和使用注意事项有哪些?
  8. 托福高频真词List16 // 附托福TPO阅读真题
  9. HEVC帧内预测参考相邻帧代码解析
  10. 星际争霸兵种的诉苦(简略版)