結(jié)合別人的博客和自己看的代碼,梳理下自己對(duì)surface的理解
1.代碼相關(guān)文件
創(chuàng)新互聯(lián)公司擁有網(wǎng)站維護(hù)技術(shù)和項(xiàng)目管理團(tuán)隊(duì),建立的售前、實(shí)施和售后服務(wù)體系,為客戶提供定制化的成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、網(wǎng)站維護(hù)、服務(wù)器機(jī)柜租用解決方案。為客戶網(wǎng)站安全和日常運(yùn)維提供整體管家式外包優(yōu)質(zhì)服務(wù)。我們的網(wǎng)站維護(hù)服務(wù)覆蓋集團(tuán)企業(yè)、上市公司、外企網(wǎng)站、商城網(wǎng)站制作、政府網(wǎng)站等各類型客戶群體,為全球1000多家企業(yè)提供全方位網(wǎng)站維護(hù)、服務(wù)器維護(hù)解決方案。
/AOSP/frameworks/native/libs/ui
主要是bufferqueuecore與surfaceflinger中分配
GraphicBufferAllocator 通過hw_get_module()&gralloc_open與硬件提供的設(shè)備交互
ex: /hardware/qcom/display/libgralloc/alloc_controller.cpp etc.
/AOSP/frameworks/native/libs/gui
Android.mk IGraphicBufferAlloc.cpp BitTube.cpp IGraphicBufferConsumer.cpp BufferItemConsumer.cpp IGraphicBufferProducer.cpp BufferItem.cpp IProducerListener.cpp BufferQueueConsumer.cpp ISensorEventConnection.cpp BufferQueueCore.cpp ISensorServer.cpp BufferQueue.cpp ISurfaceComposerClient.cpp BufferQueueProducer.cpp ISurfaceComposer.cpp BufferSlot.cpp LayerState.cpp CleanSpec.mk Sensor.cpp ConsumerBase.cpp SensorEventQueue.cpp CpuConsumer.cpp SensorManager.cpp DisplayEventReceiver.cpp StreamSplitter.cpp GLConsumer.cpp SurfaceComposerClient.cpp GraphicBufferAlloc.cpp SurfaceControl.cpp GuiConfig.cpp Surface.cpp IConsumerListener.cpp SyncFeatures.cpp IDisplayEventConnection.cpp tests
SurfaceComposerClient 中成員變量 sp
/AOSP/frameworks/native/services/surfaceflinger
Android.mk EventControlThread.cpp MODULE_LICENSE_APACHE2 Barrier.h EventControlThread.h MonitoredProducer.cpp Client.cpp EventLog MonitoredProducer.h Client.h EventThread.cpp RenderEngine clz.h EventThread.h SurfaceFlingerConsumer.cpp Colorizer.h FrameTracker.cpp SurfaceFlingerConsumer.h DdmConnection.cpp FrameTracker.h SurfaceFlinger.cpp DdmConnection.h Layer.cpp SurfaceFlinger.h DisplayDevice.cpp LayerDim.cpp surfaceflinger.rc DisplayDevice.h LayerDim.h tests DisplayHardware Layer.h Transform.cpp DispSync.cpp main_surfaceflinger.cpp Transform.h DispSync.h MessageQueue.cpp Effects MessageQueue.h
surfaceflinger管理surface及l(fā)ayer
AOSP/frameworks/base/core/java/android/view
AbsSavedState.java MagnificationSpec.aidl accessibility MagnificationSpec.java AccessibilityInteractionController.java MenuInflater.java AccessibilityIterators.java MenuItem.java ActionMode.java Menu.java ActionProvider.java MotionEvent.aidl animation MotionEvent.java AnimationRenderStats.aidl OrientationEventListener.java Choreographer.java OrientationListener.java CollapsibleActionView.java package.html ContextMenu.java PointerIcon.aidl ContextThemeWrapper.java PointerIcon.java DisplayAdjustments.java RemotableViewMethod.java Display.aidl RenderNodeAnimator.java DisplayEventReceiver.java RenderNode.java DisplayInfo.aidl ScaleGestureDetector.java DisplayInfo.java SearchEvent.java Display.java SoundEffectConstants.java DisplayListCanvas.java SubMenu.java DragEvent.aidl Surface.aidl DragEvent.java SurfaceControl.java FallbackEventHandler.java SurfaceHolder.java FocusFinderHelper.java Surface.java FocusFinder.java SurfaceSession.java FrameInfo.java SurfaceView.java FrameStats.java textservice GestureDetector.java TextureView.java GhostView.java ThreadedRenderer.java GraphicBuffer.aidl TouchDelegate.java GraphicBuffer.java VelocityTracker.java Gravity.java ViewAnimationUtils.java HapticFeedbackConstants.java ViewConfiguration.java HardwareLayer.java ViewDebug.java HardwareRenderer.java ViewGroup.java IApplicationToken.aidl ViewGroupOverlay.java IAssetAtlas.aidl ViewHierarchyEncoder.java IGraphicsStats.aidl View.java IInputFilter.aidl ViewManager.java IInputFilterHost.aidl ViewOutlineProvider.java InflateException.java ViewOverlay.java InputChannel.aidl ViewParent.java InputChannel.java ViewPropertyAnimator.java InputDevice.aidl ViewPropertyAnimatorRT.java InputDevice.java ViewRootImpl.java InputEvent.aidl ViewStructure.java InputEventConsistencyVerifier.java ViewStub.java InputEvent.java ViewTreeObserver.java InputEventReceiver.java WindowAnimationFrameStats.aidl InputEventSender.java WindowAnimationFrameStats.java InputFilter.java WindowCallbackWrapper.java inputmethod WindowContentFrameStats.aidl InputQueue.java WindowContentFrameStats.java IOnKeyguardExitResult.aidl WindowId.java IRotationWatcher.aidl WindowInfo.aidl IWindow.aidl WindowInfo.java IWindowFocusObserver.aidl WindowInsets.java IWindowId.aidl Window.java IWindowManager.aidl WindowManager.aidl IWindowSession.aidl WindowManagerGlobal.java IWindowSessionCallback.aidl WindowManagerImpl.java KeyCharacterMap.java WindowManagerInternal.java KeyEvent.aidl WindowManager.java KeyEvent.java WindowManagerPolicy.java LayoutInflater.java
2. Activity顯示
2.1 Activity創(chuàng)建
/base/core/java/android/app/ActivityThread.java
handleLaunchActivity(ActivityClientRecord r, Intent customIntent) { ............... //根據(jù)類名以Java反射的方法創(chuàng)建一個(gè)Activity Activity a = performLaunchActivity(r, customIntent); handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed); ................}
2.2 handleResumeActivity
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume) { ..................... if (r.window == null && !a.mFinished && willBeVisible) { r.window = r.activity.getWindow(); //得到一個(gè)view對(duì)象 View decor = r.window.getDecorView(); decor.setVisibility(View.INVISIBLE); //獲得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; //將view加入viewmanager wm.addView(decor, l); } } ..................................}
2.3 Activity 通過setContentView設(shè)置UI
Activity.java
public void setContentView(View view, ViewGroup.LayoutParams params) { getWindow().setContentView(view, params); initWindowDecorActionBar(); } public Window getWindow() { return mWindow; }
上面出現(xiàn)了兩個(gè)和UI有關(guān)系的類:View和Window
2.4 Activity Window 與WindowManager
Activity.java
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, String referrer, IVoiceInteractor voiceInteractor) { //創(chuàng)建window對(duì)象 mWindow = new PhoneWindow(this); mWindow.setCallback(this); mWindow.setOnWindowDismissedCallback(this); mWindow.getLayoutInflater().setPrivateFactory(this); //創(chuàng)建windowManager mWindow.setWindowManager( (WindowManager)context.getSystemService(Context.WINDOW_SERVICE), mToken, mComponent.flattenToString(), (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0); //保存WindowManager對(duì)象 mWindowManager = mWindow.getWindowManager();
setWindowManager由PhoneWindow父類window.java實(shí)現(xiàn)
Window.java
public void setWindowManager(WindowManager wm, IBinder appToken, String appName,){ mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this); }
WindowManagerImpl.java
public WindowManagerImpl createLocalWindowManager(Window parentWindow) { return new WindowManagerImpl(mDisplay, parentWindow); } public final class WindowManagerImpl implements WindowManager {}
(2.4)中流程總結(jié)
2.5 繼續(xù)分析setContentView()
Activity.java
public void setContentView(View view, ViewGroup.LayoutParams params) { getWindow().setContentView(view, params); initWindowDecorActionBar(); }
PhoneWindow.java
private ViewGroup mContentParent; public void setContentView(View view) { setContentView(view, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); } public void setContentView(View view, ViewGroup.LayoutParams params) { //mContentParent是一個(gè)viewGroup對(duì)象 if (mContentParent == null) { installDecor(); } if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) { view.setLayoutParams(params); final Scene newScene = new Scene(mContentParent, view); transitionTo(newScene); } else { //把view加入到ViewGroup中 mContentParent.addView(view, params); } ........}
mContentParent是一個(gè)ViewGroup類型,它從View中派生,所以也是一個(gè)UI單元。從它名字中“Group”所表達(dá)的意思分析,它還可以包含其他的View元素。這又是什么意思呢?也就是說,在繪制一個(gè)ViewGroup時(shí),它不僅需要把自己的樣子畫出來,還需要把它包含的View元素的樣子也畫出來。讀者可將它想象成一個(gè)容器,容器中的元素就是View。
installDecor()函數(shù)
主要用來給view繪制icon ,window title,logo, menu等等
2.6 重回handleResumeActivity
我們之所以分析2.5內(nèi)容,是為了弄清楚View, ViewManager(就是WindowManager)這些對(duì)象
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume) { ..................... if (r.window == null && !a.mFinished && willBeVisible) { r.window = r.activity.getWindow(); //得到一個(gè)view對(duì)象 View decor = r.window.getDecorView(); decor.setVisibility(View.INVISIBLE); //獲得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; //將view加入viewmanager wm.addView(decor, l); } } ..................................}
分析wm.addView(decor,l)
WindowManagerImpl.java
public final class WindowManagerImpl implements WindowManager { private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance(); public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) { applyDefaultToken(params); mGlobal.addView(view, params, mDisplay, mParentWindow); }
WindowManagerGlobal里面可以通過AIDL與IWindowManager.Stub.asInterface 及IWindowSessionCallback.Stub() IPC通信
WindowManagerGlobal.java
public void addView(View view, ViewGroup.LayoutParams params, Display display, Window parentWindow) { root = new ViewRootImpl(view.getContext(), display); view.setLayoutParams(wparams); mViews.add(view); mRoots.add(root); mParams.add(wparams); root.setView(view, wparams, panelParentView);// TAG 1
2.6.1 ViewRootImpl又是什么東東?
ViewRootImpl.java
public final class ViewRootImpl implements ViewParent, View.AttachInfo.Callbacks, HardwareRenderer.HardwareDrawCallbacks{ final IWindowSession mWindowSession; final Display mDisplay; final DisplayManager mDisplayManager; final W mWindow; final Surface mSurface = new Surface(); static class W extends IWindow.Stub { private final WeakReferencemViewAncestor; private final IWindowSession mWindowSession;}
ViewRootImpl繼承了Handler類,看來它能處理消息。ViewRootImpl果真重寫了handleMessage函數(shù)
一個(gè)成員變量叫mSurface,它是Surface類型
surface.java public class Surface implements Parcelable {
一個(gè)W類型的mWindow和一個(gè)View類型的mView變量
ViewRootImpl有一個(gè)成員變量mSurface,它是Surface類型,它和一塊Raw Buffer有關(guān)聯(lián)。
ViewRootImpl是一個(gè)ViewParent,它的子View的繪畫操作,是在畫布Surface上展開的
ViewRootImpl的構(gòu)造
public ViewRootImpl(Context context, Display display) { mDisplay = display;//Display.java Provides information about the size and density of a logical display. mWindowSession = WindowManagerGlobal.getWindowSession(); // IWindowSession AIDLmWindo w = new W(this); //內(nèi)部W對(duì)象,實(shí)際是與window通信的AIDL static class W extends IWindow.Stub mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
WindowManagerGlobal.getWindowSession()將建立Activity的ViewRoot和WindowManagerService的關(guān)系
WindowManagerGlobal.java
public static IWindowSession getWindowSession() { IWindowManager windowManager = getWindowManagerService();//得到Iwindowmanager對(duì)象, //IWindowManager 的AIDL Bn端是WindowManagerService class WindowManagerService extends IWindowManager.Stub sWindowSession = windowManager.openSession( //然后通過AIDL得到windowsession aidl 對(duì)象 不清楚為啥已經(jīng)有了windowmanager的aidl 干嘛還需要windowsession aidl new IWindowSessionCallback.Stub() { }) } public static IWindowManager getWindowManagerService() { sWindowManagerService = IWindowManager.Stub.asInterface( ServiceManager.getService("window")); //得到WindowManager AIDL BP對(duì)象 try { sWindowManagerService = getWindowManagerService(); ValueAnimator.setDurationScale(sWindowManagerService.getCurrentAnimatorScale()); } catch (RemoteException e) {}
/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public class WindowManagerService extends IWindowManager.Stub implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {} public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client, IInputContext inputContext) { Session session = new Session(this, callback, client, inputContext); return session; }
/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;
分析完ViewRootImpl創(chuàng)建過程后,現(xiàn)在返回TAG 1處繼續(xù)分析ViewRootImpl.setView()
2.6.2 ViewRootImpl.setView()
/frameworks/base/core/java/android/view/ViewRootImpl.java
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) { // Compute surface insets required to draw at specified Z value. // TODO: Use real shadow insets for a constant max Z. if (!attrs.hasManualSurfaceInsets) { final int surfaceInset = (int) Math.ceil(view.getZ() * 2); attrs.surfaceInsets.set(surfaceInset, surfaceInset, surfaceInset, surfaceInset);} //計(jì)算Z軸坐標(biāo) requestLayout(); res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes, getHostVisibility(), mDisplay.getDisplayId(), mAttachInfo.mContentInsets, mAttachInfo.mStableInsets, mAttachInfo.mOutsets, mInputChannel);
//requestLayout()流程 TAG2 public void requestLayout() { scheduleTraversals();} void scheduleTraversals() { mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier(); mChoreographer.postCallback( Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null); notifyRendererOfFramePending(); pokeDrawLockIfNeeded();} final TraversalRunnable mTraversalRunnable = new TraversalRunnable(); //Runnable實(shí)現(xiàn)多線程,避免點(diǎn)繼承的局限,一個(gè)類可以繼承多個(gè)接口.適合于資源的共享 final class TraversalRunnable implements Runnable { @Override public void run() { doTraversal(); } } void doTraversal() { performTraversals();} private void performTraversals() { //mSurface是 surface.java 對(duì)象, final Surface mSurface = new Surface(); // surface.java 通過jni 可以操作Surface.cpp 中surface對(duì)象 Surface::Surface( // const sp& bufferProducer, // bool controlledByApp) if (mSurface.isValid()) { if (mAttachInfo.mHardwareRenderer != null) { try { hwInitialized = mAttachInfo.mHardwareRenderer.initialize(mSurface); if (hwInitialized && (host.mPrivateFlags & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) == 0) { // Don't pre-allocate if transparent regions // are requested as they may not be needed mSurface.allocateBuffers(); } } //Interface for rendering a view hierarchy using hardware acceleration. final HardwareRenderer hardwareRenderer = mAttachInfo.mHardwareRenderer; hardwareRenderer.setup(mWidth, mHeight, mAttachInfo, mWindowAttributes.surfaceInsets); }
mWindowSession.addToDisplay流程 //mWindowSession(IWindowSession) 通過AIDL 與Session.java交互 final class Session extends IWindowSession.Stub public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInset s,Rect outOutsets, InputChannel outInputChannel) { return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, outContentInsets, outStableInsets, outOutsets, outInputChannel); } final WindowManagerService mService; 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) { //windowstate A window in the window manager.class WindowState implements WindowManagerPolicy.WindowState WindowState win = new WindowState(this, session, client, token, attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent); win.attach(); } WindowState.java void attach() { mSession.windowAddedLocked();} Session.java void windowAddedLocked() { mSurfaceSession = new SurfaceSession(); mService.mSessions.add(this); mNumWindow++; }
ViewRootImpl 與WMS關(guān)系總結(jié)
ViewRootImpl通過IWindowSession和WMS進(jìn)程進(jìn)行跨進(jìn)程通信。
ViewRootImpl內(nèi)部有一個(gè)W類型的對(duì)象,它也是一個(gè)基于Binder通信的類,W是IWindow的Bn端,用于響應(yīng)請(qǐng)求。IWindow定義在另一個(gè)aidl文件IWindow.aidl中
IWindowSession
System private per-application interface to the window manager.
IWindow
API back to a client window that the Window Manager uses to inform it of interesting things happening.
IWindow.aidl
void dispatchAppVisibility(boolean visible);
void dispatchWallpaperCommand(
void dispatchDragEvent(in DragEvent event);
void dispatchWindowShown();
這里的事件指的就是按鍵、觸屏等事件。那么,一個(gè)按鍵事件是如何被分發(fā)的呢?下面是它大致的流程:WMS所在的SystemServer進(jìn)程接收到按鍵事件。WMS找到UI位于屏幕頂端的進(jìn)程所對(duì)應(yīng)的IWindow對(duì)象,調(diào)用這個(gè)IWindow對(duì)象的dispatchKey。IWindow對(duì)象的Bn端位于ViewRoot中,ViewRoot再根據(jù)內(nèi)部View的位置信息找到真正處理這個(gè)事件的View,最后調(diào)用dispatchKey函數(shù)完成按鍵的處理。(這段過程沒有去跟代碼)
2.7 Activity的UI繪制
在TAG2處分析過requestLayout。根據(jù)前面的分析可知,最終調(diào)用到performTraversals()
ViewRootImpl.java
private void performTraversals() { relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);//TAG3 performDraw();//開始繪制 } private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility, boolean insetsPending) throws RemoteException { int relayoutResult = mWindowSession.relayout( mWindow, mSeq, params, (int) (mView.getMeasuredWidth() * appScale + 0.5f), (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, mWinFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets, mPendingStableInsets, mPendingOutsets, mPendingConfiguration, mSurface); }//這個(gè)函數(shù)通過AIDL調(diào)用到WMS relayoutWindow().暫時(shí)不繼續(xù)分析 private void performDraw() { draw(fullRedrawNeeded);} private void draw(boolean fullRedrawNeeded){ mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo, this);//hw render完成draw //HardwareRenderer.java abstract void draw() }
2.8 Activity 總結(jié)
Activity的頂層View是DecorView,而我們?cè)趏nCreate函數(shù)中通過setContentView設(shè)置的View只不過是這個(gè)DecorView中的一部分罷了。DecorView是一個(gè)FrameLayout類型的ViewGroup。
Activity和UI有關(guān),它包含一個(gè)Window(真實(shí)類型是PhoneWindow)和一個(gè)WindowManager(真實(shí)類型是LocalWindowManager)對(duì)象。這兩個(gè)對(duì)象將控制整個(gè)Activity的顯示。
LocalWindowManager使用了WindowManagerImpl做為最終的處理對(duì)象(Proxy模式),這個(gè)WindowManagerImpl中有一個(gè)ViewRootImpl對(duì)象。ViewRootImpl實(shí)現(xiàn)了ViewParent接口,它有兩個(gè)重要的成員變量,一個(gè)是mView,它指向Activity頂層UI單元的DecorView,另外有一個(gè)mSurface,這個(gè)Surface包含了一個(gè)Canvas(畫布)(這個(gè)surface java對(duì)象可以通過JNI 與 surface.cpp中對(duì)象交互)。除此之外,ViewRooImplt還通過Binder系統(tǒng)和WindowManagerService進(jìn)行了跨進(jìn)程交互。
ViewRoot能處理Handler的消息,Activity的顯示就是由ViewRoot在它的performTraversals函數(shù)中完成的。
3. Surface對(duì)象
終于可以分析java與C++處surface對(duì)象了,先回憶下surface是如何創(chuàng)建的
ViewRootImpl.java final Surface mSurface = new Surface();
ViewRootImpl通過IWindowSession和WMS交互,而WMS中會(huì)調(diào)用的一個(gè)attach函數(shù),會(huì)構(gòu)造一個(gè)SurfaceSession,前面遇到過但沒有繼續(xù)分析
WindowState.java void attach() { mSession.windowAddedLocked();} Session.java void windowAddedLocked() { mSurfaceSession = new SurfaceSession(); mService.mSessions.add(this); mNumWindow++; } SurfaceSession.java //* An instance of this class represents a connection to the surface //* flinger, from which you can create one or more Surface instances that will //* be composited to the screen. public final class SurfaceSession { private static native long nativeCreate(); private static native void nativeDestroy(long ptr); private static native void nativeKill(long ptr);}
由注釋可見,surfacesession負(fù)責(zé)與SF的連接
在2.7處Activity UI 繪制時(shí),遇到過relayoutWindow(),現(xiàn)在繼續(xù)看該函數(shù)
ViewRootImpl.java
private void performTraversals() { relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);//TAG3 performDraw();//開始繪制 } private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility, boolean insetsPending) throws RemoteException { int relayoutResult = mWindowSession.relayout( mWindow, mSeq, params, (int) (mView.getMeasuredWidth() * appScale + 0.5f), (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, mWinFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets, mPendingStableInsets, mPendingOutsets, mPendingConfiguration, mSurface); }//這個(gè)函數(shù)通過AIDL調(diào)用到WMS relayoutWindow() Session.java public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,..){ int res = mService.relayoutWindow(this,....);} WindowManagerService.java public int relayoutWindow(Session session, IWindow client, int seq, WindowManager.LayoutParams attrs, int requestedWidth,....){ SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();//TAG4 創(chuàng)建本地surfacecontrol 通過JNI會(huì)調(diào)用C++最終創(chuàng)建layer, java層保存的surfacecontrol對(duì)象是一個(gè)surfaceControl.cpp 中對(duì)象 //JNI處返回的surfacecontrol //surface->incStrong((void *)nativeCreate); //return reinterpret_cast(surface.get()); outSurface.copyFrom(surfaceControl);//將本地surface拷貝到outSurface } WindowStateAnimator.java SurfaceControl createSurfaceLocked() { final WindowState w = mWin; mSurfaceControl = new SurfaceControl( mSession.mSurfaceSession, attrs.getTitle().toString(), width, height, format, flags); // Start a new transaction and apply position & offset. SurfaceControl.openTransaction(); mSurfaceControl.setLayer(mAnimLayer); mSurfaceControl.setAlpha(0); SurfaceControl.closeTransaction(); return mSurfaceControl; }
SurfaceControl是個(gè)什么對(duì)象?與Surface有何關(guān)系
/frameworks/base/core/java/android/view/SurfaceControl.java
看SurfaceControl構(gòu)造函數(shù)說明,surfacecontrol根據(jù)name創(chuàng)建surface
/** * Create a surface with a name. ** The surface creation flags specify what kind of surface to create and * certain options such as whether the surface can be assumed to be opaque * and whether it should be initially hidden. Surfaces should always be * created with the {@link #HIDDEN} flag set to ensure that they are not * made visible prematurely before all of the surface's properties have been * configured. *
* Good practice is to first create the surface with the {@link #HIDDEN} flag * specified, open a transaction, set the surface layer, layer stack, alpha, * and position, call {@link #show} if appropriate, and close the transaction. * * @param session The surface session, must not be null. * @param name The surface name, must not be null. * @param w The surface initial width. * @param h The surface initial height. * @param flags The surface creation flags. Should always include {@link #HIDDEN} * in the creation flags. * * @throws throws OutOfResourcesException If the SurfaceControl cannot be created. */ public SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags){ mNativeObject = nativeCreate(session, name, w, h, format, flags); } 通過JNI android_view_SurfaceControl.cpp static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj, jstring nameStr, jint w, jint h, jint format, jint flags) { ScopedUtfChars name(env, nameStr); sp
client(android_view_SurfaceSession_getClient(env, sessionObj)); sp surface = client->createSurface( String8(name.c_str()), w, h, format, flags); } 調(diào)用SurfaceComposiClient.cpp sp SurfaceComposerClient::createSurface( const String8& name, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags){ sp sur; sp gbp; status_t err = mClient->createSurface(name, w, h, format, flags, &handle, &gbp);//mClient 是一個(gè)sp 對(duì)象,由class Client : public BnSurfaceComposerClient來接收IPC交互, sur = new SurfaceControl(this, handle, gbp);// 最終通過JNI返回到TAG4處 return sur; } Client.cpp // ISurfaceComposerClient interface /* Client是用來與surfaceflinger交互的橋梁,在sf中被創(chuàng)建 sp SurfaceFlinger::createConnection() { sp bclient; sp client(new Client(this)); */ status_t Client::createSurface( const String8& name, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, sp * handle, sp * gbp){ result = flinger->createLayer(name, client, w, h, format, flags, handle, gbp);}//這里面的flinger是由Client::Client(const sp & flinger)在創(chuàng)建時(shí)保存起來的 : mFlinger(flinger) } Surfaceflinger.cpp status_t SurfaceFlinger::createLayer( const String8& name, const sp & client, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, sp * handle, sp * gbp){ sp layer; switch (flags & ISurfaceComposerClient::eFXSurfaceMask) { case ISurfaceComposerClient::eFXSurfaceNormal: result = createNormalLayer(client,//創(chuàng)建普通layer gbp是在layer中進(jìn)行賦值 name, w, h, flags, format, handle, gbp, &layer); break; case ISurfaceComposerClient::eFXSurfaceDim: result = createDimLayer(client,//創(chuàng)建磨砂l(fā)ayer gbp是在layer中進(jìn)行賦值 name, w, h, flags, handle, gbp, &layer); break; default: result = BAD_VALUE; break; result = addClientLayer(client, *handle, *gbp, layer);//attach this layer to the client } //Client中createSurface函數(shù),調(diào)用的是SF中createLayer //與前面ViewrootImpl.java中 final Surface mSurface = new Surface();有何區(qū)分?Layer與surface是如何區(qū)分? 前面遇到j(luò)ava surface用于drawSoftware或hwRender時(shí) ex drawsoftware() canvas = mSurface.lockCanvas(dirty);mView.draw(canvas);