Android顯示系統設計框架介紹

轉載自http://www.cnblogs.com/shakin/p/4521803.html

1. Linux內核提供了統一的framebuffer顯示驅動,設備節點/dev/graphics/fb*或者/dev/fb*,以fb0表示第一個顯示屏,當前實現中只用到了一個顯示屏。

2. Android的HAL層提供了Gralloc,分爲fb和gralloc兩個設備。設備fb負責打開內核中的framebuffer以及提供post、 setSwapInterval等操作,設備gralloc則負責管理幀緩衝區的分配和釋放。上層只能通過Gralloc訪問幀緩衝區,這樣一來就實現了 有序的封裝保護。

3. 由於OpenGL ES是一個通用的函數庫,在不同的平臺系統上需要被“本地化”——即把它與具體平臺上的窗口系統建立起關聯,這樣才能保證它正常工作。從FramebufferNativeWindow就是將OpenGL ES在Android平臺上本地化窗口。

4. OpenGL或者OpenGL ES 更多的只是一個接口協議,實現上既可以採用軟件,也能依託於硬件。EGL通過讀取egl.cfg配置文件,根據用戶的設定來動態加載libagl(軟件實 現)或者libhgl(硬件實現)。然後上層纔可以正常使用各種glXXX接口。

5. SurfaceFlinger中持有一個GraphicPlane成員變量mGraphicPlanes來描述“顯示屏”;GraphicPlane類中 又包含了一個DisplayHardware對象實例(mHw)。DisplayHardware在初始化時還將調用eglInitialize、 eglCreateWindowSurface等接口,並利用EGL完成對OpenGLES環境的搭建。


本地窗口


Android提供了兩種本地窗口:

1)         面向SurfaceFlinger的FramebufferNativeWindow;

2)         面向應用程序的SurfaceTextureClient;

 

使用OpenGL繪製圖像前,需要通過EGL創建一個Surface畫板:

frameworks\native\opengl\libagl\ Egl.cpp

  1. EGLSurface eglCreateWindowSurface(  EGLDisplay dpy, EGLConfig config,  
  2.                                     NativeWindowType window,  
  3.                                     const EGLint *attrib_list)  
  4. {  
  5.     return createWindowSurface(dpy, config, window, attrib_list);  
  6. }  

OpenGL是跨平臺的圖形庫,不同平臺上的NativeWindowType窗口類型有不同的定義:

frameworks\native\opengl\include\egl\ Eglplatform.h

  1. typedef EGLNativeWindowType  NativeWindowType;  
  2.   
  3. #if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */  
  4. #ifndef WIN32_LEAN_AND_MEAN  
  5. #define WIN32_LEAN_AND_MEAN 1  
  6. #endif  
  7. #include <windows.h>  
  8.   
  9. typedef HDC     EGLNativeDisplayType;  
  10. typedef HBITMAP EGLNativePixmapType;  
  11. typedef HWND    EGLNativeWindowType;  
  12.   
  13. #elif defined(__WINSCW__) || defined(__SYMBIAN32__)  /* Symbian */  
  14.   
  15. typedef int   EGLNativeDisplayType;  
  16. typedef void *EGLNativeWindowType;  
  17. typedef void *EGLNativePixmapType;  
  18.   
  19. #elif defined(__ANDROID__) || defined(ANDROID)  
  20.   
  21. struct ANativeWindow;  
  22. struct egl_native_pixmap_t;  
  23.   
  24. typedef struct ANativeWindow*           EGLNativeWindowType;  
  25. typedef struct egl_native_pixmap_t*     EGLNativePixmapType;  
  26. typedef void*                           EGLNativeDisplayType;  
  27.   
  28. #elif defined(__unix__)  
  29.   
  30. /* X11 (tentative)  */  
  31. #include <X11/Xlib.h>  
  32. #include <X11/Xutil.h>  
  33.   
  34. typedef Display *EGLNativeDisplayType;  
  35. typedef Pixmap   EGLNativePixmapType;  
  36. typedef Window   EGLNativeWindowType;  
  37.   
  38. #else  
  39. #error "Platform not recognized"  
  40. #endif  

可以看出對於Android平臺,NativeWindowType的類型爲ANativeWindow

  1. struct ANativeWindow  
  2. {  
  3. #ifdef __cplusplus //C++定義  
  4.     ANativeWindow(): flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0)  
  5.     {  
  6.         common.magic = ANDROID_NATIVE_WINDOW_MAGIC;  
  7.         common.version = sizeof(ANativeWindow);  
  8.         memset(common.reserved, 0, sizeof(common.reserved));  
  9.     }  
  10.     /* Implement the methods that sp<ANativeWindow> expects so that it 
  11.        can be used to automatically refcount ANativeWindow's. */  
  12.     void incStrong(const void* id) const {  
  13.         common.incRef(const_cast<android_native_base_t*>(&common));  
  14.     }  
  15.     void decStrong(const void* id) const {  
  16.         common.decRef(const_cast<android_native_base_t*>(&common));  
  17.     }  
  18. #endif  
  19.     struct android_native_base_t common;  
  20.     /* flags describing some attributes of this surface or its updater */  
  21.     const uint32_t flags;  
  22.     /* min swap interval supported by this updated */  
  23.     const int   minSwapInterval;  
  24.     /* max swap interval supported by this updated */  
  25.     const int   maxSwapInterval;  
  26.     /* horizontal and vertical resolution in DPI */  
  27.     const float xdpi;  
  28.     const float ydpi;  
  29.     /* Some storage reserved for the OEM's driver. */  
  30.     intptr_t    oem[4];  
  31.     /* Set the swap interval for this surface. */  
  32.     int     (*setSwapInterval)(struct ANativeWindow* window,  
  33.                 int interval);  
  34.     /* 
  35.      * Hook called by EGL to acquire a buffer. After this call, the buffer 
  36.      * is not locked, so its content cannot be modified. This call may block if 
  37.      * no buffers are available. 
  38.      */  
  39.     int     (*dequeueBuffer)(struct ANativeWindow* window,  
  40.                 struct ANativeWindowBuffer** buffer);  
  41.     /* 
  42.      * hook called by EGL to lock a buffer. This MUST be called before modifying 
  43.      * the content of a buffer. The buffer must have been acquired with 
  44.      * dequeueBuffer first. 
  45.      */  
  46.     int     (*lockBuffer)(struct ANativeWindow* window,  
  47.                 struct ANativeWindowBuffer* buffer);  
  48.     /* 
  49.      * Hook called by EGL when modifications to the render buffer are done. 
  50.      * This unlocks and post the buffer. 
  51.      */  
  52.     int     (*queueBuffer)(struct ANativeWindow* window,  
  53.                 struct ANativeWindowBuffer* buffer);  
  54.     /* 
  55.      * hook used to retrieve information about the native window. 
  56.      */  
  57.     int     (*query)(const struct ANativeWindow* window,  
  58.                 int what, int* value);  
  59.     /* 
  60.      * hook used to perform various operations on the surface. 
  61.      * (*perform)() is a generic mechanism to add functionality to 
  62.      * ANativeWindow while keeping backward binary compatibility. 
  63.      * The valid operations are: 
  64.      *     NATIVE_WINDOW_SET_USAGE 
  65.      *     NATIVE_WINDOW_CONNECT               (deprecated) 
  66.      *     NATIVE_WINDOW_DISCONNECT            (deprecated) 
  67.      *     NATIVE_WINDOW_SET_CROP              (private) 
  68.      *     NATIVE_WINDOW_SET_BUFFER_COUNT 
  69.      *     NATIVE_WINDOW_SET_BUFFERS_GEOMETRY  (deprecated) 
  70.      *     NATIVE_WINDOW_SET_BUFFERS_TRANSFORM 
  71.      *     NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP 
  72.      *     NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS 
  73.      *     NATIVE_WINDOW_SET_BUFFERS_FORMAT 
  74.      *     NATIVE_WINDOW_SET_SCALING_MODE       (private) 
  75.      *     NATIVE_WINDOW_LOCK                   (private) 
  76.      *     NATIVE_WINDOW_UNLOCK_AND_POST        (private) 
  77.      *     NATIVE_WINDOW_API_CONNECT            (private) 
  78.      *     NATIVE_WINDOW_API_DISCONNECT         (private) 
  79.      *     NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS (private) 
  80.      *     NATIVE_WINDOW_SET_POST_TRANSFORM_CROP (private) 
  81.      * 
  82.      */  
  83.     int     (*perform)(struct ANativeWindow* window,  
  84.                 int operation, ... );  
  85.     /* 
  86.      * Hook used to cancel a buffer that has been dequeued. 
  87.      * No synchronization is performed between dequeue() and cancel(), so 
  88.      * either external synchronization is needed, or these functions must be 
  89.      * called from the same thread. 
  90.      */  
  91.     int     (*cancelBuffer)(struct ANativeWindow* window,  
  92.                 struct ANativeWindowBuffer* buffer);  
  93.     void* reserved_proc[2];  
  94. };  

無論是基於應用程序的本地窗口SurfaceTextureClient還是基於SurfaceFlinger的FramebufferNativeWindow本地窗口,都必須實現ANativeWindow定義的一套窗口協議,這樣應用程序和SurfaceFlinger才能使用OpenGL。ANativeWindow就相當於Java中的接口類型,只是用於定義窗口的功能函數,並不去實現這些函數,而是由需要使用OpenGL的對象來實現。

應用程序本地窗口

應用程序端的SurfaceTextureClient實現了ANativeWindow類型中定義的函數,這樣應用程序就可以使用OpenGL來繪製圖形圖像了,當然應用程序可以選擇性地使用OpenGL或是Skia。

SurfaceFlinger本地窗口

由於SurfaceFlinger必須要使用OpenGL來混合圖像,因此SurfaceFlinger端的FramebufferNativeWindow必須實現ANativeWindow類型。

Gralloc

通過加載gralloc抽象層,可以打開fb設備和gpu設備,fb設備用於操作framebuffer,gpu設備負責圖形緩衝區的分配和釋放。對於SurfaceFlinger服務端的本地窗口FramebufferNativeWindow將分別打開fb設備和gpu設備,FramebufferNativeWindow通過gpu設備從Framebuffer中分配圖形緩衝區,通過fb設備來渲染經SurfaceFlinger混合後的圖像。而對於應用程序端的SurfaceTextureClient本地窗口,其需要的圖形緩衝區也是由SurfaceFlinger服務端來分配,應用程序進程只需要將服務端分配的圖形緩衝區映射到應用程序的虛擬地址空間,圖形緩衝區的映射過程也是由Gralloc模塊完成。Android圖形顯示之硬件抽象層Gralloc對Gralloc模塊進行了詳細介紹,這裏只簡單帶過。

gpu、fb和gralloc模塊中定義的數據結構關係如下:

通過加載Gralloc動態庫,可以分別打開fb設備和gpu設備。

gpu設備

