android surfaceflinger研究----Surface机制

转自: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

[cpp] view plain copy
  1. //Thesecanbeaccessedbyanythread,mustbeprotectedwithalock.
  2. //Surfacecanneverbereassignedorcleared(useSurface.clear()).
  3. privatefinalSurfacemSurface=newSurface();

Surface(SurfaceTexture surfaceTexture)@Surface.java

[cpp] view plain copy
  1. /**
  2. *CreateSurfacefroma{@linkSurfaceTexture}.
  3. *
  4. *ImagesdrawntotheSurfacewillbemadeavailabletothe{@link
  5. *SurfaceTexture},whichcanattachthemanOpenGLEStexturevia{@link
  6. *SurfaceTexture#updateTexImage}.
  7. *
  8. *@paramsurfaceTextureThe{@linkSurfaceTexture}thatisupdatedbythis
  9. *Surface.
  10. */
  11. publicSurface(SurfaceTexturesurfaceTexture){
  12. if(DEBUG_RELEASE){
  13. mCreationStack=newException();
  14. }
  15. mCanvas=newCompatibleCanvas();
  16. initFromSurfaceTexture(surfaceTexture);
  17. }

由上面可以看出在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

[cpp] view plain copy
  1. privateintrelayoutWindow(WindowManager.LayoutParamsparams,intviewVisibility,
  2. booleaninsetsPending)throwsRemoteException{
  3. ...
  4. intrelayoutResult=sWindowSession.relayout(
  5. mWindow,mSeq,params,
  6. (int)(mView.getMeasuredWidth()*appScale+0.5f),
  7. (int)(mView.getMeasuredHeight()*appScale+0.5f),
  8. viewVisibility,insetsPending,mWinFrame,
  9. mPendingContentInsets,mPendingVisibleInsets,
  10. mPendingConfiguration,mSurface);
  11. //Log.d(TAG,"<<<<<<BACKFROMrelayout");
  12. if(restore){
  13. params.restore();
  14. }
  15. if(mTranslator!=null){
  16. mTranslator.translateRectInScreenToAppWinFrame(mWinFrame);
  17. mTranslator.translateRectInScreenToAppWindow(mPendingContentInsets);
  18. mTranslator.translateRectInScreenToAppWindow(mPendingVisibleInsets);
  19. }
  20. returnrelayoutResult;
  21. }

relayoutWindow()@WindowManagerService.java

