Android之Surface 与 SurfaceFlinger关系

article/2025/10/28 19:03:39

这里写图片描述

 


通过前面的知识我们知道了,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 重绘控制显示的帧率。
 


http://chatgpt.dhexx.cn/article/OdbO6Ivx.shtml

相关文章

SurfaceView、SurfaceHolder与Surface

相关文章 SurfaceView、SurfaceHolder与SurfaceTextureView、SurfaceTexture与Surface 按照官方文档的说法&#xff0c;SurfaceView继承自View&#xff0c;并提供了一个独立的绘图层&#xff0c;你可以完全控制这个绘图层&#xff0c;比如说设定它的大小&#xff0c;所以Surf…

surfaceView、surface和sufaceHolder的关系

surfaceView、surface和sufaceHolder的关系 1.SurfaceView与Surface的联系2.SurfaceView3.Surface4.SurfaceHolder 1.SurfaceView与Surface的联系 简单来说&#xff0c;Surface是管理显示内容的数据&#xff08;implementsParcelable&#xff09;&#xff0c;包括存储于数据的…

线程天敌TerminateThread与SuspendThread http://blog.csdn.net/magictong/article/details/6304439

线程天敌TerminateThread与SuspendThread 标签&#xff1a; thread null delete dll c user 2011-04-06 13:22 10295人阅读 评论(1) 收藏 举报 分类&#xff1a; C Win32&#xff08;93&#xff09; 版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得…

511遇见易语言API模块线程挂起(SuspendThread)

线程挂起用到的API是SuspendThread 511遇见易语言模块API教程 API 暂停指定的线程 函数功能&#xff1a; 挂起线程。 参数&#xff1a; 第1个参数&#xff1a; HANDLE hThread 线程句柄。 返回值&#xff1a; 成功&#xff1a;线程的前一个挂起数。 失败&#xff1a;-1。 …

面向对象设计6大原则

概览 单一职责 1、单一职责 Single Responsibility Principle&#xff0c;简称是SRP。SRP的英文定义是&#xff1a; There should never be more than one reason for a class to change. 翻译过来的意思是&#xff1a; 应该有且仅有一个原因引起类的变更。 或许我们可以…

带你了解面向对象的设计原则

##一 摘要 今天晚上给大家介绍一下面向对象的设计原则,为什么要介绍这个呢,原因很简单,大家平时所接触的语言,无论是object-C,C,JavaScrpt,C#等都是属于面向对象语言,既然是面向对象设计语言,那么就有必要去了解一下面向对象的设计原则.那么面向对象的设计原则有哪些呢?今天来…

面向对象七大设计原则

面向对象设计的七大原则 前言 在软件开发中&#xff0c;为了提高软件系统的可维护性和可复用性&#xff0c;增加软件的可扩展性和灵活性&#xff0c;我们能要尽量根据 7 条原则来开发程序&#xff0c;从而提高软件开发效率、节约软件开发成本和维护成本。 面向对象设计原则概…

软件设计与体系——面向对象设计的原则

一&#xff1a;前言 用一道题熟悉OO设计与编程&#xff1a;给定一个4位数&#xff08;数字不完全相同&#xff09;&#xff0c;这4个数字可以得到最大4位数和最小4位数&#xff0c;算它们的差&#xff0c;不是6174则重复上述过程&#xff0c;最终会得到6174&#xff0c;验证这…

面向对象设计七大原则

面向对象设计七大原则 1) 开-闭原则 &#xff08;Open Closed Principle&#xff0c;OCP&#xff09;定义开闭原则的作用实现方法例子其它例子代码 2) 里氏代换原则&#xff08;Liskov Substitutiion Principle&#xff0c;LSP&#xff09;定义作用实现方法例子 3) 依赖倒置原则…

面向对象设计六大原则

6大原则如下&#xff1a; 1)单一职责原则,一个合理的类&#xff0c;应该仅有一个引起它变化的原因&#xff0c;即单一职责,就是设计的这个类功能应该只有一个; 优点&#xff1a;消除耦合&#xff0c;减小因需求变化引起代码僵化。 2) 开-闭原则&#xff0c;讲的是设计要对扩展…

设计模式(三)——面向对象设计原则

设计模式需要遵循基本的软件设计原则。可维护性(Maintainability)和可复用性(Reusability)是衡量软件质量的重要的两个属性: 可维护性:软件能够被理解、改正、适应及扩展的难易程度可复用性:软件能够被复用的难易程度面向对象设计的原则是支持可维护性复用,一方面需要实…

程序员必备的七大面向对象设计原则(一)

花絮 每天都在和面向对象打交道&#xff0c;但是我们在应用面向对象的时候感觉自己的面向对象技术应用的很合理&#xff1f;理解的很到位&#xff1f;应用的很到位&#xff1f;用的时候恰到好处&#xff1f;用的是否符合软件的发展趋势&#xff1f; 上面很多一连串的问题&#…

面向对象设计原则之开闭原则

开闭原则是面向对象的可复用设计的第一块基石&#xff0c;它是最重要的面向对象设计原则。开闭原则由Bertrand Meyer于1988年提出&#xff0c;其定义如下&#xff1a; 开闭原则(Open-Closed Principle, OCP)&#xff1a;一个软件实体应当对扩展开放&#xff0c;对修改关闭。即…

面向对象设计模式5大基本原则

“宇宙万物之中,没有一样东西能像思想那么顽固。” 一爱默生 首先明确模式是针对面向对象的&#xff0c;它的三大特性&#xff0c;封装、继承、多态。 面向对象设计模式有5大基本原则&#xff1a;单一职责原则、开发封闭原则、依赖倒置原则、接口隔离原则、Liskov替换原…

面向对象六大设计原则

目录 1 、单一职责&#xff08;Single Responsibility Principle&#xff09; 2 、开闭原则&#xff08;Open Close Principle&#xff09; 3、里氏替换原则&#xff08;Liskov Substitution Principle&#xff09; 4、接口隔离原则&#xff08;Interface Segregation Prin…

阿里巴巴编码规范解读(六、七)-工程结构及设计规约

工程结构 应用分层 1.【推荐】 图中默认上层依赖于下层&#xff0c;箭头关系表示可直接依赖&#xff0c;如&#xff1a;开放接口层可以依赖于 Web层&#xff0c;也可以直接依赖于 Service层&#xff0c;依此类推。 开放接口层&#xff1a;可直接封装 Service 方法暴露成RPC…

面向对象设计的七大设计原则详解

面向对象的七大设计原则 文章目录 面向对象的七大设计原则简述七大原则之间的关系 一、开闭原则&#xff08;The Open-Closed Principle &#xff0c;OCP&#xff09;概念理解系统设计需要遵循开闭原则的原因开闭原则的实现方法一个符合开闭原则的设计开闭原则的相对性 二、 里…

Android Binder机制简述

一、Android binder是什么&#xff1f; Android平台上的一种跨进程通信&#xff08;IPC&#xff09;机制 从OpenBinder演化而来 从Android应用层角度来说&#xff0c;Binder是客户端和服务端进行通信的媒介 二、IPC原理 每个Android进程&#xff0c;只能运行在自己的进程所…

不得不说的Android Binder机制与AIDL

说起Android的进程间通信&#xff0c;想必大家都会不约而同的想起Android中的Binder机制。而提起Binder&#xff0c;想必也有不少同学会想起初学Android时被Binder和AIDL支配的恐惧感。但是作为一个Android开发者&#xff0c;Binder是我们必须掌握的知识。因为它是构架整个Andr…