Gpu打開過程就是創建並初始化一個gralloc_context_t對象,gpu負責圖形buffer的分配和釋放。

  1. int gralloc_device_open(const hw_module_t* module, const char* name,  
  2.         hw_device_t** device)  
  3. {  
  4.     int status = -EINVAL;  
  5.     if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {  
  6.         gralloc_context_t *dev;  
  7.         dev = (gralloc_context_t*)malloc(sizeof(*dev));  
  8.   
  9.         /* initialize our state here */  
  10.         memset(dev, 0, sizeof(*dev));  
  11.   
  12.         /* initialize the procs */  
  13.         dev->device.common.tag = HARDWARE_DEVICE_TAG;  
  14.         dev->device.common.version = 0;  
  15.         dev->device.common.module = const_cast<hw_module_t*>(module);  
  16.         dev->device.common.close = gralloc_close;  
  17.   
  18.         dev->device.alloc   = gralloc_alloc;  
  19.         dev->device.free    = gralloc_free;  
  20.   
  21.         *device = &dev->device.common;  
  22.         status = 0;  
  23.     return status;  
  24. }  

fb設備

Fb設備打開過程就是創建並初始化一個fb_context_t對象,關於屏幕大小、格式、刷新頻率等信息都是通過Framebuffer驅動來獲取,最後將Framebuffer映射到SurfaceFlinger進程地址空間,並將映射後的首地址保持到private_module_t的framebuffer->base變量中。

  1. int fb_device_open(hw_module_t const* module, const char* name,  
  2.         hw_device_t** device)  
  3. {  
  4.     int status = -EINVAL;  
  5.     if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {  
  6.         alloc_device_t* gralloc_device;  
  7.         status = gralloc_open(module, &gralloc_device);  
  8.         if (status < 0)  
  9.             return status;  
  10.   
  11.         /* initialize our state here */  
  12.         fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev));  
  13.         memset(dev, 0, sizeof(*dev));  
  14.   
  15.         /* initialize the procs */  
  16.         dev->device.common.tag = HARDWARE_DEVICE_TAG;  
  17.         dev->device.common.version = 0;  
  18.         dev->device.common.module = const_cast<hw_module_t*>(module);  
  19.         dev->device.common.close = fb_close;  
  20.         dev->device.setSwapInterval = fb_setSwapInterval;  
  21.         dev->device.post            = fb_post;  
  22.         dev->device.setUpdateRect = 0;  
  23.   
  24.         private_module_t* m = (private_module_t*)module;  
  25.         status = mapFrameBuffer(m);  
  26.         if (status >= 0) {  
  27.             int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3);  
  28.             int format = (m->info.bits_per_pixel == 32)  
  29.                          ? HAL_PIXEL_FORMAT_RGBX_8888  
  30.                          : HAL_PIXEL_FORMAT_RGB_565;  
  31.             const_cast<uint32_t&>(dev->device.flags) = 0;  
  32.             const_cast<uint32_t&>(dev->device.width) = m->info.xres;  
  33.             const_cast<uint32_t&>(dev->device.height) = m->info.yres;  
  34.             const_cast<int&>(dev->device.stride) = stride;  
  35.             const_cast<int&>(dev->device.format) = format;  
  36.             const_cast<float&>(dev->device.xdpi) = m->xdpi;  
  37.             const_cast<float&>(dev->device.ydpi) = m->ydpi;  
  38.             const_cast<float&>(dev->device.fps) = m->fps;  
  39.             const_cast<int&>(dev->device.minSwapInterval) = 1;  
  40.             const_cast<int&>(dev->device.maxSwapInterval) = 1;  
  41.             *device = &dev->device.common;  
  42.         }  
  43.     }  
  44.     return status;  
  45. }  

爲了方便應用程序及SurfaceFlinger使用Gralloc模塊中的fb設備和gpu設備,Android對gpu設備進行了封裝。我們知道,SurfaceFlinger不僅負責FramebufferNativeWindow本地窗口的圖形buffer的分配,同時也負責應用程序本地窗口SurfaceTextureClient的圖形buffer分配,應用程序只需將服務端分配的圖形buffer映射到當前進程的虛擬地址空間即可,因此應用程序和SurfaceFlinger都將會使用到Gralloc模塊。


SurfaceSession建立過程


SurfaceSession對象承擔了應用程序與SurfaceFlinger之間的通信過程,每一個需要與SurfaceFlinger進程交互的應用程序端都需要創建一個SurfaceSession對象。

客戶端請求

frameworks\base\core\java\android\view\SurfaceSession.java

  1. public SurfaceSession() {  
  2.     init();  
  3. }  

Java層的SurfaceSession對象構造過程會通過JNI在native層創建一個SurfaceComposerClient對象。

frameworks\base\core\jni\android_view_Surface.cpp

  1. static void SurfaceSession_init(JNIEnv* env, jobject clazz)  
  2. {  
  3.     sp<SurfaceComposerClient> client = new SurfaceComposerClient;  
  4.     client->incStrong(clazz);  
  5.     env->SetIntField(clazz, sso.client, (int)client.get());  
  6. }  

Java層的SurfaceSession對象與C++層的SurfaceComposerClient對象之間是一對一關係。

frameworks\native\libs\gui\SurfaceComposerClient.cpp

  1. SurfaceComposerClient::SurfaceComposerClient()  
  2.     : mStatus(NO_INIT), mComposer(Composer::getInstance())  
  3. {  
  4. }  

SurfaceComposerClient繼承於RefBase類,當第一次被強引用時,onFirstRef函數被回調,在該函數中SurfaceComposerClient會請求SurfaceFlinger爲當前應用程序創建一個Client對象,專門接收該應用程序的請求,在SurfaceFlinger端創建好Client本地Binder對象後,將該Binder代理對象返回給應用程序端,並保存在SurfaceComposerClient的成員變量mClient中。

  1. void SurfaceComposerClient::onFirstRef() {  
  2.     //得到SurfaceFlinger的代理對象BpSurfaceComposer  
  3.     sp<ISurfaceComposer> sm(getComposerService());  
  4.     if (sm != 0) {  
  5.         sp<ISurfaceComposerClient> conn = sm->createConnection();  
  6.         if (conn != 0) {  
  7.             mClient = conn;  
  8.             mStatus = NO_ERROR;  
  9.         }  
  10.     }  
  11. }  

服務端處理

在SurfaceFlinger服務端爲應用程序創建交互的Client對象

frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp

  1. sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()  
  2. {  
  3.     sp<ISurfaceComposerClient> bclient;  
  4.     sp<Client> client(new Client(this));  
  5.     status_t err = client->initCheck();  
  6.     if (err == NO_ERROR) {  
  7.         bclient = client;  
  8.     }  
  9.     return bclient;  
  10. }  



關於SurfaceFlinger服務代理對象獲取的詳細過程請查看Android SurfaceFlinger服務代理對象獲取過程源碼分析

 

Surface創建過程

 

客戶端請求

frameworks\base\core\java\android\view\Surface.java

  1. public Surface(SurfaceSession s,int pid, String name, int display, int w, int h, int format, int flags)  
  2.     throws OutOfResourcesException {  
  3.     checkHeadless();  
  4.     if (DEBUG_RELEASE) {  
  5.         mCreationStack = new Exception();  
  6.     }  
  7.     mCanvas = new CompatibleCanvas();  
  8.     init(s,pid,name,display,w,h,format,flags);  
  9.     mName = name;  
  10. }  

frameworks\base\core\jni\android_view_Surface.cpp

  1. static void Surface_init(JNIEnv* env, jobject clazz,jobject session,jint, jstring jname, jint dpy,   
  2. jint w, jint h, jint format, jint flags)  
  3. {  
  4.     if (session == NULL) {  
  5.         doThrowNPE(env);  
  6.         return;  
  7. }  
  8. //取得SurfaceComposerClient對象  
  9.     SurfaceComposerClient* client =  
  10.             (SurfaceComposerClient*)env->GetIntField(session, sso.client);  
  11.     //調用SurfaceComposerClient的createSurface函數在SurfaceFlinger服務端創建Layer對象,並返回ISurface  
  12.     //代理對象,並通過ISurface代理對象在應用程序端創建一個SurfaceControl對象,用於控制Surface  
  13.     sp<SurfaceControl> surface;  
  14.     if (jname == NULL) {  
  15.         surface = client->createSurface(dpy, w, h, format, flags);  
  16.     } else {  
  17.         const jchar* str = env->GetStringCritical(jname, 0);  
  18.         const String8 name(str, env->GetStringLength(jname));  
  19.         env->ReleaseStringCritical(jname, str);  
  20.         surface = client->createSurface(name, dpy, w, h, format, flags);  
  21.     }  
  22.     if (surface == 0) {  
  23.         jniThrowException(env, OutOfResourcesException, NULL);  
  24.         return;  
  25. }  
  26. //將創建的SurfaceControl對象指針保存到Java層的Surface的成員變量mSurfaceControl中  
  27.     setSurfaceControl(env, clazz, surface);  
  28. }  

該函數首先得到前面創建好的SurfaceComposerClient對象,通過該對象向SurfaceFlinger端的Client對象發送創建Surface的請求,最後得到一個SurfaceControl對象。

frameworks\native\libs\gui\SurfaceComposerClient.cpp

  1. sp<SurfaceControl> SurfaceComposerClient::createSurface(  
  2.         const String8& name,  
  3.         DisplayID display,  
  4.         uint32_t w,  
  5.         uint32_t h,  
  6.         PixelFormat format,  
  7.         uint32_t flags)  
  8. {  
  9.     sp<SurfaceControl> result;  
  10. if (mStatus == NO_ERROR) {  
  11.     //通過IsurfaceComposerClient的代理對象請求服務端的Client創建Surface  
  12.         ISurfaceComposerClient::surface_data_t data;  
  13.         sp<ISurface> surface = mClient->createSurface(&data, name,  
  14.                 display, w, h, format, flags);  
  15.         //通過ISurface的代理對象創建SurfaceControl  
  16.         if (surface != 0) {  
  17.             result = new SurfaceControl(this, surface, data);  
  18.         }  
  19.     }  
  20.     return result;  
  21. }  

SurfaceComposerClient將Surface創建請求轉交給保存在其成員變量中的Bp SurfaceComposerClient對象來完成,在SurfaceFlinger端的Client本地對象會返回一個ISurface代理對象給應用程序,通過該代理對象爲應用程序當前創建的Surface創建一個SurfaceControl對象。

frameworks\native\include\gui\ISurfaceComposerClient.h

  1. virtual sp<ISurface> createSurface( surface_data_t* params,  
  2.                                         const String8& name,  
  3.                                         DisplayID display,  
  4.                                         uint32_t w,  
  5.                                         uint32_t h,  
  6.                                         PixelFormat format,  
  7.                                         uint32_t flags)  
  8.     {  
  9.         Parcel data, reply;  
  10.         data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());  
  11.         data.writeString8(name);  
  12.         data.writeInt32(display);  
  13.         data.writeInt32(w);  
  14.         data.writeInt32(h);  
  15.         data.writeInt32(format);  
  16.         data.writeInt32(flags);  
  17.         remote()->transact(CREATE_SURFACE, data, &reply);  
  18.         params->readFromParcel(reply);  
  19.         return interface_cast<ISurface>(reply.readStrongBinder());  
  20.     }  