[cpp] view plain copy
  1. publicintrelayoutWindow(Sessionsession,IWindowclient,intseq,
  2. WindowManager.LayoutParamsattrs,intrequestedWidth,
  3. intrequestedHeight,intviewVisibility,booleaninsetsPending,
  4. RectoutFrame,RectoutContentInsets,RectoutVisibleInsets,
  5. ConfigurationoutConfig,SurfaceoutSurface){
  6. booleandisplayed=false;
  7. booleaninTouchMode;
  8. booleanconfigChanged;
  9. //iftheydon'thavethispermission,maskoutthestatusbarbits
  10. synchronized(mWindowMap){
  11. WindowStatewin=windowForClientLocked(session,client,false);
  12. if(viewVisibility==View.VISIBLE&&
  13. (win.mAppToken==null||!win.mAppToken.clientHidden)){
  14. displayed=!win.isVisibleLw();
  15. ...
  16. try{
  17. Surfacesurface=win.createSurfaceLocked();
  18. if(surface!=null){
  19. outSurface.copyFrom(surface);
  20. win.mReportDestroySurface=false;
  21. win.mSurfacePendingDestroy=false;
  22. if(SHOW_TRANSACTIONS)Slog.i(TAG,
  23. "OUTSURFACE"+outSurface+":copied");
  24. }else{
  25. //Forsomereasonthereisn'tasurface.Clearthe
  26. //caller'sobjectsotheyseethesamestate.
  27. outSurface.release();
  28. }
  29. }catch(Exceptione){
  30. mInputMonitor.updateInputWindowsLw(true/*force*/);
  31. Slog.w(TAG,"Exceptionthrownwhencreatingsurfaceforclient"
  32. +client+"("+win.mAttrs.getTitle()+")",
  33. e);
  34. Binder.restoreCallingIdentity(origId);
  35. return0;
  36. }
  37. ...
  38. }
  39. }

1.2SurfaceSession

SurfaceSession可以认为是创建Surface过程中,WMS和SurfaceFlinger之间的会话层,通过这个SurfaceSession实现了Surface的创建。

一个SurfaceSession表示一个到SurfaceFlinger的连接,通过它可以创建一个或多个Surface实例。

SurfaceSession是JAVA层的概念,@SurfaceSession.java。它对应的native实体是一个SurfaceComposerClient对象。

SurfaceComposerClient通过ComposerService类来获得SurfaceFlinger的IBinder接口ISurfaceComposer,但是光获得SurfaceFlinger的IBinder接口是不够的,要想请求SurfaceFlinger创建一个Surface,还需要向SurfaceFlinger获得一个IBinder接口ISurfaceComposerClient,通过这个ISurfaceComposerClient来请求SurfaceFlinger创建一个Surface,为什么这么绕呢,为什么不直接让SurfaceFlinger创建Surface呢?

站在SurfaceFlinger的角度来考虑,对于SurfaceFlinger来说,可能有多个Client来请求SurfaceFlinger的业务,每个Client可能会请求SurfaceFlinger创建多个Surface,那么SurfaceFlinger本地需要提供一套机制来保存每个client请求创建的Surface,SurfaceFlinger通过为每个client创建一个Client对象实现这个机制,并将这个Client的IBinder接口ISurfaceComposerClient返给SurfaceComposerClient对象。SurfaceComposerClient对象在通过ISurfaceComposerClient去请求创建Surface(ISurfaceComposerClient的功能只有创建和销毁Surface)。

@SurfaceFlinger.h

[cpp] view plain copy
  1. classClient:publicBnSurfaceComposerClient
  2. classSurfaceFlinger:
  3. publicBinderService<SurfaceFlinger>,
  4. publicBnSurfaceComposer,
  5. publicIBinder::DeathRecipient,
  6. protectedThread


@SurfaceComposerClient.cpp

[cpp] view plain copy
  1. voidSurfaceComposerClient::onFirstRef(){
  2. sp<ISurfaceComposer>sm(getComposerService());
  3. if(sm!=0){
  4. sp<ISurfaceComposerClient>conn=sm->createConnection();
  5. if(conn!=0){
  6. mClient=conn;
  7. mStatus=NO_ERROR;
  8. }
  9. }
  10. }

在SurfaceFlinger中对应的执行代码为:

[cpp] view plain copy
  1. sp<ISurfaceComposerClient>SurfaceFlinger::createConnection()
  2. {
  3. sp<ISurfaceComposerClient>bclient;
  4. sp<Client>client(newClient(this));
  5. status_terr=client->initCheck();
  6. if(err==NO_ERROR){
  7. bclient=client;
  8. }
  9. returnbclient;
  10. }

下图描述了整个SurfaceSession的内部结构与工作流程。

蓝色箭头是SurfaceComposerClient通过ComposerService获得SurfaceFlinger的IBinder接口ISurfaceComposer过程;

红色箭头表示SurfaceComposerClient通过IPC请求SurfaceFlinger创建Client的过程,并获得Client的IBinder接口ISurfaceComposerClient;

绿色箭头表示SurfaceComposerClient通过IPC请求Client创建Surface。


1.3 Surface的形态

上一节我们分析了SurfaceSession的静态结构,得知Surface的创建过程是通过SurfaceSession这个中间会话层去请求SurfaceFlinger去创建的,并且这篇文章中,我们说了半天Surface了,那么究竟我们要创建的Surface究竟是什么样的一个东西呢,它的具体形态是什么呢?这一小节我们就来分析以下Surface的形态。

1.3.1 client端Surface的形态

首先,我们看一下Surface在WMS中定义的代码

createSurfaceLocked()@WindowState.java

[cpp] view plain copy
  1. SurfacecreateSurfaceLocked(){
  2. if(mSurface==null){
  3. ...
  4. try{
  5. finalbooleanisHwAccelerated=(mAttrs.flags&
  6. WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED)!=0;
  7. finalintformat=isHwAccelerated?PixelFormat.TRANSLUCENT:mAttrs.format;
  8. if(!PixelFormat.formatHasAlpha(mAttrs.format)){
  9. flags|=Surface.OPAQUE;
  10. }
  11. mSurface=newSurface(
  12. mSession.mSurfaceSession,mSession.mPid,
  13. mAttrs.getTitle().toString(),
  14. 0,w,h,format,flags);
  15. if(SHOW_TRANSACTIONS||SHOW_SURFACE_ALLOC)Slog.i(WindowManagerService.TAG,
  16. "CREATESURFACE"
  17. +mSurface+"INSESSION"
  18. +mSession.mSurfaceSession
  19. +":pid="+mSession.mPid+"format="
  20. +mAttrs.format+"flags=0x"
  21. +Integer.toHexString(flags)
  22. +"/"+this);
  23. }
  24. ...
  25. }
  26. returnmSurface;
  27. }

我们可以看到,它将SurfaceSession对象当作参数传递给了Surface的构造函数。往下看Surface的构造函数。

@Surface.java

[cpp] view plain copy
  1. /**createasurfacewithaname@hide*/
  2. publicSurface(SurfaceSessions,
  3. intpid,Stringname,intdisplay,intw,inth,intformat,intflags)
  4. throwsOutOfResourcesException{
  5. if(DEBUG_RELEASE){
  6. mCreationStack=newException();
  7. }
  8. mCanvas=newCompatibleCanvas();
  9. init(s,pid,name,display,w,h,format,flags);
  10. mName=name;
  11. }

这个构造函数,不同于我们在ViewRootImpl中看到的Surface的构造函数,这个构造函数并不是一个空壳,它做了本地实体的初始化工作,因此这个Surface才是一个真正的Suface。

Native函数init(Surface_init@android_view_Surface.cpp)会调到SurfaceComposerClient::createSurface,再向下的过程在上一节的图中描述很清楚了,在此不作介绍了。同时,先不管SurfaceFlinger为SurfaceComposerClient创建的Surface到底是一个什么东西,我们先看看SurfaceComposerClient为WMS创建的是一个什么东西?

@SurfaceComposerClient.cpp

[cpp] view plain copy
  1. sp<SurfaceControl>SurfaceComposerClient::createSurface(
  2. constString8&name,
  3. DisplayIDdisplay,
  4. uint32_tw,
  5. uint32_th,
  6. PixelFormatformat,
  7. uint32_tflags)
  8. {
  9. sp<SurfaceControl>result;
  10. if(mStatus==NO_ERROR){
  11. ISurfaceComposerClient::surface_data_tdata;
  12. sp<ISurface>surface=mClient->createSurface(&data,name,//mClient为BpSurfaceComposerClient
  13. display,w,h,format,flags);
  14. if(surface!=0){
  15. result=newSurfaceControl(this,surface,data);
  16. }
  17. }
  18. returnresult;
  19. }

从上面的代码我们可以看出,SurfaceComposerClient为WMS返回的是一个SurfaceControl对象,这个SurfaceControl对象包含了surfaceFlinger为SurfaceComposerClient创建的surface,这个surfaceFlinge创建的Surface在Client端的形态为ISurface。这个过程下面分析SurfaceFlinger端的Surface形态时会看到。

SurfaceControl类中还有一个非常重要的成员mSurfaceData<class Surface : public SurfaceTextureClient>,它的类型也叫做Surface,定义在frameworks/base/include/surfaceflinger/surface.h。这个Surface提供了显示Buffer的管理。在文章的后面再介绍。

@frameworks/base/libs/gui/Surface.cpp

[cpp] view plain copy
  1. sp<Surface>SurfaceControl::getSurface()const
  2. {
  3. Mutex::Autolock_l(mLock);
  4. if(mSurfaceData==0){
  5. sp<SurfaceControl>surface_control(const_cast<SurfaceControl*>(this));
  6. mSurfaceData=newSurface(surface_control);
  7. }
  8. returnmSurfaceData;
  9. }

1.3.2 SurfaceFlinger端Surface形态

SurfaceFlinger::createSurface@SurfaceFlinger.cpp [cpp] view plain copy
  1. sp<ISurface>SurfaceFlinger::createSurface(
  2. ISurfaceComposerClient::surface_data_t*params,
  3. constString8&name,
  4. constsp<Client>&client,
  5. DisplayIDd,uint32_tw,uint32_th,PixelFormatformat,
  6. uint32_tflags)
  7. {
  8. sp<LayerBaseClient>layer;
  9. sp<ISurface>surfaceHandle;
  10. if(int32_t(w|h)<0){
  11. LOGE("createSurface()failed,worhisnegative(w=%d,h=%d)",
  12. int(w),int(h));
  13. returnsurfaceHandle;
  14. }
  15. //LOGD("createSurfaceforpid%d(%dx%d)",pid,w,h);
  16. sp<Layer>normalLayer;
  17. switch(flags&eFXSurfaceMask){
  18. caseeFXSurfaceNormal:
  19. normalLayer=createNormalSurface(client,d,w,h,flags,format);
  20. layer=normalLayer;
  21. break;
  22. caseeFXSurfaceBlur:
  23. //fornowwetreatBlurasDim,untilwecanimplementit
  24. //efficiently.
  25. caseeFXSurfaceDim:
  26. layer=createDimSurface(client,d,w,h,flags);
  27. break;
  28. caseeFXSurfaceScreenshot:
  29. layer=createScreenshotSurface(client,d,w,h,flags);
  30. break;
  31. }
  32. if(layer!=0){
  33. layer->initStates(w,h,flags);
  34. layer->setName(name);
  35. ssize_ttoken=addClientLayer(client,layer);
  36. surfaceHandle=layer->getSurface();
  37. if(surfaceHandle!=0){
  38. params->token=token;
  39. params->identity=layer->getIdentity();
  40. if(normalLayer!=0){
  41. Mutex::Autolock_l(mStateLock);
  42. mLayerMap.add(layer->getSurfaceBinder(),normalLayer);
  43. }
  44. }
  45. setTransactionFlags(eTransactionNeeded);
  46. }
  47. returnsurfaceHandle;
  48. }

当client请求SurfaceFlinger创建Surface时,SurfaceFlinger首先根据WMS提供的窗口的属性来一个命名为Layer概念的对象,然后再根据Layer创建它的子类对象LayerBaseClient::BSurface。此时第三个名为Surface(BSurface)类出现了,下一节我们来介绍一下这个Layer的概念。

1.4 Layer


1.4.1 Layer的分类

目前,android4.0中有3中Layer类型,如上图所示。

1.Layer, 普通的Layer,它为每个Client端请求的Surface创建显示Buffer。

2.LayerDim,这种Layer不会创建显示Buffer,它只是将通过这个Layer将原来FrameBuffer上的数据进行暗淡处理;

3. LayerScreenshot,这种Layer不会创建显示Buffer,它只是将通过这个Layer将原来FrameBuffer上的数据进行抓取;

从这些Layer看出,我们分析的重点就是第一种Layer,下面我们着重分析一下普通的Layer。Layer的具体业务我们在下一篇文章中分析

1.4.2 Layer的管理

上文我们在分析SurfaceSession的时候,也分析过,一个Client可能会创建多个Surface,也就是要创建多个Layer,那么SurfaceFlinger端如何管理多个Layer呢?SurfaceFlinger维护了3个Vector来管理Layer<Client:DefaultKeyedVector< size_t, wp<LayerBaseClient> > mLayers;SurfaceFlinger:LayerVector layersSortedByZ;>。

第一种方式,我们知道SurfaceFlinger会为每个SurfaceSession创建一个Client对象,这第一种方式就是将所有为某一个SurfacSession创建的Layer保存在它对应的Client对象中。

SurfaceFlinger::createSurface()@SurfaceFlinger.cpp,调用路径如下:

SurfaceFlinger::addClientLayer->

client->attachLayer(lbc)->

mLayers.add(name, layer);

第二种方式,在SurfaceFlinger中以排序的方式保存下来。其调用路径如下:

SurfaceFlinger::addClientLayer->

SurfaceFlinger::addLayer_l->

mCurrentState.layersSortedByZ.add(layer)

第三种方式,将所有的创建的普通的Layer保存起来,以便Client Surface在请求实现Buffer时能够辨识Client Surface对应的Layer。

SurfaceFlinger::createSurface()@SurfaceFlinger.cpp

[cpp] view plain copy
  1. surfaceHandle=layer->getSurface();
  2. if(surfaceHandle!=0){
  3. params->token=token;
  4. params->identity=layer->getIdentity();
  5. if(normalLayer!=0){
  6. Mutex::Autolock_l(mStateLock);
  7. mLayerMap.add(layer->getSurfaceBinder(),normalLayer);
  8. }
  9. }

2. Surface 显示Buffer的存储管理

在前文介绍Client端的Surface形态的内容时,我们提到SurfaceControl中还会维护一个名为Surface对象,它定义在frameworks/base/libs/surfaceflinger/Surface.h中,它负责向LayerBaseClient::BSurface请求显示Buffer,同时将显示Buffer交给JAVA Surface的Canvas去绘制窗口,我们称这个Surface为Client Surface

2.1 窗口绘制

我们先从ViewRootImpl中分析一下,它是如何显示窗口View的,如何用到Client Surface请求的显示Buffer的。

draw()@ViewRoot.java

[cpp] view plain copy
  1. Canvascanvas;
  2. try{
  3. intleft=dirty.left;
  4. inttop=dirty.top;
  5. intright=dirty.right;
  6. intbottom=dirty.bottom;
  7. finallonglockCanvasStartTime;
  8. if(ViewDebug.DEBUG_LATENCY){
  9. lockCanvasStartTime=System.nanoTime();
  10. }
  11. canvas=surface.lockCanvas(dirty);
  12. if(ViewDebug.DEBUG_LATENCY){
  13. longnow=System.nanoTime();
  14. Log.d(TAG,"Latency:Spent"
  15. +((now-lockCanvasStartTime)*0.000001f)
  16. +"mswaitingforsurface.lockCanvas()");
  17. }
  18. if(left!=dirty.left||top!=dirty.top||right!=dirty.right||
  19. bottom!=dirty.bottom){
  20. mAttachInfo.mIgnoreDirtyState=true;
  21. }
  22. //TODO:Dothisinnative
  23. canvas.setDensity(mDensity);

上面的代码显示,JAVA Surface 会lock canvas。而Client Surface的创建就在这个过程中,即下面代码中的第一行getSurface().我们先不管Client Surface的创建,先看看Canvas是如何与Client Surface的显示Buffer关联的。

Surface_lockCanvas@android_view_Surface.cpp

[cpp] view plain copy
  1. staticjobjectSurface_lockCanvas(JNIEnv*env,jobjectclazz,jobjectdirtyRect)
  2. {
  3. constsp<Surface>&surface(getSurface(env,clazz));
  4. if(!Surface::isValid(surface)){
  5. doThrowIAE(env);
  6. return0;
  7. }
  8. //getdirtyregion
  9. RegiondirtyRegion;
  10. if(dirtyRect){
  11. Rectdirty;
  12. dirty.left=env->GetIntField(dirtyRect,ro.l);
  13. dirty.top=env->GetIntField(dirtyRect,ro.t);
  14. dirty.right=env->GetIntField(dirtyRect,ro.r);
  15. dirty.bottom=env->GetIntField(dirtyRect,ro.b);
  16. if(!dirty.isEmpty()){
  17. dirtyRegion.set(dirty);
  18. }
  19. }else{
  20. dirtyRegion.set(Rect(0x3FFF,0x3FFF));
  21. }
  22. Surface::SurfaceInfoinfo;
  23. status_terr=surface->lock(&info,&dirtyRegion);
  24. if(err<0){
  25. constchar*constexception=(err==NO_MEMORY)?
  26. OutOfResourcesException:
  27. "java/lang/IllegalArgumentException";
  28. jniThrowException(env,exception,NULL);
  29. return0;
  30. }
  31. //AssociateaSkCanvasobjecttothissurface
  32. jobjectcanvas=env->GetObjectField(clazz,so.canvas);
  33. env->SetIntField(canvas,co.surfaceFormat,info.format);
  34. SkCanvas*nativeCanvas=(SkCanvas*)env->GetIntField(canvas,no.native_canvas);
  35. SkBitmapbitmap;
  36. ssize_tbpr=info.s*bytesPerPixel(info.format);
  37. bitmap.setConfig(convertPixelFormat(info.format),info.w,info.h,bpr);
  38. if(info.format==PIXEL_FORMAT_RGBX_8888){
  39. bitmap.setIsOpaque(true);
  40. }
  41. if(info.w>0&&info.h>0){
  42. bitmap.setPixels(info.bits);
  43. }else{
  44. //besafewithanemptybitmap.
  45. bitmap.setPixels(NULL);
  46. }
  47. nativeCanvas->setBitmapDevice(bitmap);
  48. SkRegionclipReg;
  49. if(dirtyRegion.isRect()){//verycommoncase
  50. constRectb(dirtyRegion.getBounds());
  51. clipReg.setRect(b.left,b.top,b.right,b.bottom);
  52. }else{
  53. size_tcount;
  54. Rectconst*r=dirtyRegion.getArray(&count);
  55. while(count){
  56. clipReg.op(r->left,r->top,r->right,r->bottom,SkRegion::kUnion_Op);
  57. r++,count--;
  58. }
  59. }
  60. nativeCanvas->clipRegion(clipReg);
  61. intsaveCount=nativeCanvas->save();
  62. env->SetIntField(clazz,so.saveCount,saveCount);
  63. if(dirtyRect){
  64. constRect&bounds(dirtyRegion.getBounds());
  65. env->SetIntField(dirtyRect,ro.l,bounds.left);
  66. env->SetIntField(dirtyRect,ro.t,bounds.top);
  67. env->SetIntField(dirtyRect,ro.r,bounds.right);
  68. env->SetIntField(dirtyRect,ro.b,bounds.bottom);
  69. }
  70. returncanvas;
  71. }

上面的代码,我们可以看出,Canvas的Bitmap设备设置了Client Surface的显示Buffer为其Bitmap pixel存储空间。

[cpp] view plain copy
  1. bitmap.setPixels(info.bits);

这样Canvas的绘制空间就有了。下一步就该绘制窗口了。

draw()@ViewRootImpl.java

[cpp] view plain copy
  1. try{
  2. canvas.translate(0,-yoff);
  3. if(mTranslator!=null){
  4. mTranslator.translateCanvas(canvas);
  5. }
  6. canvas.setScreenDensity(scalingRequired
  7. ?DisplayMetrics.DENSITY_DEVICE:0);
  8. mAttachInfo.mSetIgnoreDirtyState=false;
  9. mView.draw(canvas);
  10. }


其中ViewRootImpl中的mView为整个窗口的View。它将Render自己和所有它的子View。

2.2Client Surface的初始化(SurfaceControl中的Surface)

Client Surface的创建是从ViewRootImpl首次Lock canvas时进行的,这么做的目的可能也是为了节约空间,减少不必要的开支。

Client Surface的初始化和显示Buffer的管理过程比较复杂,下图给出了这一部分的一个静态结构图,有些东西从图上表现不出来,下面我简单的介绍一下。

framework是如何与surfaceflinger进行业务交互的。

1)如何创建surface

2)如何显示窗口等等

