Android Surface理解
结合别人的博客和自己看的代码,梳理下自己对surface的理解
1.代码相关文件
/AOSP/frameworks/native/libs/ui
主要是bufferqueuecore与surfaceflinger中分配
GraphicBufferAllocator 通过hw_get_module()&gralloc_open与硬件提供的设备交互
ex: /hardware/qcom/display/libgralloc/alloc_controller.cpp etc.
/AOSP/frameworks/native/libs/gui
Android.mkIGraphicBufferAlloc.cppBitTube.cppIGraphicBufferConsumer.cppBufferItemConsumer.cppIGraphicBufferProducer.cppBufferItem.cppIProducerListener.cppBufferQueueConsumer.cppISensorEventConnection.cppBufferQueueCore.cppISensorServer.cppBufferQueue.cppISurfaceComposerClient.cppBufferQueueProducer.cppISurfaceComposer.cppBufferSlot.cppLayerState.cppCleanSpec.mkSensor.cppConsumerBase.cppSensorEventQueue.cppCpuConsumer.cppSensorManager.cppDisplayEventReceiver.cppStreamSplitter.cppGLConsumer.cppSurfaceComposerClient.cppGraphicBufferAlloc.cppSurfaceControl.cppGuiConfig.cppSurface.cppIConsumerListener.cppSyncFeatures.cppIDisplayEventConnection.cpptests
SurfaceComposerClient 中成员变量sp<ISurfaceComposerClient> mClient;与surface.cpp binder通信
/AOSP/frameworks/native/services/surfaceflinger
Android.mkEventControlThread.cppMODULE_LICENSE_APACHE2Barrier.hEventControlThread.hMonitoredProducer.cppClient.cppEventLogMonitoredProducer.hClient.hEventThread.cppRenderEngineclz.hEventThread.hSurfaceFlingerConsumer.cppColorizer.hFrameTracker.cppSurfaceFlingerConsumer.hDdmConnection.cppFrameTracker.hSurfaceFlinger.cppDdmConnection.hLayer.cppSurfaceFlinger.hDisplayDevice.cppLayerDim.cppsurfaceflinger.rcDisplayDevice.hLayerDim.htestsDisplayHardwareLayer.hTransform.cppDispSync.cppmain_surfaceflinger.cppTransform.hDispSync.hMessageQueue.cppEffectsMessageQueue.h
surfaceflinger管理surface及layer
AOSP/frameworks/base/core/java/android/view
AbsSavedState.javaMagnificationSpec.aidlaccessibilityMagnificationSpec.javaAccessibilityInteractionController.javaMenuInflater.javaAccessibilityIterators.javaMenuItem.javaActionMode.javaMenu.javaActionProvider.javaMotionEvent.aidlanimationMotionEvent.javaAnimationRenderStats.aidlOrientationEventListener.javaChoreographer.javaOrientationListener.javaCollapsibleActionView.javapackage.htmlContextMenu.javaPointerIcon.aidlContextThemeWrapper.javaPointerIcon.javaDisplayAdjustments.javaRemotableViewMethod.javaDisplay.aidlRenderNodeAnimator.javaDisplayEventReceiver.javaRenderNode.javaDisplayInfo.aidlScaleGestureDetector.javaDisplayInfo.javaSearchEvent.javaDisplay.javaSoundEffectConstants.javaDisplayListCanvas.javaSubMenu.javaDragEvent.aidlSurface.aidlDragEvent.javaSurfaceControl.javaFallbackEventHandler.javaSurfaceHolder.javaFocusFinderHelper.javaSurface.javaFocusFinder.javaSurfaceSession.javaFrameInfo.javaSurfaceView.javaFrameStats.javatextserviceGestureDetector.javaTextureView.javaGhostView.javaThreadedRenderer.javaGraphicBuffer.aidlTouchDelegate.javaGraphicBuffer.javaVelocityTracker.javaGravity.javaViewAnimationUtils.javaHapticFeedbackConstants.javaViewConfiguration.javaHardwareLayer.javaViewDebug.javaHardwareRenderer.javaViewGroup.javaIApplicationToken.aidlViewGroupOverlay.javaIAssetAtlas.aidlViewHierarchyEncoder.javaIGraphicsStats.aidlView.javaIInputFilter.aidlViewManager.javaIInputFilterHost.aidlViewOutlineProvider.javaInflateException.javaViewOverlay.javaInputChannel.aidlViewParent.javaInputChannel.javaViewPropertyAnimator.javaInputDevice.aidlViewPropertyAnimatorRT.javaInputDevice.javaViewRootImpl.javaInputEvent.aidlViewStructure.javaInputEventConsistencyVerifier.javaViewStub.javaInputEvent.javaViewTreeObserver.javaInputEventReceiver.javaWindowAnimationFrameStats.aidlInputEventSender.javaWindowAnimationFrameStats.javaInputFilter.javaWindowCallbackWrapper.javainputmethodWindowContentFrameStats.aidlInputQueue.javaWindowContentFrameStats.javaIOnKeyguardExitResult.aidlWindowId.javaIRotationWatcher.aidlWindowInfo.aidlIWindow.aidlWindowInfo.javaIWindowFocusObserver.aidlWindowInsets.javaIWindowId.aidlWindow.javaIWindowManager.aidlWindowManager.aidlIWindowSession.aidlWindowManagerGlobal.javaIWindowSessionCallback.aidlWindowManagerImpl.javaKeyCharacterMap.javaWindowManagerInternal.javaKeyEvent.aidlWindowManager.javaKeyEvent.javaWindowManagerPolicy.javaLayoutInflater.java
2.Activity显示
2.1 Activity创建
/base/core/java/android/app/ActivityThread.java
handleLaunchActivity(ActivityClientRecordr,IntentcustomIntent){...............//根据类名以Java反射的方法创建一个ActivityActivitya=performLaunchActivity(r,customIntent);handleResumeActivity(r.token,false,r.isForward,!r.activity.mFinished&&!r.startsNotResumed);................}
2.2 handleResumeActivity
finalvoidhandleResumeActivity(IBindertoken,booleanclearHide,booleanisForward,booleanreallyResume){.....................if(r.window==null&&!a.mFinished&&willBeVisible){r.window=r.activity.getWindow();//得到一个view对象Viewdecor=r.window.getDecorView();decor.setVisibility(View.INVISIBLE);//获得viewManagerViewManagerwm=a.getWindowManager();WindowManager.LayoutParamsl=r.window.getAttributes();a.mDecor=decor;l.type=WindowManager.LayoutParams.TYPE_BASE_APPLICATION;l.softInputMode|=forwardBit;if(a.mVisibleFromClient){a.mWindowAdded=true;//将view加入viewmanagerwm.addView(decor,l);}}..................................}
2.3 Activity 通过setContentView设置UI
Activity.java
publicvoidsetContentView(Viewview,ViewGroup.LayoutParamsparams){getWindow().setContentView(view,params);initWindowDecorActionBar();}publicWindowgetWindow(){returnmWindow;}
上面出现了两个和UI有关系的类:View和Window
2.4 Activity Window 与WindowManager
Activity.java
finalvoidattach(Contextcontext,ActivityThreadaThread,Instrumentationinstr,IBindertoken,intident,Applicationapplication,Intentintent,ActivityInfoinfo,CharSequencetitle,Activityparent,Stringid,NonConfigurationInstanceslastNonConfigurationInstances,Configurationconfig,Stringreferrer,IVoiceInteractorvoiceInteractor){//创建window对象mWindow=newPhoneWindow(this);mWindow.setCallback(this);mWindow.setOnWindowDismissedCallback(this);mWindow.getLayoutInflater().setPrivateFactory(this);//创建windowManagermWindow.setWindowManager((WindowManager)context.getSystemService(Context.WINDOW_SERVICE),mToken,mComponent.flattenToString(),(info.flags&ActivityInfo.FLAG_HARDWARE_ACCELERATED)!=0);//保存WindowManager对象mWindowManager=mWindow.getWindowManager();
setWindowManager由PhoneWindow父类window.java实现
Window.java
publicvoidsetWindowManager(WindowManagerwm,IBinderappToken,StringappName,){mWindowManager=((WindowManagerImpl)wm).createLocalWindowManager(this);}
WindowManagerImpl.java
publicWindowManagerImplcreateLocalWindowManager(WindowparentWindow){returnnewWindowManagerImpl(mDisplay,parentWindow);}publicfinalclassWindowManagerImplimplementsWindowManager{}
(2.4)中流程总结
2.5 继续分析setContentView()
Activity.java
publicvoidsetContentView(Viewview,ViewGroup.LayoutParamsparams){getWindow().setContentView(view,params);initWindowDecorActionBar();}
PhoneWindow.java
privateViewGroupmContentParent;publicvoidsetContentView(Viewview){setContentView(view,newViewGroup.LayoutParams(MATCH_PARENT,MATCH_PARENT));}publicvoidsetContentView(Viewview,ViewGroup.LayoutParamsparams){//mContentParent是一个viewGroup对象if(mContentParent==null){installDecor();}if(hasFeature(FEATURE_CONTENT_TRANSITIONS)){view.setLayoutParams(params);finalScenenewScene=newScene(mContentParent,view);transitionTo(newScene);}else{//把view加入到ViewGroup中mContentParent.addView(view,params);}........}
mContentParent是一个ViewGroup类型,它从View中派生,所以也是一个UI单元。从它名字中“Group”所表达的意思分析,它还可以包含其他的View元素。这又是什么意思呢?也就是说,在绘制一个ViewGroup时,它不仅需要把自己的样子画出来,还需要把它包含的View元素的样子也画出来。读者可将它想象成一个容器,容器中的元素就是View。
installDecor()函数
主要用来给view绘制icon ,window title,logo, menu等等
2.6 重回handleResumeActivity
我们之所以分析2.5内容,是为了弄清楚View, ViewManager(就是WindowManager)这些对象
finalvoidhandleResumeActivity(IBindertoken,booleanclearHide,booleanisForward,booleanreallyResume){.....................if(r.window==null&&!a.mFinished&&willBeVisible){r.window=r.activity.getWindow();//得到一个view对象Viewdecor=r.window.getDecorView();decor.setVisibility(View.INVISIBLE);//获得viewManagerViewManagerwm=a.getWindowManager();WindowManager.LayoutParamsl=r.window.getAttributes();a.mDecor=decor;l.type=WindowManager.LayoutParams.TYPE_BASE_APPLICATION;l.softInputMode|=forwardBit;if(a.mVisibleFromClient){a.mWindowAdded=true;//将view加入viewmanagerwm.addView(decor,l);}}..................................}
分析wm.addView(decor,l)
WindowManagerImpl.java
publicfinalclassWindowManagerImplimplementsWindowManager{privatefinalWindowManagerGlobalmGlobal=WindowManagerGlobal.getInstance();publicvoidaddView(@NonNullViewview,@NonNullViewGroup.LayoutParamsparams){applyDefaultToken(params);mGlobal.addView(view,params,mDisplay,mParentWindow);}
WindowManagerGlobal里面可以通过AIDL与IWindowManager.Stub.asInterface及IWindowSessionCallback.Stub()IPC通信
WindowManagerGlobal.java
publicvoidaddView(Viewview,ViewGroup.LayoutParamsparams,Displaydisplay,WindowparentWindow){root=newViewRootImpl(view.getContext(),display);view.setLayoutParams(wparams);mViews.add(view);mRoots.add(root);mParams.add(wparams);root.setView(view,wparams,panelParentView);//TAG1
2.6.1 ViewRootImpl又是什么东东?
ViewRootImpl.java
publicfinalclassViewRootImplimplementsViewParent,View.AttachInfo.Callbacks,HardwareRenderer.HardwareDrawCallbacks{finalIWindowSessionmWindowSession;finalDisplaymDisplay;finalDisplayManagermDisplayManager;finalWmWindow;finalSurfacemSurface=newSurface();staticclassWextendsIWindow.Stub{privatefinalWeakReference<ViewRootImpl>mViewAncestor;privatefinalIWindowSessionmWindowSession;}
ViewRootImpl继承了Handler类,看来它能处理消息。ViewRootImpl果真重写了handleMessage函数
一个成员变量叫mSurface,它是Surface类型
surface.javapublicclassSurfaceimplementsParcelable{
一个W类型的mWindow和一个View类型的mView变量
ViewRootImpl有一个成员变量mSurface,它是Surface类型,它和一块Raw Buffer有关联。
ViewRootImpl是一个ViewParent,它的子View的绘画操作,是在画布Surface上展开的
ViewRootImpl的构造
publicViewRootImpl(Contextcontext,Displaydisplay){mDisplay=display;//Display.javaProvidesinformationaboutthesizeanddensityofalogicaldisplay.mWindowSession=WindowManagerGlobal.getWindowSession();//IWindowSessionAIDLmWindow=newW(this);//内部W对象,实际是与window通信的AIDLstaticclassWextendsIWindow.StubmDisplayManager=(DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
WindowManagerGlobal.getWindowSession()将建立Activity的ViewRoot和WindowManagerService的关系
WindowManagerGlobal.java
publicstaticIWindowSessiongetWindowSession(){IWindowManagerwindowManager=getWindowManagerService();//得到Iwindowmanager对象,//IWindowManager的AIDLBn端是WindowManagerServiceclassWindowManagerServiceextendsIWindowManager.StubsWindowSession=windowManager.openSession(//然后通过AIDL得到windowsessionaidl对象不清楚为啥已经有了windowmanager的aidl干嘛还需要windowsessionaidlnewIWindowSessionCallback.Stub(){})}publicstaticIWindowManagergetWindowManagerService(){sWindowManagerService=IWindowManager.Stub.asInterface(ServiceManager.getService("window"));//得到WindowManagerAIDLBP对象try{sWindowManagerService=getWindowManagerService();ValueAnimator.setDurationScale(sWindowManagerService.getCurrentAnimatorScale());}catch(RemoteExceptione){}
ViewRootImpl和WMS的关系/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
publicclassWindowManagerServiceextendsIWindowManager.StubimplementsWatchdog.Monitor,WindowManagerPolicy.WindowManagerFuncs{}publicIWindowSessionopenSession(IWindowSessionCallbackcallback,IInputMethodClientclient,IInputContextinputContext){Sessionsession=newSession(this,callback,client,inputContext);returnsession;}
/frameworks/base/services/core/java/com/android/server/wm/Session.java
finalclassSessionextendsIWindowSession.StubimplementsIBinder.DeathRecipient{finalWindowManagerServicemService;finalIWindowSessionCallbackmCallback;finalIInputMethodClientmClient;
分析完ViewRootImpl创建过程后,现在返回TAG 1处继续分析ViewRootImpl.setView()
2.6.2 ViewRootImpl.setView()
/frameworks/base/core/java/android/view/ViewRootImpl.java
publicvoidsetView(Viewview,WindowManager.LayoutParamsattrs,ViewpanelParentView){//ComputesurfaceinsetsrequiredtodrawatspecifiedZvalue.//TODO:UserealshadowinsetsforaconstantmaxZ.if(!attrs.hasManualSurfaceInsets){finalintsurfaceInset=(int)Math.ceil(view.getZ()*2);attrs.surfaceInsets.set(surfaceInset,surfaceInset,surfaceInset,surfaceInset);}//计算Z轴坐标requestLayout();res=mWindowSession.addToDisplay(mWindow,mSeq,mWindowAttributes,getHostVisibility(),mDisplay.getDisplayId(),mAttachInfo.mContentInsets,mAttachInfo.mStableInsets,mAttachInfo.mOutsets,mInputChannel);
//requestLayout()流程TAG2publicvoidrequestLayout(){scheduleTraversals();}voidscheduleTraversals(){mTraversalBarrier=mHandler.getLooper().getQueue().postSyncBarrier();mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL,mTraversalRunnable,null);notifyRendererOfFramePending();pokeDrawLockIfNeeded();}finalTraversalRunnablemTraversalRunnable=newTraversalRunnable();//Runnable实现多线程,避免点继承的局限,一个类可以继承多个接口.适合于资源的共享finalclassTraversalRunnableimplementsRunnable{@Overridepublicvoidrun(){doTraversal();}}voiddoTraversal(){performTraversals();}privatevoidperformTraversals(){//mSurface是surface.java对象,finalSurfacemSurface=newSurface();//surface.java通过jni可以操作Surface.cpp中surface对象Surface::Surface(//constsp<IGraphicBufferProducer>&bufferProducer,//boolcontrolledByApp)if(mSurface.isValid()){if(mAttachInfo.mHardwareRenderer!=null){try{hwInitialized=mAttachInfo.mHardwareRenderer.initialize(mSurface);if(hwInitialized&&(host.mPrivateFlags&View.PFLAG_REQUEST_TRANSPARENT_REGIONS)==0){//Don'tpre-allocateiftransparentregions//arerequestedastheymaynotbeneededmSurface.allocateBuffers();}}//Interfaceforrenderingaviewhierarchyusinghardwareacceleration.finalHardwareRendererhardwareRenderer=mAttachInfo.mHardwareRenderer;hardwareRenderer.setup(mWidth,mHeight,mAttachInfo,mWindowAttributes.surfaceInsets);}
mWindowSession.addToDisplay流程//mWindowSession(IWindowSession)通过AIDL与Session.java交互finalclassSessionextendsIWindowSession.StubpublicintaddToDisplay(IWindowwindow,intseq,WindowManager.LayoutParamsattrs,intviewVisibility,intdisplayId,RectoutContentInsets,RectoutStableInsets,RectoutOutsets,InputChanneloutInputChannel){returnmService.addWindow(this,window,seq,attrs,viewVisibility,displayId,outContentInsets,outStableInsets,outOutsets,outInputChannel);}finalWindowManagerServicemService;WindowManagerService.javapublicintaddWindow(Sessionsession,IWindowclient,intseq,WindowManager.LayoutParamsattrs,intviewVisibility,intdisplayId,RectoutContentInsets,RectoutStableInsets,RectoutOutsets,InputChanneloutInputChannel){//windowstateAwindowinthewindowmanager.classWindowStateimplementsWindowManagerPolicy.WindowStateWindowStatewin=newWindowState(this,session,client,token,attachedWindow,appOp[0],seq,attrs,viewVisibility,displayContent);win.attach();}WindowState.javavoidattach(){mSession.windowAddedLocked();}Session.javavoidwindowAddedLocked(){mSurfaceSession=newSurfaceSession();mService.mSessions.add(this);mNumWindow++;}
ViewRootImpl 与WMS关系总结
ViewRootImpl通过IWindowSession和WMS进程进行跨进程通信。
ViewRootImpl内部有一个W类型的对象,它也是一个基于Binder通信的类,W是IWindow的Bn端,用于响应请求。IWindow定义在另一个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();
这里的事件指的就是按键、触屏等事件。那么,一个按键事件是如何被分发的呢?下面是它大致的流程:WMS所在的SystemServer进程接收到按键事件。WMS找到UI位于屏幕顶端的进程所对应的IWindow对象,调用这个IWindow对象的dispatchKey。IWindow对象的Bn端位于ViewRoot中,ViewRoot再根据内部View的位置信息找到真正处理这个事件的View,最后调用dispatchKey函数完成按键的处理。(这段过程没有去跟代码)
2.7Activity的UI绘制
在TAG2处分析过requestLayout。根据前面的分析可知,最终调用到performTraversals()
ViewRootImpl.java
privatevoidperformTraversals(){relayoutResult=relayoutWindow(params,viewVisibility,insetsPending);//TAG3performDraw();//开始绘制}privateintrelayoutWindow(WindowManager.LayoutParamsparams,intviewVisibility,booleaninsetsPending)throwsRemoteException{intrelayoutResult=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);}//这个函数通过AIDL调用到WMSrelayoutWindow().暂时不继续分析privatevoidperformDraw(){draw(fullRedrawNeeded);}privatevoiddraw(booleanfullRedrawNeeded){mAttachInfo.mHardwareRenderer.draw(mView,mAttachInfo,this);//hwrender完成draw//HardwareRenderer.javaabstractvoiddraw()}
2.8 Activity 总结
Activity的顶层View是DecorView,而我们在onCreate函数中通过setContentView设置的View只不过是这个DecorView中的一部分罢了。DecorView是一个FrameLayout类型的ViewGroup。
Activity和UI有关,它包含一个Window(真实类型是PhoneWindow)和一个WindowManager(真实类型是LocalWindowManager)对象。这两个对象将控制整个Activity的显示。
LocalWindowManager使用了WindowManagerImpl做为最终的处理对象(Proxy模式),这个WindowManagerImpl中有一个ViewRootImpl对象。ViewRootImpl实现了ViewParent接口,它有两个重要的成员变量,一个是mView,它指向Activity顶层UI单元的DecorView,另外有一个mSurface,这个Surface包含了一个Canvas(画布)(这个surface java对象可以通过JNI 与 surface.cpp中对象交互)。除此之外,ViewRooImplt还通过Binder系统和WindowManagerService进行了跨进程交互。
ViewRoot能处理Handler的消息,Activity的显示就是由ViewRoot在它的performTraversals函数中完成的。
3. Surface对象
终于可以分析java与C++处surface对象了,先回忆下surface是如何创建的
ViewRootImpl.javafinalSurfacemSurface=newSurface();
ViewRootImpl通过IWindowSession和WMS交互,而WMS中会调用的一个attach函数,会构造一个SurfaceSession,前面遇到过但没有继续分析
WindowState.javavoidattach(){mSession.windowAddedLocked();}Session.javavoidwindowAddedLocked(){mSurfaceSession=newSurfaceSession();mService.mSessions.add(this);mNumWindow++;}SurfaceSession.java//*Aninstanceofthisclassrepresentsaconnectiontothesurface//*flinger,fromwhichyoucancreateoneormoreSurfaceinstancesthatwill//*becompositedtothescreen.publicfinalclassSurfaceSession{privatestaticnativelongnativeCreate();privatestaticnativevoidnativeDestroy(longptr);privatestaticnativevoidnativeKill(longptr);}
由注释可见,surfacesession负责与SF的连接
在2.7处Activity UI 绘制时,遇到过relayoutWindow(),现在继续看该函数
ViewRootImpl.java
privatevoidperformTraversals(){relayoutResult=relayoutWindow(params,viewVisibility,insetsPending);//TAG3performDraw();//开始绘制}privateintrelayoutWindow(WindowManager.LayoutParamsparams,intviewVisibility,booleaninsetsPending)throwsRemoteException{intrelayoutResult=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);}//这个函数通过AIDL调用到WMSrelayoutWindow()Session.javapublicintrelayout(IWindowwindow,intseq,WindowManager.LayoutParamsattrs,..){intres=mService.relayoutWindow(this,....);}WindowManagerService.javapublicintrelayoutWindow(Sessionsession,IWindowclient,intseq,WindowManager.LayoutParamsattrs,intrequestedWidth,....){SurfaceControlsurfaceControl=winAnimator.createSurfaceLocked();//TAG4创建本地surfacecontrol通过JNI会调用C++最终创建layer,java层保存的surfacecontrol对象是一个surfaceControl.cpp中对象//JNI处返回的surfacecontrol//surface->incStrong((void*)nativeCreate);//returnreinterpret_cast<jlong>(surface.get());outSurface.copyFrom(surfaceControl);//将本地surface拷贝到outSurface}WindowStateAnimator.javaSurfaceControlcreateSurfaceLocked(){finalWindowStatew=mWin;mSurfaceControl=newSurfaceControl(mSession.mSurfaceSession,attrs.getTitle().toString(),width,height,format,flags);//Startanewtransactionandapplyposition&offset.SurfaceControl.openTransaction();mSurfaceControl.setLayer(mAnimLayer);mSurfaceControl.setAlpha(0);SurfaceControl.closeTransaction();returnmSurfaceControl;}
SurfaceControl是个什么对象?与Surface有何关系
/frameworks/base/core/java/android/view/SurfaceControl.java
看SurfaceControl构造函数说明,surfacecontrol根据name创建surface
/***Createasurfacewithaname.*<p>*Thesurfacecreationflagsspecifywhatkindofsurfacetocreateand*certainoptionssuchaswhetherthesurfacecanbeassumedtobeopaque*andwhetheritshouldbeinitiallyhidden.Surfacesshouldalwaysbe*createdwiththe{@link#HIDDEN}flagsettoensurethattheyarenot*madevisibleprematurelybeforeallofthesurface'spropertieshavebeen*configured.*<p>*Goodpracticeistofirstcreatethesurfacewiththe{@link#HIDDEN}flag*specified,openatransaction,setthesurfacelayer,layerstack,alpha,*andposition,call{@link#show}ifappropriate,andclosethetransaction.**@paramsessionThesurfacesession,mustnotbenull.*@paramnameThesurfacename,mustnotbenull.*@paramwThesurfaceinitialwidth.*@paramhThesurfaceinitialheight.*@paramflagsThesurfacecreationflags.Shouldalwaysinclude{@link#HIDDEN}*inthecreationflags.**@throwsthrowsOutOfResourcesExceptionIftheSurfaceControlcannotbecreated.*/publicSurfaceControl(SurfaceSessionsession,Stringname,intw,inth,intformat,intflags){mNativeObject=nativeCreate(session,name,w,h,format,flags);}通过JNIandroid_view_SurfaceControl.cppstaticjlongnativeCreate(JNIEnv*env,jclassclazz,jobjectsessionObj,jstringnameStr,jintw,jinth,jintformat,jintflags){ScopedUtfCharsname(env,nameStr);sp<SurfaceComposerClient>client(android_view_SurfaceSession_getClient(env,sessionObj));sp<SurfaceControl>surface=client->createSurface(String8(name.c_str()),w,h,format,flags);}调用SurfaceComposiClient.cppsp<SurfaceControl>SurfaceComposerClient::createSurface(constString8&name,uint32_tw,uint32_th,PixelFormatformat,uint32_tflags){sp<SurfaceControl>sur;sp<IGraphicBufferProducer>gbp;status_terr=mClient->createSurface(name,w,h,format,flags,&handle,&gbp);//mClient是一个sp<ISurfaceComposerClient>对象,由classClient:publicBnSurfaceComposerClient来接收IPC交互,sur=newSurfaceControl(this,handle,gbp);//最终通过JNI返回到TAG4处returnsur;}Client.cpp//ISurfaceComposerClientinterface/*Client是用来与surfaceflinger交互的桥梁,在sf中被创建sp<ISurfaceComposerClient>SurfaceFlinger::createConnection(){sp<ISurfaceComposerClient>bclient;sp<Client>client(newClient(this));*/status_tClient::createSurface(constString8&name,uint32_tw,uint32_th,PixelFormatformat,uint32_tflags,sp<IBinder>*handle,sp<IGraphicBufferProducer>*gbp){result=flinger->createLayer(name,client,w,h,format,flags,handle,gbp);}//这里面的flinger是由Client::Client(constsp<SurfaceFlinger>&flinger)在创建时保存起来的:mFlinger(flinger)}Surfaceflinger.cppstatus_tSurfaceFlinger::createLayer(constString8&name,constsp<Client>&client,uint32_tw,uint32_th,PixelFormatformat,uint32_tflags,sp<IBinder>*handle,sp<IGraphicBufferProducer>*gbp){sp<Layer>layer;switch(flags&ISurfaceComposerClient::eFXSurfaceMask){caseISurfaceComposerClient::eFXSurfaceNormal:result=createNormalLayer(client,//创建普通layergbp是在layer中进行赋值name,w,h,flags,format,handle,gbp,&layer);break;caseISurfaceComposerClient::eFXSurfaceDim:result=createDimLayer(client,//创建磨砂layergbp是在layer中进行赋值name,w,h,flags,handle,gbp,&layer);break;default:result=BAD_VALUE;break;result=addClientLayer(client,*handle,*gbp,layer);//attachthislayertotheclient}//Client中createSurface函数,调用的是SF中createLayer//与前面ViewrootImpl.java中finalSurfacemSurface=newSurface();有何区分?Layer与surface是如何区分?前面遇到javasurface用于drawSoftware或hwRender时exdrawsoftware()canvas=mSurface.lockCanvas(dirty);mView.draw(canvas);
上述流程的小结
3.1 Surface与画图
lockCanvas
Surface.java*Getsa{@linkCanvas}fordrawingintothissurface.publicCanvaslockCanvas(RectinOutDirty){mLockedObject=nativeLockCanvas(mNativeObject,mCanvas,inOutDirty);returnmCanvas;}
调用JNI
android_view_Surface.cpp
staticjlongnativeLockCanvas(JNIEnv*env,jclassclazz,jlongnativeObject,jobjectcanvasObj,jobjectdirtyRectObj){sp<Surface>surface(reinterpret_cast<Surface*>(nativeObject));RectdirtyRect;Rect*dirtyRectPtr=NULL;if(dirtyRectObj){dirtyRect.left=env->GetIntField(dirtyRectObj,gRectClassInfo.left);dirtyRect.top=env->GetIntField(dirtyRectObj,gRectClassInfo.top);dirtyRect.right=env->GetIntField(dirtyRectObj,gRectClassInfo.right);dirtyRect.bottom=env->GetIntField(dirtyRectObj,gRectClassInfo.bottom);dirtyRectPtr=&dirtyRect;}ANativeWindow_BufferoutBuffer;status_terr=surface->lock(&outBuffer,dirtyRectPtr);//一块表示脏区域的dirtyRectPtr//从surface.cpp中dequeueBuffer()获得一个GraphicBuffer,然后将buffer的长宽,format等赋制给outBuffer,//SkImageInfoinfo=SkImageInfo::Make(outBuffer.width,outBuffer.height,convertPixelFormat(outBuffer.format),kPremul_SkAlphaType);SkBitmapbitmap;ssize_tbpr=outBuffer.stride*bytesPerPixel(outBuffer.format);bitmap.setInfo(info,bpr);if(outBuffer.width>0&&outBuffer.height>0){bitmap.setPixels(outBuffer.bits);//bitmap指向一片存储区域}else{//besafewithanemptybitmap.bitmap.setPixels(NULL);}Canvas*nativeCanvas=GraphicsJNI::getNativeCanvas(env,canvasObj);nativeCanvas->setBitmap(bitmap);//将Bitmap设置到这个Canvas中,这样进UI绘画时就有画布了//Createanotherreferencetothesurfaceandreturnit.Thisreference//shouldbepassedtonativeUnlockCanvasAndPostinplaceofmNativeObject,//becausethelattercouldbereplacedwhilethesurfaceislocked.sp<Surface>lockedSurface(surface);lockedSurface->incStrong(&sRefBaseOwner);return(jlong)lockedSurface.get();}
lockCanvas获得一块存储区域,然后将它和Canvas绑定到一起,这样,UI绘画的结果就记录在这块存储区域里了
再看unlockCanvas
Surface.java
privatevoidunlockSwCanvasAndPost(Canvascanvas){//只有sw渲染的才走这边?try{nativeUnlockCanvasAndPost(mLockedObject,canvas);}finally{nativeRelease(mLockedObject);mLockedObject=0;}}
android_view_Surface.cpp
staticvoidnativeUnlockCanvasAndPost(JNIEnv*env,jclassclazz,jlongnativeObject,jobjectcanvasObj){sp<Surface>surface(reinterpret_cast<Surface*>(nativeObject));//detachthecanvasfromthesurfaceCanvas*nativeCanvas=GraphicsJNI::getNativeCanvas(env,canvasObj);nativeCanvas->setBitmap(SkBitmap());//unlocksurfacestatus_terr=surface->unlockAndPost();}
Surface.cpp
status_tSurface::unlockAndPost(){status_terr=mLockedBuffer->unlockAsync(&fd);//通过mGraphicBufferProducer->queueBuffererr=queueBuffer(mLockedBuffer.get(),fd);}
直接使用别人的图片surface画图过程
回忆下上文surface 是如何创建的
sp<SurfaceControl>SurfaceComposerClient::createSurface(constString8&name,uint32_tw,uint32_th,PixelFormatformat,uint32_tflags){sp<IGraphicBufferProducer>gbp;status_terr=mClient->createSurface(name,w,h,format,flags,&handle,&gbp);ALOGE_IF(err,"SurfaceComposerClient::createSurfaceerror%s",strerror(-err));if(err==NO_ERROR){sur=newSurfaceControl(this,handle,gbp);}}
mClientsp<ISurfaceComposerClient>mClient;
class Client : public BnSurfaceComposerClient
Client 中mFlingersp<SurfaceFlinger> mFlinger; 这样SurfaceComposerClient 就通过IPC 与surfaceflinger 交互起来了
status_tClient::createSurface(constString8&name,uint32_tw,uint32_th,PixelFormatformat,uint32_tflags,sp<IBinder>*handle,sp<IGraphicBufferProducer>*gbp){sp<MessageBase>msg=newMessageCreateLayer(mFlinger.get(),name,this,w,h,format,flags,handle,gbp);mFlinger->postMessageSync(msg);returnstatic_cast<MessageCreateLayer*>(msg.get())->getResult();}
Client::createSurface() 与 android_view_Surface.cpp 中nativeReadFromParcel
surfacecontrol.cppstatus_tSurfaceControl::writeSurfaceToParcel(constsp<SurfaceControl>&control,Parcel*parcel){sp<IGraphicBufferProducer>bp;if(control!=NULL){bp=control->mGraphicBufferProducer;}returnparcel->writeStrongBinder(IInterface::asBinder(bp));//Surface核心是不是就是IGraphicBufferProducer指针}
android_view_Surface.cppstaticjlongnativeReadFromParcel(JNIEnv*env,jclassclazz,jlongnativeObject,jobjectparcelObj){Parcel*parcel=parcelForJavaObject(env,parcelObj);sp<Surface>self(reinterpret_cast<Surface*>(nativeObject));sp<IBinder>binder(parcel->readStrongBinder());//updatetheSurfaceonlyiftheunderlyingIGraphicBufferProducer//haschanged.if(self!=NULL&&(IInterface::asBinder(self->getIGraphicBufferProducer())==binder)){//sameIGraphicBufferProducer,returnourselvesreturnjlong(self.get());//直接返回surfacesp}//当GraphicBufferProducer改变时,新建一个surface,并将原先surfacedecStrong释放,返回新surface指针sp<Surface>sur;sp<IGraphicBufferProducer>gbp(interface_cast<IGraphicBufferProducer>(binder));if(gbp!=NULL){//wehaveanewIGraphicBufferProducer,createanewSurfaceforitsur=newSurface(gbp,true);//andkeepareferencebeforepassingtojavasur->incStrong(&sRefBaseOwner);}if(self!=NULL){//andloosethejavareferencetoourselvesself->decStrong(&sRefBaseOwner);}returnjlong(sur.get());
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。