服務端處理

frameworks\native\include\gui\ISurfaceComposerClient.h

  1. status_t BnSurfaceComposerClient::onTransact(  
  2.     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  
  3. {  
  4.      switch(code) {  
  5.         case CREATE_SURFACE: {  
  6.             CHECK_INTERFACE(ISurfaceComposerClient, data, reply);  
  7.             surface_data_t params;  
  8.             String8 name = data.readString8();  
  9.             DisplayID display = data.readInt32();  
  10.             uint32_t w = data.readInt32();  
  11.             uint32_t h = data.readInt32();  
  12.             PixelFormat format = data.readInt32();  
  13.             uint32_t flags = data.readInt32();  
  14.             //Client繼承於BnSurfaceComposerClient,調用Client的createSurface函數處理  
  15.             sp<ISurface> s = createSurface(¶ms, name, display, w, h,  
  16.                     format, flags);  
  17.             params.writeToParcel(reply);  
  18.             reply->writeStrongBinder(s->asBinder());  
  19.             return NO_ERROR;  
  20.         } break;  
  21.         default:  
  22.             return BBinder::onTransact(code, data, reply, flags);  
  23.     }  
  24. }  

frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp$ Client

  1. sp<ISurface> Client::createSurface(  
  2.         ISurfaceComposerClient::surface_data_t* params,  
  3.         const String8& name,  
  4.         DisplayID display, uint32_t w, uint32_t h, PixelFormat format,  
  5.         uint32_t flags)  
  6. {  
  7.     sp<MessageBase> msg = new MessageCreateSurface(mFlinger.get(),  
  8.             params, name, this, display, w, h, format, flags);  
  9.     //將Surface創建請求轉換爲異步消息處理方式發送到SurfaceFlinger消息隊列中,由SurfaceFlinger服務來完成  
  10.     mFlinger->postMessageSync(msg);  
  11.     return static_cast<MessageCreateSurface*>( msg.get() )->getResult();  
  12. }  

MessageCreateSurface消息是專門爲應用程序請求創建Surface而定義的一種消息類型:

  1. /* 
  2.  * createSurface must be called from the GL thread so that it can 
  3.  * have access to the GL context. 
  4.  */  
  5. class MessageCreateSurface : public MessageBase {  
  6.     sp<ISurface> result;  
  7.     SurfaceFlinger* flinger;  
  8.     ISurfaceComposerClient::surface_data_t* params;  
  9.     Client* client;  
  10.     const String8& name;  
  11.     DisplayID display;  
  12.     uint32_t w, h;  
  13.     PixelFormat format;  
  14.     uint32_t flags;  
  15. public:  
  16.     MessageCreateSurface(SurfaceFlinger* flinger,  
  17.             ISurfaceComposerClient::surface_data_t* params,  
  18.             const String8& name, Client* client,  
  19.             DisplayID display, uint32_t w, uint32_t h, PixelFormat format,uint32_t flags)  
  20.         : flinger(flinger), params(params), client(client), name(name),display(display),  
  21.         w(w), h(h), format(format), flags(flags)  
  22.     {  
  23.     }  
  24.     sp<ISurface> getResult() const { return result; }  
  25.     //MessageCreateSurface消息的處理過程  
  26.     virtual bool handler() {  
  27.         result = flinger->createSurface(params, name, client,  
  28.                 display, w, h, format, flags);  
  29.         return true;  
  30.     }  
  31. };  

Client將應用程序創建Surface的請求轉換爲異步消息投遞到SurfaceFlinger的消息隊列中,將創建Surface的任務轉交給SurfaceFlinger。

frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp

  1. sp<ISurface> SurfaceFlinger::createSurface(  
  2.         ISurfaceComposerClient::surface_data_t* params,  
  3.         const String8& name,  
  4.         const sp<Client>& client,  
  5.         DisplayID d, uint32_t w, uint32_t h, PixelFormat format,  
  6.         uint32_t flags)  
  7. {  
  8.     sp<LayerBaseClient> layer;  
  9.     sp<ISurface> surfaceHandle;  
  10.     if (int32_t(w|h) < 0) {  
  11.         ALOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",int(w), int(h));  
  12.         return surfaceHandle;  
  13.     }  
  14.     //ALOGD("createSurface for (%d x %d), name=%s", w, h, name.string());  
  15.     sp<Layer> normalLayer;  
  16.     //根據flags創建不同類型的Surface  
  17.     switch (flags & eFXSurfaceMask) {  
  18.         case eFXSurfaceNormal:  
  19.             normalLayer = createNormalSurface(client, d, w, h, flags, format);  
  20.             layer = normalLayer;  
  21.             break;  
  22.         case eFXSurfaceBlur:  
  23.             // for now we treat Blur as Dim, until we can implement it  
  24.             // efficiently.  
  25.         case eFXSurfaceDim:  
  26.             layer = createDimSurface(client, d, w, h, flags);  
  27.             break;  
  28.         case eFXSurfaceScreenshot:  
  29.             layer = createScreenshotSurface(client, d, w, h, flags);  
  30.             break;  
  31.     }  
  32.     //爲客戶端的Surface創建好Layer對象  
  33.     if (layer != 0) {  
  34.         layer->initStates(w, h, flags);  
  35.         layer->setName(name);  
  36.         //將創建好的Layer對象保存在Client中  
  37.         ssize_t token = addClientLayer(client, layer);  
  38.         //創建BSurface本地Binder對象  
  39.         surfaceHandle = layer->getSurface();  
  40.         if (surfaceHandle != 0) {  
  41.             //token爲當前Layer對象在Client中的id號  
  42.             params->token = token;  
  43.             //Identity是每個Layer對象標號,SurfaceFlinger每創建一個Layer對象,自動加1  
  44.             params->identity = layer->getIdentity();  
  45.             //將創建好的Layer對象保存在SurfaceFlinger中  
  46.             if (normalLayer != 0) {  
  47.                 Mutex::Autolock _l(mStateLock);  
  48.                 mLayerMap.add(layer->getSurfaceBinder(), normalLayer);  
  49.             }  
  50.         }  
  51.         setTransactionFlags(eTransactionNeeded);  
  52.     }  
  53.     return surfaceHandle;  
  54. }  

SurfaceFlinger根據標誌位創建對應類型的Surface,當前系統定義了5種類型的Surface:


普遍Surface的創建過程:

  1. sp<Layer> SurfaceFlinger::createNormalSurface(  
  2.         const sp<Client>& client, DisplayID display,  
  3.         uint32_t w, uint32_t h, uint32_t flags,  
  4.         PixelFormat& format)  
  5. {  
  6.     // initialize the surfaces  
  7.     switch (format) { // TODO: take h/w into account  
  8.     case PIXEL_FORMAT_TRANSPARENT:  
  9.     case PIXEL_FORMAT_TRANSLUCENT:  
  10.         format = PIXEL_FORMAT_RGBA_8888;  
  11.         break;  
  12.     case PIXEL_FORMAT_OPAQUE:  
  13. #ifdef NO_RGBX_8888  
  14.         format = PIXEL_FORMAT_RGB_565;  
  15. #else  
  16.         format = PIXEL_FORMAT_RGBX_8888;  
  17. #endif  
  18.         break;  
  19.     }  
  20. #ifdef NO_RGBX_8888  
  21.     if (format == PIXEL_FORMAT_RGBX_8888)  
  22.         format = PIXEL_FORMAT_RGBA_8888;  
  23. #endif  
  24.     //在SurfaceFlinger端爲應用程序的Surface創建對應的Layer對象  
  25.     sp<Layer> layer = new Layer(this, display, client);  
  26.     status_t err = layer->setBuffers(w, h, format, flags);  
  27.     if (CC_LIKELY(err != NO_ERROR)) {  
  28.         ALOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));  
  29.         layer.clear();  
  30.     }  
  31.     return layer;  
  32. }  

在SurfaceFlinger服務端爲應用程序創建的Surface創建對應的Layer對象。應用程序請求創建Surface過程如下:

 

Layer構造過程

frameworks\native\services\surfaceflinger\LayerBase.cpp

  1. LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)  
  2.     : dpy(display), contentDirty(false),  
  3.       sequence(uint32_t(android_atomic_inc(&sSequence))),  
  4.       mFlinger(flinger), mFiltering(false),  
  5.       mNeedsFiltering(false),  
  6.       mOrientation(0),  
  7.       mPlaneOrientation(0),  
  8.       mTransactionFlags(0),  
  9.       mPremultipliedAlpha(true), mName("unnamed"), mDebug(false)  
  10. {  
  11.     const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());  
  12.     mFlags = hw.getFlags();  
  13. }  

 

  1. LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,  
  2.         const sp<Client>& client)  
  3.     : LayerBase(flinger, display),  
  4.       mHasSurface(false),  
  5.       mClientRef(client),  
  6.     //爲每個Layer對象分配一個唯一的標示號  
  7.       mIdentity(uint32_t(android_atomic_inc(&sIdentity)))  
  8. {  
  9. }  

frameworks\native\services\surfaceflinger\Layer.cpp

  1. Layer::Layer(SurfaceFlinger* flinger,  
  2.         DisplayID display, const sp<Client>& client)  
  3.     :   LayerBaseClient(flinger, display, client),  
  4.         mTextureName(-1U),  
  5.         mQueuedFrames(0),  
  6.         mCurrentTransform(0),  
  7.         mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),  
  8.         mCurrentOpacity(true),  
  9.         mRefreshPending(false),  
  10.         mFrameLatencyNeeded(false),  
  11.         mFrameLatencyOffset(0),  
  12.         mFormat(PIXEL_FORMAT_NONE),  
  13.         mGLExtensions(GLExtensions::getInstance()),  
  14.         mOpaqueLayer(true),  
  15.         mNeedsDithering(false),  
  16.         mSecure(false),  
  17.         mProtectedByApp(false)  
  18. {  
  19.     mCurrentCrop.makeInvalid();  
  20.     glGenTextures(1, &mTextureName);  
  21. }  

第一次強引用Layer對象時,onFirstRef()函數被回調

  1. void Layer::onFirstRef()  
  2. {  
  3.     LayerBaseClient::onFirstRef();  
  4.     //創建BufferQueue對象  
  5. sp<BufferQueue> bq = new SurfaceTextureLayer();  
  6.     //創建SurfaceTexture對象  
  7.     mSurfaceTexture = new SurfaceTexture(mTextureName, true,  
  8.             GL_TEXTURE_EXTERNAL_OES, false, bq);  
  9.     mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));  
  10.     //設置buffer可用監聽,生產者就是通過回調機制來通知消費者buffer數據已經填充好了  
  11.     mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));  
  12.     //設置同步模式  
  13.     mSurfaceTexture->setSynchronousMode(true);  
  14.     //設置緩衝區個數  
  15. #ifdef TARGET_DISABLE_TRIPLE_BUFFERING  
  16. #warning "disabling triple buffering"  
  17.     mSurfaceTexture->setBufferCountServer(2);  
  18. #else  
  19.     mSurfaceTexture->setBufferCountServer(3);  
  20. #endif  
  21. }  