所有的这一切都是通过系统服务WindowManagerService与surfaceflinger来进行的。

Android中的Surface机制这一块代码写的比较难理解,光叫Surface的类就有3个,因此本篇文章从两部分来分析。

首先,想要理解Surface机制,还是需要首先理清各个类之间的关系。

其次,在理解了整个Surface机制的类关系之后,到时我们再结合前一篇文章中对显示系统的介绍,研究一下一个Surface是如何和显示系统建立起联系来的,这个联系主要是指Surface的显示buffer的存储管理。

在下篇文章中,再分析SurfaceFlinger是如何将已经存储了窗口图形数据的Surface Buffer显示到显示系统中。

待续。。。。。

更多相关文章

  1. Android之菜单总结
  2. Android使用Retrofit进行网络请求
  3. Android官方入门文档[1]创建一个Android项目
  4. Android(安卓)P SystemUI之StatusBar UI布局status_bar.xml解析
  5. android 创建桌面快捷方式 、插件
  6. android用户界面-组件Widget-地图视图MapView
  7. AIR Native Extension的使用(Android)一 : 打包ane
  8. 创建android逐帧动画的两种方式
  9. Android中使Dialog显示时背景不变暗

随机推荐

  1. adb connect 失败时(unable to connect t
  2. Android(安卓)从网页中跳转到APP
  3. android 结束进程
  4. android view视图的层叠(叠加)
  5. android intent
  6. 一:android开发简介
  7. Android应用开发相关下载资源(2016/07/24
  8. Android(安卓)5.0以上Button,ImageView自
  9. 演化理解 Android(安卓)异步加载图片
  10. activity的android:name 设置问题