首先给大家分享一个巨牛巨牛的人工智能教程,是我无意中发现的。教程不仅零基础,通俗易懂,而且非常风趣幽默,还时不时有内涵段子,像看小说一样,哈哈~我正在学习中,觉得太牛了,所以分享给大家!点这里可以跳转到教程
转自: http://blog.csdn.net/windskier/article/details/7041610
前一篇文章介绍了android的显示系统,这篇文章中,我们把视角往上层移动一下,研究一下framework是如何与surfaceflinger进行业务交互的。
1)如何创建surface
2)如何显示窗口等等
所有的这一切都是通过系统服务WindowManagerService与surfaceflinger来进行的。
Android中的Surface机制这一块代码写的比较难理解,光叫Surface的类就有3个,因此本篇文章从两部分来分析。
首先,想要理解Surface机制,还是需要首先理清各个类之间的关系。
其次,在理解了整个Surface机制的类关系之后,到时我们再结合前一篇文章中对显示系统的介绍,研究一下一个Surface是如何和显示系统建立起联系来的,这个联系主要是指Surface的显示buffer的存储管理。
在下篇文章中,再分析SurfaceFlinger是如何将已经存储了窗口图形数据的Surface Buffer显示到显示系统中。
1. Surface机制的静态关系
将这一部分叫做Surface机制,是有别于SurfaceFlinger而言的,android的图形系统中,作为C/S模型两端的WMS和SurfaceFlinger是图形系统业务的核心,但是不把WMS和SurfaceFlinger中间的这层联系搞清楚的话,是很难理解整个图形系统的,在本文中我将两者之间的这个联系关系称之为Surface机制,它的主要任务就是创建一个Surface,ViewRoot在这个Surface上描绘当前的窗口,SurfaceFlinger将这个Surface flinger(扔)给显示系统将其呈现在硬件设备上。其实这里这个Surface在不同的模块中是以不同的形态存在的,唯一不变的就是其对应的显示Buffer。
1.1 ViewRoot和WMS共享Surface
我们知道每个Activity都会有一个ViewRootImpl作为Activity Window与WMS交互的接口,ViewRootImpl会绘制整个Activity的窗口View到Surface上,因此我们在ViewRootImpl中就有了创建Surface的需求。看一下代码中的Surface的定义:
ViewRootImpl.java
// These can be accessed by any thread, must be protected with a lock. // Surface can never be reassigned or cleared (use Surface.clear()). private final Surface mSurface = new Surface();
Surface(SurfaceTexture surfaceTexture)@Surface.java
/** * Create Surface from a {@link SurfaceTexture}. * * Images drawn to the Surface will be made available to the {@link * SurfaceTexture}, which can attach them an OpenGL ES texture via {@link * SurfaceTexture#updateTexImage}. * * @param surfaceTexture The {@link SurfaceTexture} that is updated by this * Surface. */ public Surface(SurfaceTexture surfaceTexture) { if (DEBUG_RELEASE) { mCreationStack = new Exception(); } mCanvas = new CompatibleCanvas(); initFromSurfaceTexture(surfaceTexture); }
由上面可以看出在ViewRootImpl中定义的Surface只是一个空壳,那么真正的Surface是在哪里被初始化的呢?大管家WMS中!当ViewRootImpl请求WMS relayout时,会将ViewSurface中的Surface交给WMS初始化。在WMS中,对应每个WindowState对象,在relayout窗口时,同样会创建一个Surface,wms中的这个Surface会真正的初始化,然后再将这个WMS Surface复制给ViewRootImpl中的Surface。这么实现的目的就是保证ViewRootImpl和WMS共享同一个Surface。ViewRootImpl对Surface进行绘制,WMS对这个Surface进行初始化及管理。很和谐!
relayoutWindow@ViewRootImpl.java
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility, boolean insetsPending) throws RemoteException { ... int relayoutResult = sWindowSession.relayout( mWindow, mSeq, params, (int) (mView.getMeasuredWidth() * appScale + 0.5f), (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility, insetsPending, mWinFrame, mPendingContentInsets, mPendingVisibleInsets, mPendingConfiguration, mSurface); //Log.d(TAG, "<<<<<< BACK FROM relayout"); if (restore) { params.restore(); } if (mTranslator != null) { mTranslator.translateRectInScreenToAppWinFrame(mWinFrame); mTranslator.translateRectInScreenToAppWindow(mPendingContentInsets); mTranslator.translateRectInScreenToAppWindow(mPendingVisibleInsets); } return relayoutResult; }
relayoutWindow()@WindowManagerService.java
public int relayoutWindow(Session session, IWindow client, int seq, WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, boolean insetsPending, Rect outFrame, Rect outContentInsets, Rect outVisibleInsets, Configuration outConfig, Surface outSurface) { boolean displayed = false; boolean inTouchMode; boolean configChanged; // if they don't have this permission, mask out the status bar bits synchronized(mWindowMap) { WindowState win = windowFo