BufferQueue構造過程

frameworks\native\libs\gui\ SurfaceTexture.cpp

  1. SurfaceTextureLayer::SurfaceTextureLayer()  
  2.     : BufferQueue(true) {  
  3. }  

frameworks\native\libs\gui\BufferQueue.cpp

  1. BufferQueue::BufferQueue(  bool allowSynchronousMode, int bufferCount ) :  
  2.     mDefaultWidth(1),  
  3.     mDefaultHeight(1),  
  4.     mPixelFormat(PIXEL_FORMAT_RGBA_8888),  
  5.     mMinUndequeuedBuffers(bufferCount),  
  6.     mMinAsyncBufferSlots(bufferCount + 1),  
  7.     mMinSyncBufferSlots(bufferCount),  
  8.     mBufferCount(mMinAsyncBufferSlots),  
  9.     mClientBufferCount(0),  
  10.     mServerBufferCount(mMinAsyncBufferSlots),  
  11.     mSynchronousMode(false),  
  12.     mAllowSynchronousMode(allowSynchronousMode),  
  13.     mConnectedApi(NO_CONNECTED_API),  
  14.     mAbandoned(false),  
  15.     mFrameCounter(0),  
  16.     mBufferHasBeenQueued(false),  
  17.     mDefaultBufferFormat(0),  
  18.     mConsumerUsageBits(0),  
  19.     mTransformHint(0)  
  20. {  
  21.     // Choose a name using the PID and a process-unique ID.  
  22.     mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());  
  23.     ST_LOGV("BufferQueue");  
  24.     //由於BufferQueue與SurfaceFlinger處於同一進程中,因此這裏獲取到SurfaceFlinger的本地Binder對象  
  25.     sp<ISurfaceComposer> composer(ComposerService::getComposerService());  
  26.     //通過SurfaceFlinger來創建圖形buffer分配器  
  27.     mGraphicBufferAlloc = composer->createGraphicBufferAlloc();  
  28.     if (mGraphicBufferAlloc == 0) {  
  29.         ST_LOGE("createGraphicBufferAlloc() failed in BufferQueue()");  
  30.     }  
  31. }  

GraphicBufferAlloc構造過程

frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp

  1. sp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()  
  2. {  
  3.     sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());  
  4.     return gba;  
  5. }  

SurfaceTexture構造過程

frameworks\native\libs\gui\ SurfaceTexture.cpp

  1. SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,  
  2.         GLenum texTarget, bool useFenceSync, const sp<BufferQueue> &bufferQueue) :  
  3.     mCurrentTransform(0),  
  4.     mCurrentTimestamp(0),  
  5.     mFilteringEnabled(true),  
  6.     mTexName(tex),  
  7. #ifdef USE_FENCE_SYNC  
  8.     mUseFenceSync(useFenceSync),  
  9. #else  
  10.     mUseFenceSync(false),  
  11. #endif  
  12.     mTexTarget(texTarget),  
  13.     mEglDisplay(EGL_NO_DISPLAY),  
  14.     mEglContext(EGL_NO_CONTEXT),  
  15.     mAbandoned(false),  
  16.     mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT),  
  17.     mAttached(true)  
  18. {  
  19.     // Choose a name using the PID and a process-unique ID.  
  20.     mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());  
  21.     ST_LOGV("SurfaceTexture");  
  22.     if (bufferQueue == 0) {  
  23.         ST_LOGV("Creating a new BufferQueue");  
  24.         mBufferQueue = new BufferQueue(allowSynchronousMode);  
  25.     }  
  26.     else {  
  27.         mBufferQueue = bufferQueue;  
  28.     }  
  29.     memcpy(mCurrentTransformMatrix, mtxIdentity,  
  30.             sizeof(mCurrentTransformMatrix));  
  31.     // Note that we can't create an sp<...>(this) in a ctor that will not keep a  
  32.     // reference once the ctor ends, as that would cause the refcount of 'this'  
  33.     // dropping to 0 at the end of the ctor.  Since all we need is a wp<...>  
  34.     // that's what we create.  
  35.     wp<BufferQueue::ConsumerListener> listener;  
  36.     sp<BufferQueue::ConsumerListener> proxy;  
  37.     //將當前SurfaceTexture對象保存到ProxyConsumerListener成員變量中,由ProxyConsumerListener  
  38.     //來代理接收FrameAvailable通知  
  39.     listener = static_cast<BufferQueue::ConsumerListener*>(this);  
  40.     proxy = new BufferQueue::ProxyConsumerListener(listener);  
  41.     //將ProxyConsumerListener對象設置到BufferQueue中,當buffer可被消費時,由BufferQueue  
  42.     //通知ProxyConsumerListener。BufferQueueProxyConsumerListenerSurfaceTexture  
  43.     status_t err = mBufferQueue->consumerConnect(proxy);  
  44.     if (err != NO_ERROR) {  
  45.         ST_LOGE("SurfaceTexture: error connecting to BufferQueue: %s (%d)",  
  46.                 strerror(-err), err);  
  47.     } else {  
  48.         mBufferQueue->setConsumerName(mName);  
  49.         mBufferQueue->setConsumerUsageBits(DEFAULT_USAGE_FLAGS);  
  50.     }  
  51. }  

根據buffer可用監聽器的註冊過程,我們知道,當生產者也就是應用程序填充好圖形buffer數據後,通過回調方式通知消費者的過程如下:


在服務端爲Surface創建Layer過程中,分別創建了SurfaceTexture、BufferQueue和GraphicBufferAlloc對象,它們之間的關係如下:

ISurface本地對象創建過程

以上完成Layer對象創建後,通過layer->getSurface()來創建ISurface的Binder本地對象,並將其代理對象返回給應用程序。

frameworks\native\services\surfaceflinge\ Layer.cpp

  1. sp<ISurface> Layer::createSurface()  
  2. {  
  3.     sp<ISurface> sur(new BSurface(mFlinger, this));  
  4.     return sur;  
  5. }  

總結一下Surface創建過程,應用程序通過SurfaceComposerClient請求SurfaceFlinger創建一個Surface,在SurfaceFlinger服務端將會創建的對象有:

1.         一個Layer對象:

2.         一個SurfaceTexture對象

3.         一個BufferQueue對象:用於管理當前創建的Surface的圖形buffer

4.         一個GraphicBufferAlloc對象:用於分配圖形buffer

5.         一個BSurface本地Binder對象:用於獲取BufferQueue的Binder代理對象

關於Surface創建過程的詳細分析請參考Android應用程序創建Surface過程源碼分析。Android在SurfaceFlinger進程爲應用程序定義了4個Binder對象:

1.         SurfaceFlinger: 有名Binder對象,可通過服務查詢方式獲取;

2.         Client:                 無名Binder對象,只能由SurfaceFlinger服務創建;

3.         BSurface:           無名Binder對象,只能由Client服務創建;

4.         BufferQueue:      無名Binder對象,只能通過BSurface服務返回;

以上各個Binder對象提供的接口函數如下所示:


應用程序本地窗口Surface創建過程


從前面分析可知,SurfaceFlinger在處理應用程序請求創建Surface中,在SurfaceFlinger服務端僅僅創建了Layer對象,那麼應用程序本地窗口Surface在什麼時候、什麼地方創建呢?

我們知道Surface繼承於SurfaceTextureClient,而SurfaceTextureClient是面向應用程序的本地創建,因此它就應該是在應用程序進程中創建。在前面的分析中,我們也知道,SurfaceFlinger

爲應用程序創建好了Layer對象並返回ISurface的代理對象給應用程序,應用程序通過該代理對象創建了一個SurfaceControl對象,Java層Surface需要通過android_view_Surface.cpp中的JNI函數來操作native層的Surface,在操作native層Surface前,首先需要獲取到native的Surface,應用程序本地窗口Surface就是在這個時候創建的。

frameworks\base\core\jni\android_view_Surface.cpp

  1. static sp<Surface> getSurface(JNIEnv* env, jobject clazz)  
  2. {  
  3.     //從Java層的Surface對象中獲取native的Surface對象指針  
  4.     sp<Surface> result(Surface_getSurface(env, clazz));  
  5.     //native Surface還未創建  
  6.     if (result == 0) {  
  7.         /* 
  8.          * if this method is called from the WindowManager's process, it means 
  9.          * the client is is not remote, and therefore is allowed to have 
  10.          * a Surface (data), so we create it here. 
  11.          * If we don't have a SurfaceControl, it means we're in a different 
  12.          * process. 
  13.          */  
  14.         SurfaceControl* const control =  
  15.             (SurfaceControl*)env->GetIntField(clazz, so.surfaceControl);  
  16.         if (control) {  
  17.             //創建native Surface  
  18.             result = control->getSurface();  
  19.             if (result != 0) {  
  20.                 result->incStrong(clazz);  
  21.                 env->SetIntField(clazz, so.surface, (int)result.get());  
  22.             }  
  23.         }  
  24.     }  
  25.     return result;  
  26. }  

frameworks\native\libs\gui\Surface.cpp

  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.         //構造應用程序本地窗口  
  7.         mSurfaceData = new Surface(surface_control);  
  8.     }  
  9.     return mSurfaceData;  
  10. }  

 

  1. Surface::Surface(const sp<SurfaceControl>& surface)  
  2.     : SurfaceTextureClient(),  
  3.       mSurface(surface->mSurface),  
  4.       mIdentity(surface->mIdentity)  
  5. {  
  6.     sp<ISurfaceTexture> st;  
  7.     if (mSurface != NULL) {  
  8.         st = mSurface->getSurfaceTexture();  
  9.     }  
  10.     init(st);  
  11. }  

Surface繼承於SurfaceTextureClient類,在構造Surface時,首先會調用SurfaceTextureClient的構造函數:

frameworks\native\libs\gui\SurfaceTextureClient.cpp

  1. SurfaceTextureClient::SurfaceTextureClient() {  
  2.     SurfaceTextureClient::init();  
  3. }  

 

  1. void SurfaceTextureClient::init() {  
  2.     // Initialize the ANativeWindow function pointers.  
  3.     ANativeWindow::setSwapInterval  = hook_setSwapInterval;  
  4.     ANativeWindow::dequeueBuffer    = hook_dequeueBuffer;  
  5.     ANativeWindow::cancelBuffer     = hook_cancelBuffer;  
  6.     ANativeWindow::lockBuffer       = hook_lockBuffer;  
  7.     ANativeWindow::queueBuffer      = hook_queueBuffer;  
  8.     ANativeWindow::query            = hook_query;  
  9.     ANativeWindow::perform          = hook_perform;  
  10.     const_cast<int&>(ANativeWindow::minSwapInterval) = 0;  
  11.     const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;  
  12.     mReqWidth = 0;  
  13.     mReqHeight = 0;  
  14.     mReqFormat = 0;  
  15.     mReqUsage = 0;  
  16.     mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;  
  17.     mCrop.clear();  
  18.     mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;  
  19.     mTransform = 0;  
  20.     mDefaultWidth = 0;  
  21.     mDefaultHeight = 0;  
  22.     mUserWidth = 0;  
  23.     mUserHeight = 0;  
  24.     mTransformHint = 0;  
  25.     mConsumerRunningBehind = false;  
  26.     mConnectedToCpu = false;  
  27. }  

父類SurfaceTextureClient構造完成後,通過ISurface的代理對象BpSurface請求BSurface獲取BufferQueue的代理對象。

frameworks\native\services\surfaceflinge\ Layer.cpp

  1. class BSurface : public BnSurface, public LayerCleaner {  
  2.     wp<const Layer> mOwner;  
  3.     virtual sp<ISurfaceTexture> getSurfaceTexture() const {  
  4.         sp<ISurfaceTexture> res;  
  5.         sp<const Layer> that( mOwner.promote() );  
  6.         if (that != NULL) {  
  7.             res = that->mSurfaceTexture->getBufferQueue();  
  8.         }  
  9.         return res;  
  10.     }  
  11. public:  
  12.     BSurface(const sp<SurfaceFlinger>& flinger,const sp<Layer>& layer)  
  13.         : LayerCleaner(flinger, layer), mOwner(layer) { }  
  14. };  

最後調用Surface的init函數進行初始化

frameworks\native\libs\gui\Surface.cpp

  1. void Surface::init(const sp<ISurfaceTexture>& surfaceTexture)  
  2. {  
  3.     if (mSurface != NULL || surfaceTexture != NULL) {  
  4.         ALOGE_IF(surfaceTexture==0, "got a NULL ISurfaceTexture from ISurface");  
  5.         if (surfaceTexture != NULL) {  
  6.             setISurfaceTexture(surfaceTexture);  
  7.             setUsage(GraphicBuffer::USAGE_HW_RENDER);  
  8.         }  
  9.   
  10.         DisplayInfo dinfo;  
  11.         SurfaceComposerClient::getDisplayInfo(0, &dinfo);  
  12.         const_cast<float&>(ANativeWindow::xdpi) = dinfo.xdpi;  
  13.         const_cast<float&>(ANativeWindow::ydpi) = dinfo.ydpi;  
  14.         const_cast<uint32_t&>(ANativeWindow::flags) = 0;  
  15.     }  
  16. }  

到此應用程序的本地窗口Surface就創建完成了,通過上面的分析,可以知道,應用程序本地窗口的創建會在應用程序進程和SurfaceFlinger進程分別創建不同的對象:

1. SurfaceFlinger進程:Layer、SurfaceTexture、BufferQueue等;

2. 應用程序進程:Surface、SurfaceControl、SurfaceComposerClient等;

ISurfaceTexture是應用程序與BufferQueue的傳輸通道。
ISurfaceComposerClient是應用程序與SurfaceFlinger間的橋樑,在應用進程中則被封裝在SurfaceComposerClient這個類中。這是一個匿名binder server,由應用程序調用SurfaceFlinger這個實名binder的createConnection方法來獲取到,服務端的實現是SurfaceFlinger::Client。任何有UI界面的程序都在SurfaceFlinger中有且僅有一個Client實例。
ISurface:由應用程序調用ISurfaceComposerClient::createSurface()得到,同時在SurfaceFlinger這一進程中將會有一個Layer被創建,代表了一個“畫面”。ISurface就是控制這一畫面的handle。
Surface:從邏輯關係上看,它是上述ISurface的使用者。從繼承關係上看,它是一個SurfaceTextureClient,也就是本地窗口。SurfaceTextureClient內部持有ISurfaceTexture,即BufferQueue的實現接口。
以上Surface、Layer、SurfaceTexture、BufferQueue,應用程序和Client之間的關係如下圖所示:



Surface的圖形buffer申請過程


在創建完應用程序本地窗口Surface後,想要在該Surface上繪圖,首先需要爲該Surface分配圖形buffer。我們前面介紹了Android應用程序圖形緩衝區的分配都是由SurfaceFlinger服務進程來完成,在請求創建Surface時,在服務端創建了一個BufferQueue本地Binder對象,該對象負責管理應用程序一個本地窗口Surface的圖形緩衝區。在BufferQueue中定義了圖形buffer的四個狀態:

  1. enum BufferState {  
  2.     // FREE indicates that the buffer is not currently being used and  
  3.     // will not be used in the future until it gets dequeued and  
  4.     // subsequently queued by the client.  
  5.     // aka "owned by BufferQueue, ready to be dequeued"  
  6.     FREE = 0,  
  7.   
  8.     // DEQUEUED indicates that the buffer has been dequeued by the  
  9.     // client, but has not yet been queued or canceled. The buffer is  
  10.     // considered 'owned' by the client, and the server should not use  
  11.     // it for anything.  
  12.     //  
  13.     // Note that when in synchronous-mode (mSynchronousMode == true),  
  14.     // the buffer that's currently attached to the texture may be  
  15.     // dequeued by the client.  That means that the current buffer can  
  16.     // be in either the DEQUEUED or QUEUED state.  In asynchronous mode,  
  17.     // however, the current buffer is always in the QUEUED state.  
  18.     // aka "owned by producer, ready to be queued"  
  19.     DEQUEUED = 1,  
  20.   
  21.     // QUEUED indicates that the buffer has been queued by the client,  
  22.     // and has not since been made available for the client to dequeue.  
  23.     // Attaching the buffer to the texture does NOT transition the  
  24.     // buffer away from the QUEUED state. However, in Synchronous mode  
  25.     // the current buffer may be dequeued by the client under some  
  26.     // circumstances. See the note about the current buffer in the  
  27.     // documentation for DEQUEUED.  
  28.     // aka "owned by BufferQueue, ready to be acquired"  
  29.     QUEUED = 2,  
  30.   
  31.     // aka "owned by consumer, ready to be released"  
  32.     ACQUIRED = 3  
  33. };  

BufferQueue對圖形buffer的管理採用消費者-生產者模型,所有的buffer都由BufferQueue管理,當生產者也就是應用程序需要繪圖時,必須向BufferQueue申請繪圖緩衝區,並且將圖形buffer設置爲DEQUEUED出列狀態,此時只有應用程序才能訪問這塊圖形buffer。當應用程序完成繪圖後,需要將圖形緩衝區歸還給BufferQueue管理,並設置當前buffer爲QUEUED入列狀態,同時通知消費者繪圖完成。消費者又將向BufferQueue申請已完成的圖形buffer,並將當前申請的圖形buffer設置爲ACQUIRED狀態,此時的圖形buffer只能被消費者處理。


客戶端請求

frameworks\native\libs\gui\SurfaceTextureClient.cpp

  1. int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) {  
  2.     ATRACE_CALL();  
  3.     ALOGV("SurfaceTextureClient::dequeueBuffer");  
  4.     Mutex::Autolock lock(mMutex);  
  5.     //圖形buffer的索引號  
  6.     int buf = -1;  
  7.     int reqW = mReqWidth ? mReqWidth : mUserWidth;  
  8.     int reqH = mReqHeight ? mReqHeight : mUserHeight;  
  9.     //請求服務端的BufferQueue  
  10.     status_t result = mSurfaceTexture->dequeueBuffer(&buf, reqW, reqH,  
  11.             mReqFormat, mReqUsage);  
  12.     if (result < 0) {  
  13.         ALOGV("dequeueBuffer: ISurfaceTexture::dequeueBuffer(%d, %d, %d, %d)"  
  14.              "failed: %d", mReqWidth, mReqHeight, mReqFormat, mReqUsage,  
  15.              result);  
  16.         return result;  
  17.     }  
  18.     sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);  
  19.     //結果爲RELEASE_ALL_BUFFERS,則釋放所有的buffer  
  20.     if (result & ISurfaceTexture::RELEASE_ALL_BUFFERS) {  
  21.         freeAllBuffers();  
  22.     }  
  23.     //結果爲BUFFER_NEEDS_REALLOCATION,則請求重新分配圖形buffer  
  24.     if ((result & ISurfaceTexture::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {  
  25.         //請求服務端的BufferQueue  
  26.         result = mSurfaceTexture->requestBuffer(buf, &gbuf);  
  27.         if (result != NO_ERROR) {  
  28.             ALOGE("dequeueBuffer: ISurfaceTexture::requestBuffer failed: %d",result);  
  29.             return result;  
  30.         }  
  31.     }  
  32.     *buffer = gbuf.get();  
  33.     return OK;  
  34. }  

frameworks\native\libs\gui\ISurfaceTexture.cpp$ BpSurfaceTexture

  1. virtual status_t dequeueBuffer(int *buf, uint32_t w, uint32_t h,  
  2.         uint32_t format, uint32_t usage) {  
  3.     Parcel data, reply;  
  4.     data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());  
  5.     data.writeInt32(w);  
  6.     data.writeInt32(h);  
  7.     data.writeInt32(format);  
  8.     data.writeInt32(usage);  
  9.     status_t result = remote()->transact(DEQUEUE_BUFFER, data, &reply);  
  10.     if (result != NO_ERROR) {  
  11.         return result;  
  12.     }  
  13.     *buf = reply.readInt32();  
  14.     result = reply.readInt32();  
  15.     return result;  
  16. }  

服務端處理

frameworks\native\libs\gui\ISurfaceTexture.cpp$BnSurfaceTexture

  1. status_t BnSurfaceTexture::onTransact(  
  2.     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  
  3. {  
  4.     switch(code) {  
  5.         case DEQUEUE_BUFFER: {  
  6.             CHECK_INTERFACE(ISurfaceTexture, data, reply);  
  7.             uint32_t w      = data.readInt32();  
  8.             uint32_t h      = data.readInt32();  
  9.             uint32_t format = data.readInt32();  
  10.             uint32_t usage  = data.readInt32();  
  11.             int buf;  
  12.             int result = dequeueBuffer(&buf, w, h, format, usage);  
  13.             reply->writeInt32(buf);  
  14.             reply->writeInt32(result);  
  15.             return NO_ERROR;  
  16.         } break;  
  17.     }  
  18.     return BBinder::onTransact(code, data, reply, flags);  
  19. }  

frameworks\native\libs\gui\BufferQueue.cpp

  1. status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,  
  2.         uint32_t format, uint32_t usage) {  
  3.     ATRACE_CALL();  
  4.     ST_LOGV("dequeueBuffer: w=%d h=%d fmt=%#x usage=%#x", w, h, format, usage);  
  5.     if ((w && !h) || (!w && h)) {  
  6.         ST_LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h);  
  7.         return BAD_VALUE;  
  8.     }  
  9.     status_t returnFlags(OK);  
  10.     EGLDisplay dpy = EGL_NO_DISPLAY;  
  11.     EGLSyncKHR fence = EGL_NO_SYNC_KHR;  
  12.   
  13.     { // Scope for the lock  
  14.         Mutex::Autolock lock(mMutex);  
  15.         if (format == 0) {  
  16.             format = mDefaultBufferFormat;  
  17.         }  
  18.         // turn on usage bits the consumer requested  
  19.         usage |= mConsumerUsageBits;  
  20.         int found = -1;  
  21.         int foundSync = -1;  
  22.         int dequeuedCount = 0;  
  23.         bool tryAgain = true;  
  24.         while (tryAgain) {  
  25.             if (mAbandoned) {  
  26.                 ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!");  
  27.                 return NO_INIT;  
  28.             }  
  29.             const int minBufferCountNeeded = mSynchronousMode ? mMinSyncBufferSlots : mMinAsyncBufferSlots;  
  30.             const bool numberOfBuffersNeedsToChange = !mClientBufferCount &&  
  31.                     ((mServerBufferCount != mBufferCount) ||(mServerBufferCount < minBufferCountNeeded));  
  32.                       
  33.             if (!mQueue.isEmpty() && numberOfBuffersNeedsToChange) {  
  34.                 // wait for the FIFO to drain  
  35.                 mDequeueCondition.wait(mMutex);  
  36.                 // NOTE: we continue here because we need to reevaluate our  
  37.                 // whole state (eg: we could be abandoned or disconnected)  
  38.                 continue;  
  39.             }  
  40.   
  41.             if (numberOfBuffersNeedsToChange) {  
  42.                 // here we're guaranteed that mQueue is empty  
  43.                 freeAllBuffersLocked();  
  44.                 mBufferCount = mServerBufferCount;  
  45.                 if (mBufferCount < minBufferCountNeeded)  
  46.                     mBufferCount = minBufferCountNeeded;  
  47.                 mBufferHasBeenQueued = false;  
  48.                 returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS;  
  49.             }  
  50.             // look for a free buffer to give to the client  
  51.             found = INVALID_BUFFER_SLOT;  
  52.             foundSync = INVALID_BUFFER_SLOT;  
  53.             dequeuedCount = 0;  
  54.             for (int i = 0; i < mBufferCount; i++) {  
  55.                 const int state = mSlots[i].mBufferState;  
  56.                 if (state == BufferSlot::DEQUEUED) {  
  57.                     dequeuedCount++;//統計已經被生產者出列的buffer個數  
  58.                 }  
  59.                 if (state == BufferSlot::FREE) {  
  60.                     /*  
  61.                      * mFrameNumber用於標示buffer入列序號,buffer入列時都會 
  62.                      * mFrameNumber自動加一,通過mFrameNumber可以判斷buffer入列的先後順序 
  63.                      */  
  64.                     bool isOlder = mSlots[i].mFrameNumber < mSlots[found].mFrameNumber;  
  65.                     if (found < 0 || isOlder) {  
  66.                         foundSync = i;  
  67.                         found = i;  
  68.                     }  
  69.                 }  
  70.             }  
  71.             // clients are not allowed to dequeue more than one buffer  
  72.             // if they didn't set a buffer count.  
  73.             if (!mClientBufferCount && dequeuedCount) {  
  74.                 ST_LOGE("dequeueBuffer: can't dequeue multiple buffers without "  
  75.                         "setting the buffer count");  
  76.                 return -EINVAL;  
  77.             }  
  78.             // See whether a buffer has been queued since the last  
  79.             // setBufferCount so we know whether to perform the  
  80.             // mMinUndequeuedBuffers check below.  
  81.             if (mBufferHasBeenQueued) {  
  82.                 // make sure the client is not trying to dequeue more buffers  
  83.                 // than allowed.  
  84.                 const int avail = mBufferCount - (dequeuedCount+1);  
  85.                 if (avail < (mMinUndequeuedBuffers-int(mSynchronousMode))) {  
  86.                     ST_LOGE("dequeueBuffer: mMinUndequeuedBuffers=%d exceeded ""(dequeued=%d)",  
  87.                             mMinUndequeuedBuffers-int(mSynchronousMode),  
  88.                             dequeuedCount);  
  89.                     return -EBUSY;  
  90.                 }  
  91.             }  
  92.             // if no buffer is found, wait for a buffer to be released  
  93.             tryAgain = found == INVALID_BUFFER_SLOT;  
  94.             if (tryAgain) {  
  95.                 mDequeueCondition.wait(mMutex);  
  96.             }  
  97.         }  
  98.         if (found == INVALID_BUFFER_SLOT) {  
  99.             // This should not happen.  
  100.             ST_LOGE("dequeueBuffer: no available buffer slots");  
  101.             return -EBUSY;  
  102.         }  
  103.         //狀態爲FREE、合適的buffer索引號  
  104.         const int buf = found;  
  105.         *outBuf = found;  
  106.         ATRACE_BUFFER_INDEX(buf);  
  107.         const bool useDefaultSize = !w && !h;  
  108.         if (useDefaultSize) {  
  109.             // use the default size  
  110.             w = mDefaultWidth;  
  111.             h = mDefaultHeight;  
  112.         }  
  113.         const bool updateFormat = (format != 0);  
  114.         if (!updateFormat) {  
  115.             // keep the current (or default) format  
  116.             format = mPixelFormat;  
  117.         }  
  118.         // buffer is now in DEQUEUED (but can also be current at the same time,  
  119.         // if we're in synchronous mode)  
  120.         mSlots[buf].mBufferState = BufferSlot::DEQUEUED;  
  121.         const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);  
  122.         //如果當前buffer不合適,則創建一個新的圖形buffer  
  123.         if ((buffer == NULL) ||  
  124.             (uint32_t(buffer->width)  != w) ||  
  125.             (uint32_t(buffer->height) != h) ||  
  126.             (uint32_t(buffer->format) != format) ||  
  127.             ((uint32_t(buffer->usage) & usage) != usage))  
  128.         {  
  129.             status_t error;  
  130.             //創建新的圖形buffer  
  131.             sp<GraphicBuffer> graphicBuffer(  
  132.                     mGraphicBufferAlloc->createGraphicBuffer(w, h, format, usage, &error));  
  133.             if (graphicBuffer == 0) {  
  134.                 ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer ""failed");  
  135.                 return error;  
  136.             }  
  137.             if (updateFormat) {  
  138.                 mPixelFormat = format;  
  139.             }  
  140.             //根據buffer索引,初始化mSlots中對應的元素  
  141.             mSlots[buf].mAcquireCalled = false;  
  142.             mSlots[buf].mGraphicBuffer = graphicBuffer;  
  143.             mSlots[buf].mRequestBufferCalled = false;  
  144.             mSlots[buf].mFence = EGL_NO_SYNC_KHR;  
  145.             mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;  
  146.             //設置返回結果爲BUFFER_NEEDS_REALLOCATION  
  147.             returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;  
  148.         }  
  149.         dpy = mSlots[buf].mEglDisplay;  
  150.         fence = mSlots[buf].mFence;  
  151.         mSlots[buf].mFence = EGL_NO_SYNC_KHR;  
  152.     }  // end lock scope  
  153.     if (fence != EGL_NO_SYNC_KHR) {  
  154.         EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000);  
  155.         // If something goes wrong, log the error, but return the buffer without  
  156.         // synchronizing access to it.  It's too late at this point to abort the  
  157.         // dequeue operation.  
  158.         if (result == EGL_FALSE) {  
  159.             ST_LOGE("dequeueBuffer: error waiting for fence: %#x", eglGetError());  
  160.         } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {  
  161.             ST_LOGE("dequeueBuffer: timeout waiting for fence");  
  162.         }  
  163.         eglDestroySyncKHR(dpy, fence);  
  164.     }  
  165.     ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", *outBuf,  
  166.             mSlots[*outBuf].mGraphicBuffer->handle, returnFlags);  
  167.     return returnFlags;  
  168. }  

BufferQueue中有一個mSlots數組用於管理其內的各緩衝區,最大容量爲32。mSlots在程序一開始就靜態分配了32個BufferSlot大小的空間。但BufferSlot的內部變指針mGraphicBuffer所指向的圖形buffer空間卻是動態分配的。


圖形緩衝區創建過程


如果從mSlots數組中找到了一個狀態爲FREE的圖形buffer,但由於該圖形buffer不合適,因此需要重新創建一個GraphicBuffer對象。


frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp

  1. sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,  
  2.         PixelFormat format, uint32_t usage, status_t* error) {  
  3.     //構造一個GraphicBuffer對象  
  4.     sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));  
  5.     status_t err = graphicBuffer->initCheck();  
  6.     *error = err;  
  7.     if (err != 0 || graphicBuffer->handle == 0) {  
  8.         if (err == NO_MEMORY) {  
  9.             GraphicBuffer::dumpAllocationsToSystemLog();  
  10.         }  
  11.         ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "  
  12.              "failed (%s), handle=%p",  
  13.                 w, h, strerror(-err), graphicBuffer->handle);  
  14.         return 0;  
  15.     }  
  16.     return graphicBuffer;  
  17. }  

frameworks\native\libs\ui\GraphicBuffer.cpp

  1. GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,   
  2.         PixelFormat reqFormat, uint32_t reqUsage)  
  3.     : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),  
  4.       mInitCheck(NO_ERROR), mIndex(-1)  
  5. {  
  6.     width  =   
  7.     height =   
  8.     stride =   
  9.     format =   
  10.     usage  = 0;  
  11.     handle = NULL;  
  12.     //分配圖形buffer存儲空間  
  13.     mInitCheck = initSize(w, h, reqFormat, reqUsage);  
  14. }  

根據圖形buffer的寬高、格式等信息爲圖形緩衝區分配存儲空間

  1. status_t GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat format,  
  2.         uint32_t reqUsage)  
  3. {  
  4.     GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();  
  5.     status_t err = allocator.alloc(w, h, format, reqUsage, &handle, &stride);  
  6.     if (err == NO_ERROR) {  
  7.         this->width  = w;  
  8.         this->height = h;  
  9.         this->format = format;  
  10.         this->usage  = reqUsage;  
  11.     }  
  12.     return err;  
  13. }  

使用GraphicBufferAllocator對象來爲圖形緩衝區分配內存空間,GraphicBufferAllocator是對Gralloc模塊中的gpu設備的封裝類。關於GraphicBufferAllocator內存分配過程請查看Android圖形緩衝區分配過程源碼分析,圖形緩衝區分配完成後,還會映射到SurfaceFlinger服務進程的虛擬地址空間。


應用程序獲取圖形buffer首地址


我們知道,Surface爲應用程序這邊用於描述畫板類,繼承於SurfaceTextureClient類,是面向應用程序的本地窗口,實現了EGL窗口協議。在SurfaceTextureClient中定義了一個大小爲32的mSlots數組,用於保存當前Surface申請的圖形buffer。每個Surface在SurfaceFlinger服務端有一個layer對象與之對應,在前面也介紹了,每個Layer又擁有一個SurfaceTexture對象,每個SurfaceTexture對象又持有一個buffer隊列BufferQue,BufferQue同樣爲每個Layer定義了一個大小爲32的mSlots數組,同樣用來保存每個Layer所使用的buffer。只不過應用程序端的mSlots數組元素和服務端的mSlots數組元素定義不同,應用程序在申請圖形buffer時必須保存這兩個隊列數據中的buffer同步。

如果重新爲圖形buffer分配空間,那麼BufferQueue的dequeueBuffer函數返回值中需要加上BUFFER_NEEDS_REALLOCATION標誌。客戶端在發現這個標誌後,它還應調用requestBuffer()來取得最新的buffer地址。

客戶端請求

frameworks\native\libs\gui\SurfaceTextureClient.cpp

  1. int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) {  
  2.     ...  
  3.     if ((result & ISurfaceTexture::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {  
  4.         //獲取圖形buffer的首地址  
  5.         result = mSurfaceTexture->requestBuffer(buf, &gbuf);  
  6.         if (result != NO_ERROR) {  
  7.             ALOGE("dequeueBuffer: ISurfaceTexture::requestBuffer failed: %d",  
  8.                     result);  
  9.             return result;  
  10.         }  
  11.     }  
  12.     *buffer = gbuf.get();  
  13.     return OK;  
  14. }  

frameworks\native\libs\gui\ISurfaceTexture.cpp$ BpSurfaceTexture

  1. virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) {  
  2.     Parcel data, reply;  
  3.     data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());  
  4.     data.writeInt32(bufferIdx);  
  5.     status_t result =remote()->transact(REQUEST_BUFFER, data, &reply);  
  6.     if (result != NO_ERROR) {  
  7.         return result;  
  8.     }  
  9.     bool nonNull = reply.readInt32();  
  10.     if (nonNull) {  
  11.         //在應用程序進程中創建一個GraphicBuffer對象  
  12.         sp<GraphicBuffer> p = new GraphicBuffer();  
  13.         result = reply.read(*p);  
  14.         if (result != NO_ERROR) {  
  15.             p = 0;  
  16.             return result;  
  17.         }  
  18.         *buf = p;  
  19.     }  
  20.     result = reply.readInt32();  
  21.     return result;  
  22. }  

frameworks\native\libs\ui\GraphicBuffer.cpp

  1. GraphicBuffer::GraphicBuffer()  
  2.     : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),  
  3.       mInitCheck(NO_ERROR), mIndex(-1)  
  4. {  
  5.     width  =   
  6.     height =   
  7.     stride =   
  8.     format =   
  9.     usage  = 0;  
  10.     handle = NULL;  
  11. }  

服務端進程接收到應用程序進程requestBuffer請求後,將新創建的GraphicBuffer對象發送給應用程序。上面可以看到,應用程序進程這邊也創建了一個GraphicBuffer對象,在SurfaceFlinger服務進程中也同樣創建了一個GraphicBuffer對象,SurfaceFlinger服務進程只是將它進程中創建的GraphicBuffer對象傳輸給應用程序進程,我們知道,一個對象要在進程間傳輸必須繼承於Flattenable類,並且實現flatten和unflatten方法,flatten方法用於序列化該對象,unflatten方法用於反序列化對象。

 

GraphicBuffer同樣繼承於Flattenable類並實現了flatten和unflatten方法,在應用程序讀取來自服務進程的GraphicBuffer對象時,也就是result = reply.read(*p),會調用GraphicBuffer類的unflatten函數進行反序列化過程: 

  1. status_t GraphicBuffer::unflatten(void const* buffer, size_t size,  
  2.         int fds[], size_t count)  
  3. {  
  4.     if (size < 8*sizeof(int)) return NO_MEMORY;  
  5.     int const* buf = static_cast<int const*>(buffer);  
  6.     if (buf[0] != 'GBFR') return BAD_TYPE;  
  7.       
  8.     const size_t numFds  = buf[6];  
  9.     const size_t numInts = buf[7];  
  10.   
  11.     const size_t sizeNeeded = (8 + numInts) * sizeof(int);  
  12.     if (size < sizeNeeded) return NO_MEMORY;  
  13.   
  14.     size_t fdCountNeeded = 0;  
  15.     if (count < fdCountNeeded) return NO_MEMORY;  
  16.       
  17.     if (handle) {  
  18.         // free previous handle if any  
  19.         free_handle();  
  20.     }  
  21.     if (numFds || numInts) {  
  22.         width  = buf[1];  
  23.         height = buf[2];  
  24.         stride = buf[3];  
  25.         format = buf[4];  
  26.         usage  = buf[5];  
  27.         //創建一個native_handle對象  
  28.         native_handle* h = native_handle_create(numFds, numInts);  
  29.         memcpy(h->data,          fds,     numFds*sizeof(int));  
  30.         memcpy(h->data + numFds, &buf[8], numInts*sizeof(int));  
  31.         handle = h;  
  32.     } else {  
  33.         width = height = stride = format = usage = 0;  
  34.         handle = NULL;  
  35.     }  
  36.     mOwner = ownHandle;  
  37.     if (handle != 0) {  
  38.         //使用GraphicBufferMapper將服務端創建的圖形buffer映射到當前進程地址空間  
  39.         status_t err = mBufferMapper.registerBuffer(handle);  
  40.         if (err != NO_ERROR) {  
  41.             native_handle_close(handle);  
  42.             native_handle_delete(const_cast<native_handle*>(handle));  
  43.             handle = NULL;  
  44.             return err;  
  45.         }  
  46.     }  
  47.     return NO_ERROR;  
  48. }  


應用程序進程得到服務端進程返回來的GraphicBuffer對象後,還需要將該圖形buffer映射到應用程序進程地址空間,有關圖形緩存區的映射詳細過程請查看Android圖形緩衝區映射過程源碼分析

服務端處理

frameworks\native\libs\gui\ISurfaceTexture.cpp$BnSurfaceTexture

  1. status_t BnSurfaceTexture::onTransact(  
  2.     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  
  3. {  
  4.     switch(code) {  
  5.         case REQUEST_BUFFER: {  
  6.             CHECK_INTERFACE(ISurfaceTexture, data, reply);  
  7.             int bufferIdx   = data.readInt32();  
  8.             sp<GraphicBuffer> buffer;  
  9.             //通過BufferQueue的requestBuffer函數來獲得重新分配的圖形buffer  
  10.             int result = requestBuffer(bufferIdx, &buffer);  
  11.             reply->writeInt32(buffer != 0);  
  12.             //將GraphicBuffer對象寫回到應用程序進程,因此GraphicBuffer必須是Flattenable的子類  
  13.             if (buffer != 0) {  
  14.                 reply->write(*buffer);  
  15.             }  
  16.             reply->writeInt32(result);  
  17.             return NO_ERROR;  
  18.         } break;  
  19.     }  
  20.     return BBinder::onTransact(code, data, reply, flags);  
  21. }  

frameworks\native\libs\gui\BufferQueue.cpp

  1. status_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) {  
  2.     ATRACE_CALL();  
  3.     ST_LOGV("requestBuffer: slot=%d", slot);  
  4.     Mutex::Autolock lock(mMutex);  
  5.     if (mAbandoned) {  
  6.         ST_LOGE("requestBuffer: SurfaceTexture has been abandoned!");  
  7.         return NO_INIT;  
  8.     }  
  9.     if (slot < 0 || mBufferCount <= slot) {  
  10.         ST_LOGE("requestBuffer: slot index out of range [0, %d]: %d",  
  11.                 mBufferCount, slot);  
  12.         return BAD_VALUE;  
  13.     }  
  14.     mSlots[slot].mRequestBufferCalled = true;  
  15.     *buf = mSlots[slot].mGraphicBuffer;  
  16.     return NO_ERROR;  
  17. }  

由於GraphicBuffer繼承於Flattenable類,在Android 數據Parcel序列化過程源碼分析中介紹了,將一個對象寫入到Parcel中,需要使用flatten函數序列化該對象:

frameworks\native\libs\ui\GraphicBuffer.cpp

  1. status_t GraphicBuffer::flatten(void* buffer, size_t size,  
  2.         int fds[], size_t count) const  
  3. {  
  4.     size_t sizeNeeded = GraphicBuffer::getFlattenedSize();  
  5.     if (size < sizeNeeded) return NO_MEMORY;  
  6.   
  7.     size_t fdCountNeeded = GraphicBuffer::getFdCount();  
  8.     if (count < fdCountNeeded) return NO_MEMORY;  
  9.   
  10.     int* buf = static_cast<int*>(buffer);  
  11.     buf[0] = 'GBFR';  
  12.     buf[1] = width;  
  13.     buf[2] = height;  
  14.     buf[3] = stride;  
  15.     buf[4] = format;  
  16.     buf[5] = usage;  
  17.     buf[6] = 0;  
  18.     buf[7] = 0;  
  19.   
  20.     if (handle) {  
  21.         buf[6] = handle->numFds;  
  22.         buf[7] = handle->numInts;  
  23.         native_handle_t const* const h = handle;  
  24.         memcpy(fds,     h->data,             h->numFds*sizeof(int));  
  25.         memcpy(&buf[8], h->data + h->numFds, h->numInts*sizeof(int));  
  26.     }  
  27.   
  28.     return NO_ERROR;  
  29. }  

到此我們就介紹完了應用程序請求BufferQueue出列一個可用圖形buffer的完整過程,那麼應用程序什麼時候發出這個請求呢?我們知道,在使用Surface繪圖前,需要調用SurfaceHolder的lockCanvas()函數來鎖定畫布,然後纔可以在畫布上作圖,應用程序就是在這個時候向SurfaceFlinger服務進程中的BufferQueue申請圖形緩存區的。



應用程序釋放圖形buffer過程



當應用程序完成繪圖後,需要調用SurfaceHolder的unlockCanvasAndPost(canvas)函數來釋放畫布,並請求SurfaceFlinger服務進程混合並顯示該圖像。


從以上時序圖可以看到,應用程序完成繪圖後,首先對當前這塊圖形buffer進行解鎖,然後調用queueBuffer()函數請求SurfaceFlinger服務進程中的BufferQueue將當前已繪製好圖形的buffer入列,也就是將當前buffer交還給BufferQueue管理。應用程序這個生產者在這塊buffer中生產出了圖像產品後,就需要將buffer中的圖像產品放到BufferQueue銷售市場中交易,SurfaceFlinger這個消費者得知市場上有新的圖像產品出現,就立刻請求VSync信號,在下一次VSync到來時,SurfaceFlinger混合當前市場上的所有圖像產品,並顯示到屏幕上,從而完成圖像產品的消費過程。

客戶端請求

frameworks\native\libs\gui\SurfaceTextureClient.cpp 

  1. int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer) {  
  2.     ATRACE_CALL();  
  3.     ALOGV("SurfaceTextureClient::queueBuffer");  
  4.     Mutex::Autolock lock(mMutex);  
  5.     int64_t timestamp;  
  6.     if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {  
  7.         timestamp = systemTime(SYSTEM_TIME_MONOTONIC);  
  8.         ALOGV("SurfaceTextureClient::queueBuffer making up timestamp: %.2f ms",  
  9.              timestamp / 1000000.f);  
  10.     } else {  
  11.         timestamp = mTimestamp;  
  12.     }  
  13.     int i = getSlotFromBufferLocked(buffer);  
  14.     if (i < 0) {  
  15.         return i;  
  16.     }  
  17.     // Make sure the crop rectangle is entirely inside the buffer.  
  18.     Rect crop;  
  19.     mCrop.intersect(Rect(buffer->width, buffer->height), &crop);  
  20.   
  21.     ISurfaceTexture::QueueBufferOutput output;  
  22.     ISurfaceTexture::QueueBufferInput input(timestamp, crop, mScalingMode,  
  23.             mTransform);  
  24.     status_t err = mSurfaceTexture->queueBuffer(i, input, &output);  
  25.     if (err != OK)  {  
  26.         ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);  
  27.     }  
  28.     uint32_t numPendingBuffers = 0;  
  29.     output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint,&numPendingBuffers);  
  30.     mConsumerRunningBehind = (numPendingBuffers >= 2);  
  31.     return err;  
  32. }  

frameworks\native\libs\gui\ ISurfaceTexture.cpp $BpSurfaceTexture

  1. virtual status_t queueBuffer(int buf,const QueueBufferInput& input, QueueBufferOutput* output) {  
  2.     Parcel data, reply;  
  3.     data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());  
  4.     data.writeInt32(buf);  
  5.     memcpy(data.writeInplace(sizeof(input)), &input, sizeof(input));  
  6.     status_t result = remote()->transact(QUEUE_BUFFER, data, &reply);  
  7.     if (result != NO_ERROR) {  
  8.         return result;  
  9.     }  
  10.     memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));  
  11.     result = reply.readInt32();  
  12.     return result;  
  13. }  

服務端處理

frameworks\native\libs\gui\ ISurfaceTexture.cpp $BnSurfaceTexture

  1. status_t BnSurfaceTexture::onTransact(  
  2.     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  
  3. {  
  4.     switch(code) {  
  5.         case QUEUE_BUFFER: {  
  6.             CHECK_INTERFACE(ISurfaceTexture, data, reply);  
  7.             int buf = data.readInt32();  
  8.             QueueBufferInput const* const input =  
  9.                     reinterpret_cast<QueueBufferInput const *>(  
  10.                             data.readInplace(sizeof(QueueBufferInput)));  
  11.             QueueBufferOutput* const output =  
  12.                     reinterpret_cast<QueueBufferOutput *>(  
  13.                             reply->writeInplace(sizeof(QueueBufferOutput)));  
  14.             status_t result = queueBuffer(buf, *input, output);  
  15.             reply->writeInt32(result);  
  16.             return NO_ERROR;  
  17.         } break;  
  18.     }  
  19.     return BBinder::onTransact(code, data, reply, flags);  
  20. }  

frameworks\native\libs\gui\ BufferQueue.cpp

  1. status_t BufferQueue::queueBuffer(int buf,  
  2.         const QueueBufferInput& input, QueueBufferOutput* output) {  
  3.     ATRACE_CALL();  
  4.     ATRACE_BUFFER_INDEX(buf);  
  5.     Rect crop;  
  6.     uint32_t transform;  
  7.     int scalingMode;  
  8.     int64_t timestamp;  
  9.     input.deflate(×tamp, &crop, &scalingMode, &transform);  
  10.     ST_LOGV("queueBuffer: slot=%d time=%#llx crop=[%d,%d,%d,%d] tr=%#x "  
  11.             "scale=%s",  
  12.             buf, timestamp, crop.left, crop.top, crop.right, crop.bottom,  
  13.             transform, scalingModeName(scalingMode));  
  14.     sp<ConsumerListener> listener;  
  15.   
  16.     { // scope for the lock  
  17.         Mutex::Autolock lock(mMutex);  
  18.         if (mAbandoned) {  
  19.             ST_LOGE("queueBuffer: SurfaceTexture has been abandoned!");  
  20.             return NO_INIT;  
  21.         }  
  22.         if (buf < 0 || buf >= mBufferCount) {  
  23.             ST_LOGE("queueBuffer: slot index out of range [0, %d]: %d",  
  24.                     mBufferCount, buf);  
  25.             return -EINVAL;  
  26.         } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {  
  27.             ST_LOGE("queueBuffer: slot %d is not owned by the client "  
  28.                     "(state=%d)", buf, mSlots[buf].mBufferState);  
  29.             return -EINVAL;  
  30.         } else if (!mSlots[buf].mRequestBufferCalled) {  
  31.             ST_LOGE("queueBuffer: slot %d was enqueued without requesting a "  
  32.                     "buffer", buf);  
  33.             return -EINVAL;  
  34.         }  
  35.         const sp<GraphicBuffer>& graphicBuffer(mSlots[buf].mGraphicBuffer);  
  36.         Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());  
  37.         Rect croppedCrop;  
  38.         crop.intersect(bufferRect, &croppedCrop);  
  39.         if (croppedCrop != crop) {  
  40.             ST_LOGE("queueBuffer: crop rect is not contained within the "  
  41.                     "buffer in slot %d", buf);  
  42.             return -EINVAL;  
  43.         }  
  44.         if (mSynchronousMode) {  
  45.             // In synchronous mode we queue all buffers in a FIFO.  
  46.             mQueue.push_back(buf);  
  47.   
  48.             // Synchronous mode always signals that an additional frame should  
  49.             // be consumed.  
  50.             listener = mConsumerListener;  
  51.         } else {  
  52.             // In asynchronous mode we only keep the most recent buffer.  
  53.             if (mQueue.empty()) {  
  54.                 mQueue.push_back(buf);  
  55.   
  56.                 // Asynchronous mode only signals that a frame should be  
  57.                 // consumed if no previous frame was pending. If a frame were  
  58.                 // pending then the consumer would have already been notified.  
  59.                 listener = mConsumerListener;  
  60.             } else {  
  61.                 Fifo::iterator front(mQueue.begin());  
  62.                 // buffer currently queued is freed  
  63.                 mSlots[*front].mBufferState = BufferSlot::FREE;  
  64.                 // and we record the new buffer index in the queued list  
  65.                 *front = buf;  
  66.             }  
  67.         }  
  68.         mSlots[buf].mTimestamp = timestamp;  
  69.         mSlots[buf].mCrop = crop;  
  70.         mSlots[buf].mTransform = transform;  
  71.         switch (scalingMode) {  
  72.             case NATIVE_WINDOW_SCALING_MODE_FREEZE:  
  73.             case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:  
  74.             case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:  
  75.                 break;  
  76.             default:  
  77.                 ST_LOGE("unknown scaling mode: %d (ignoring)", scalingMode);  
  78.                 scalingMode = mSlots[buf].mScalingMode;  
  79.                 break;  
  80.         }  
  81.         mSlots[buf].mBufferState = BufferSlot::QUEUED;  
  82.         mSlots[buf].mScalingMode = scalingMode;  
  83.         mFrameCounter++;  
  84.         mSlots[buf].mFrameNumber = mFrameCounter;  
  85.         mBufferHasBeenQueued = true;  
  86.         //通知有buffer入列  
  87.         mDequeueCondition.broadcast();  
  88.         output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint,  
  89.                 mQueue.size());  
  90.         ATRACE_INT(mConsumerName.string(), mQueue.size());  
  91.     } // scope for the lock  
  92.     //通知消費者buffer已入列  
  93.     if (listener != 0) {  
  94.         listener->onFrameAvailable();  
  95.     }  
  96.     return OK;  
  97. }  

在前面構造SurfaceTexture對象時,通過mBufferQueue->consumerConnect(proxy)將ProxyConsumerListener監聽器保存到了BufferQueue的成員變量mConsumerListener中,同時又將SurfaceTexture對象保存到ProxyConsumerListener的成員變量mConsumerListener中。

frameworks\native\libs\gui\SurfaceTexture.cpp

  1. SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,  
  2.         GLenum texTarget, bool useFenceSync, const sp<BufferQueue> &bufferQueue)   
  3. {  
  4.     ...  
  5.     wp<BufferQueue::ConsumerListener> listener;  
  6.     sp<BufferQueue::ConsumerListener> proxy;  
  7.     listener = static_cast<BufferQueue::ConsumerListener*>(this);  
  8.     proxy = new BufferQueue::ProxyConsumerListener(listener);  
  9.     status_t err = mBufferQueue->consumerConnect(proxy);  
  10.     ....  
  11. }  

因此BufferQueue通過回調ProxyConsumerListener的onFrameAvailable()函數來通知消費者圖形buffer已經準備就緒。
frameworks\native\libs\gui\ BufferQueue.cpp 

  1. void BufferQueue::ProxyConsumerListener::onFrameAvailable() {  
  2.     sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote());  
  3.     if (listener != NULL) {  
  4.         listener->onFrameAvailable();  
  5.     }  
  6. }  

ProxyConsumerListener又回調SurfaceTexture的onFrameAvailable()函數來處理。

frameworks\native\libs\gui\ SurfaceTexture.cpp

  1. void SurfaceTexture::onFrameAvailable() {  
  2.     ST_LOGV("onFrameAvailable");  
  3.   
  4.     sp<FrameAvailableListener> listener;  
  5.     { // scope for the lock  
  6.         Mutex::Autolock lock(mMutex);  
  7.         listener = mFrameAvailableListener;  
  8.     }  
  9.   
  10.     if (listener != NULL) {  
  11.         ST_LOGV("actually calling onFrameAvailable");  
  12.         listener->onFrameAvailable();  
  13.     }  
  14. }  

在Layer對象的onFirstRef()函數中,通過調用SurfaceTexture的setFrameAvailableListener函數來爲SurfaceTexture設置buffer可用監器爲FrameQueuedListene,其實就是將FrameQueuedListener對象保存到SurfaceTexture的成員變量mFrameAvailableListener中:
frameworks\native\services\surfaceflinger\ Layer.cpp 

  1. mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));  

因此buffer可用通知最終又交給FrameQueuedListener來處理:

  1. struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener {  
  2.         FrameQueuedListener(Layer* layer) : mLayer(layer) { }  
  3. private:  
  4.     wp<Layer> mLayer;  
  5.     virtual void onFrameAvailable() {  
  6.         sp<Layer> that(mLayer.promote());  
  7.         if (that != 0) {  
  8.             that->onFrameQueued();  
  9.         }  
  10.     }  
  11. };  

FrameQueuedListener的onFrameAvailable()函數又調用Layer類的onFrameQueued()來處理

  1. void Layer::onFrameQueued() {  
  2.     android_atomic_inc(&mQueuedFrames);  
  3.     mFlinger->signalLayerUpdate();  
  4. }  

接着又通知SurfaceFlinger來更新Layer層。
frameworks\native\services\surfaceflinger\ SurfaceFlinger.cpp 

  1. void SurfaceFlinger::signalLayerUpdate() {  
  2.     mEventQueue.invalidate();  
  3. }  

該函數就是向SurfaceFlinger的事件隊列中發送一個Vsync信號請求
frameworks\native\services\surfaceflinger\ MessageQueue.cpp 

  1. void MessageQueue::invalidate() {  
  2.     mEvents->requestNextVsync();  
  3. }  
應用程序入列一個圖形buffer的整個過程如下:
發佈了2 篇原創文章 · 獲贊 7 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章