zoukankan      html  css  js  c++  java
  • Android中*_handle_t/ANativeWindowBuffer/ANativeWindow/GraphicBuffer/Surface的关系

    在阅读SurfaceFlinger HardwareComposer以及gralloc相关代码的过程中,我们经常会遇到native_handle private_handle_t ANativeWindowBuffer ANativeWindow GraphicBuffer Surface等等一系列和memory相关的struct和class,他们相互之间到底是什么区别,又有什么联系呢?本文从struct/class的结构角度分析下上述类型之间的关联.

        概括来说,native_handle private_handle_t ANativeWindowBuffer GraphicBuffer这四个struct/class所描述的是一块memory,而ANativeWindow 和Surface所描述的是一系列上述memeory的组合和对buffer的操作方法.有的struct/class在比较低的level使用,和平台相关,而另外一些在比较高的level使用,和平台无关,还有一些介于低/高level之间,用以消除平台相关性,让Android可以方便的运行在不同的平台上.

        我们依次来看下上述struct/class的定义:

    1. native_handle 

    system/core/include/cutils/native_handle.h

    1. typedef struct native_handle  
    2. {  
    3.     int version;        /* sizeof(native_handle_t) */  
    4.     int numFds;         /* number of file-descriptors at &data[0] */  
    5.     int numInts;        /* number of ints at &data[numFds] */  
    6.     int data[0];        /* numFds + numInts ints */  
    7. } native_handle_t;  

        native_handle/native_handle_t只是定义了一个描述buffer的结构体原型,这个原型是和平台无关的,方便buffer在各个进程之间传递,注意成员data是一个大小为0的数组,这意味着data指向紧挨着numInts后面的一个地址.我们可以把native_handle_t看成是一个纯虚的基类.


        一般来说,我们描述一块buffer,需要知道它在kernel中对应的fd,虚拟地址/物理地址,offset,size等等信息,后面我们在private_handle_t中就可以看到这些字段.
        android的gralloc模块负责从fb设备或者gpu中分配meomory,所以我们在gralloc中就可以找到native_handle的具体实现,gralloc中对buffer的描述就和具体的平台相关了,我们以aosp中最基本的gralloc为例,来看下gralloc中对native_handle是如何使用的.


    2.private_handle_t

    hardware/libhardware/modules/gralloc/gralloc_priv.h

    1. #ifdef __cplusplus  
    2. //在c++编译环境下private_handle_t继承于native_handle  
    3. struct private_handle_t : public native_handle {  
    4. #else  
    5. //在c编译环境下,private_handle_t的第一个成员是native_handle类型,其实和c++的继承是一个意思,  
    6. //总之就是一个指向private_handle_t的指针同样也可以表示一个指向native_handle的指针.  
    7. struct private_handle_t {  
    8.     struct native_handle nativeHandle;  
    9. #endif  
    10.     // file-descriptors  
    11.     int     fd;   
    12.     // ints  
    13.     int     magic;  
    14.     int     flags;  
    15.     int     size;  
    16.     int     offset;  
    17.     // 因为native_handle的data成员是一个大小为0的数组,所以data[0]其实就是指向了fd,data[1]指向magic,以此类推.  
    18.     // 上面提到我们可以把native_handle看成是一个纯虚的基类,那么在private_handle_t这个派生类中,numFds=1 numInts=4.  
    19.     ...  
    20. }  

        gralloc分配的buffer都可以用一个private_handle_t来描述,同时也可以用一个native_handle来描述.在不同的平台的实现上,private_handle_t可能会有不同的定义,所以private_handle_t在各个模块之间传递的时候很不方便,而如果用native_handle的身份来传递,就可以消除平台的差异性.在HardwareComposer中,由SurfaceFlinger传给hwc的handle即是native_handle类型,而hwc作为平台相关的模块,他需要知道native_handle中各个字段的具体含义,所以hwc往往会将native_handle指针转化为private_handle_t指针来使用.

    3. buffer_handle_t

        标题中并没有提到这个类型,因为这个类型实在是太简单了,我们看code

    system/core/include/system/window.h

    1. typedef const native_handle_t* buffer_handle_t;  

        在window.h中又把指向native_handle_t的指针define为buffer_handle_t,

    sturct native_handle

    native_handle_t

    struct private_handle_t
    这三个类型可以看作是同一个东西,而buffer_handle_t则是指向他们的指针.

        那么android是如何使用这些struct的,gralloc分配的buffer如何和android联系起来呢?
    我们继续来看window.h

    4. ANativeWindowBuffer和ANativeWindow

        在具体分析ANativeWindowBuffer和ANativeWindow之前,我们先来看下和这两个类型都相关的另外一个结构体android_native_base_t

    system/core/include/system/window.h

    1. typedef struct android_native_base_t  
    2. {  
    3.     /* a magic value defined by the actual EGL native type */  
    4.     int magic;  
    5.   
    6.     /* the sizeof() of the actual EGL native type */  
    7.     int version;  
    8.   
    9.     void* reserved[4];  
    10.   
    11.     /* reference-counting interface */  
    12.     void (*incRef)(struct android_native_base_t* base);  
    13.     void (*decRef)(struct android_native_base_t* base);  
    14. } android_native_base_t;  

    incRef和decRef是为了把派生类和android所有class的老祖宗RefBase联系起来所预留的函数指针,在后面我们在会看到指针具体会指向哪些函数.

    1. typedef struct ANativeWindowBuffer  
    2. {  
    3. #ifdef __cplusplus  
    4.     ANativeWindowBuffer() {  
    5.         // ANDROID_NATIVE_BUFFER_MAGIC的值是"_bfr"  
    6.         common.magic = ANDROID_NATIVE_BUFFER_MAGIC;  
    7.         common.version = sizeof(ANativeWindowBuffer);  
    8.         memset(common.reserved, 0, sizeof(common.reserved));  
    9.     }     
    10.   
    11.     // Implement the methods that sp<ANativeWindowBuffer> expects so that it  
    12.     // can be used to automatically refcount ANativeWindowBuffer's.  
    13.     // 调用common,也就是android_native_base_t的incRef和decRef函数,具体函数是什么还不知道  
    14.     void incStrong(const void* /*id*/) const {  
    15.         common.incRef(const_cast<android_native_base_t*>(&common));  
    16.     }     
    17.     void decStrong(const void* /*id*/) const {  
    18.         common.decRef(const_cast<android_native_base_t*>(&common));  
    19.     }     
    20. #endif  
    21.   
    22.     // common的incRef和decRef还没有明确是什么  
    23.    struct android_native_base_t common;  
    24.   
    25.     int width;  
    26.     int height;  
    27.     int stride;  
    28.     int format;  
    29.     int usage;  
    30.   
    31.     void* reserved[2];  
    32.     // buffer_handle_t是指向sturct native_handle, native_handle_t, struct private_handle_t的指针.  
    33.     buffer_handle_t handle;  
    34.   
    35.     void* reserved_proc[8];  
    36. } ANativeWindowBuffer_t;  
    37. // Old typedef for backwards compatibility.  
    38. typedef ANativeWindowBuffer_t android_native_buffer_t;  

    ANativeWindow的定义如下

    1. struct ANativeWindow  
    2. {  
    3. #ifdef __cplusplus  
    4.     ANativeWindow()  
    5.         : flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0)  
    6.     {  
    7.         // ANDROID_NATIVE_WINDOW_MAGIC的值是"_wnd"  
    8.         common.magic = ANDROID_NATIVE_WINDOW_MAGIC;  
    9.         common.version = sizeof(ANativeWindow);  
    10.         memset(common.reserved, 0, sizeof(common.reserved));  
    11.     }  
    12.   
    13.     /* Implement the methods that sp<ANativeWindow> expects so that it 
    14.        can be used to automatically refcount ANativeWindow's. */  
    15.     // 调用common,也就是android_native_base_t的incRef和decRef函数,具体函数是什么还不知道  
    16.     void incStrong(const void* /*id*/) const {  
    17.         common.incRef(const_cast<android_native_base_t*>(&common));  
    18.     }  
    19.     void decStrong(const void* /*id*/) const {  
    20.         common.decRef(const_cast<android_native_base_t*>(&common));  
    21.     }  
    22. #endif  
    23.     // common的incRef和decRef还没有明确是什么  
    24.     struct android_native_base_t common;  
    25.     ...  
    26.     int     (*dequeueBuffer)(struct ANativeWindow* window,  
    27.                 struct ANativeWindowBuffer** buffer, int* fenceFd);  
    28.     int     (*queueBuffer)(struct ANativeWindow* window,  
    29.                 struct ANativeWindowBuffer* buffer, int fenceFd);  
    30.     int     (*cancelBuffer)(struct ANativeWindow* window,  
    31.                 struct ANativeWindowBuffer* buffer, int fenceFd);  
    32. };  
    33.  /* Backwards compatibility: use ANativeWindow (struct ANativeWindow in C). 
    34.   * android_native_window_t is deprecated. 
    35.   */  
    36. typedef struct ANativeWindow ANativeWindow;  
    37. typedef struct ANativeWindow android_native_window_t __deprecated;  

    我们目前需要注意的是ANativeWindow的函数指针成员所指向的函数都需要一个struct ANativeWindowBuffer* buffer的参数.

    ANativeWindowBuffer和ANativeWindow还是没有给android_native_base_t的incRef和decRef指针赋值,ANativeWindowBuffer和ANativeWindow两个还是可以理解为抽象类!


    5. GraphicBuffer和Surface

    frameworks/native/include/ui/GraphicBuffer.h 

    1. class GraphicBuffer  
    2.     : public ANativeObjectBase< ANativeWindowBuffer, GraphicBuffer, RefBase >,  
    3.       public Flattenable<GraphicBuffer>  
    4. {  
    5. ...  
    6. }  

    GraphicBuffer继承于模版类ANativeObjectBase,这个模版类有三个模版.

    frameworks/native/include/ui/ANativeObjectBase.h

    1. // NATIVE_TYPE=ANativeWindowBuffer TYPE=GraphicBuffer REF=RefBase  
    2. template <typename NATIVE_TYPE, typename TYPE, typename REF>  
    3. // ANativeObjectBase多重继承于ANativeWindowBuffer和RefBase  
    4. class ANativeObjectBase : public NATIVE_TYPE, public REF   
    5. {  
    6. public:  
    7.     // Disambiguate between the incStrong in REF and NATIVE_TYPE  
    8.     // incStrong和decStrong直接调用其中一个基类RefBase的对应函数  
    9.     void incStrong(const void* id) const {  
    10.         REF::incStrong(id);  
    11.     }     
    12.     void decStrong(const void* id) const {  
    13.         REF::decStrong(id);  
    14.     }     
    15.   
    16. protected:  
    17.     // 给ANativeObjectBase取了个别名BASE  
    18.     typedef ANativeObjectBase<NATIVE_TYPE, TYPE, REF> BASE;  
    19.     ANativeObjectBase() : NATIVE_TYPE(), REF() {  
    20.         // 构造函数中给ANativeWindowBuffer.common的两个函数指针赋值了!这两个指针就是我们之前在分析ANativeWindowBuffer的时候悬而未决的地方.  
    21.         // incRef和decRef指针分别指向内部函数incRef和decRef  
    22.         NATIVE_TYPE::common.incRef = incRef;  
    23.         NATIVE_TYPE::common.decRef = decRef;  
    24.     }     
    25.     static inline TYPE* getSelf(NATIVE_TYPE* self) {  
    26.         return static_cast<TYPE*>(self);  
    27.     }     
    28.     static inline TYPE const* getSelf(NATIVE_TYPE const* self) {  
    29.         return static_cast<TYPE const *>(self);  
    30.     }     
    31.     static inline TYPE* getSelf(android_native_base_t* base) {  
    32.         return getSelf(reinterpret_cast<NATIVE_TYPE*>(base));  
    33.     }     
    34.     static inline TYPE const * getSelf(android_native_base_t const* base) {  
    35.         return getSelf(reinterpret_cast<NATIVE_TYPE const*>(base));  
    36.     }  
    37.     // 内部函数incRef和decRef调用上面的incStong和decStrong,也就是说ANativeWindowBuffer.common的两个函数指针最终会调用到RefBase的incStrong和decStrong.  
    38.     static void incRef(android_native_base_t* base) {  
    39.         ANativeObjectBase* self = getSelf(base);  
    40.         self->incStrong(self);  
    41.     }     
    42.     static void decRef(android_native_base_t* base) {  
    43.         ANativeObjectBase* self = getSelf(base);  
    44.         self->decStrong(self);  
    45.     }   
    46. };  

        搞了半天,原来GraphicBuffer就是ANativeWindowBuffer一种具体实现,把ANativeWindowBuffer的common成员的两个函数指针incRef decRef指向了GraphicBuffer的另一个基类RefBase的incStrong和decStrong,而ANativeWindowBuffer无非就是把buffer_handle_t包了一层.我们看下另外一个从ANativeObjectBase派生的类,他就是大名鼎鼎的,Surface!

    frameworks/native/include/gui/Surface.h

    1. class Surface  
    2.     : public ANativeObjectBase<ANativeWindow, Surface, RefBase>  
    3. {  
    4.     enum { NUM_BUFFER_SLOTS = BufferQueue::NUM_BUFFER_SLOTS };  
    5.     ...  
    6.     struct BufferSlot {  
    7.         sp<GraphicBuffer> buffer;  
    8.         Region dirtyRegion;  
    9.     };  
    10.     // mSlots stores the buffers that have been allocated for each buffer slot.  
    11.     // It is initialized to null pointers, and gets filled in with the result of  
    12.     // IGraphicBufferProducer::requestBuffer when the client dequeues a buffer from a  
    13.     // slot that has not yet been used. The buffer allocated to a slot will also  
    14.     // be replaced if the requested buffer usage or geometry differs from that  
    15.     // of the buffer allocated to a slot.  
    16.     BufferSlot mSlots[NUM_BUFFER_SLOTS];  
    17.     ...  
    18. }  

        Surface和GraphicBuffer都继承自模版类ANativeObjectBase,他使用的三个模版是ANativeWindow, Surface, RefBase,关于incRef和decRef两个函数指针的指向问题和上面GraphicBuffer是完全相同的, 这里就不赘述了.我们需要注意的是Surface有一个BufferSlot类型的成员数组mSlots,BufferSlot是GraphicBuffer的包装,所以我们可以理解为每个Surface中都有一个大小为NUM_BUFFER_SLOTS的GraphicBuffer数组.


        因为Surface继承自ANativeWindow,所以Surface需要实现ANativeWindow中定义的一些接口,这些实现在Surface的构造函数中:

    frameworks/native/libs/gui/Surface.cpp

    1. Surface::Surface(  
    2.         const sp<IGraphicBufferProducer>& bufferProducer,  
    3.         bool controlledByApp)  
    4.     : mGraphicBufferProducer(bufferProducer)  
    5. {  
    6.     // Initialize the ANativeWindow function pointers.  
    7.     ANativeWindow::setSwapInterval  = hook_setSwapInterval;  
    8.     ANativeWindow::dequeueBuffer    = hook_dequeueBuffer;  
    9.     ANativeWindow::cancelBuffer     = hook_cancelBuffer;  
    10.     ANativeWindow::queueBuffer      = hook_queueBuffer;  
    11.     ANativeWindow::query            = hook_query;  
    12.     ANativeWindow::perform          = hook_perform;  
    13.   
    14.     ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;  
    15.     ANativeWindow::cancelBuffer_DEPRECATED  = hook_cancelBuffer_DEPRECATED;  
    16.     ANativeWindow::lockBuffer_DEPRECATED    = hook_lockBuffer_DEPRECATED;  
    17.     ANativeWindow::queueBuffer_DEPRECATED   = hook_queueBuffer_DEPRECATED;  
    18.   
    19.     const_cast<int&>(ANativeWindow::minSwapInterval) = 0;  
    20.     const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;  
    21. }  

    ANativeWindow定义的这些接口有什么用呢?谁会来call这些函数呢?举个例子来看.我们在EGL的api中可以找到eglCreateWindowSurface这个函数的定义:

    frameworks/native/opengl/libs/EGL/eglApi.cpp

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

    注意其中一个参数NativeWindowType window,这个NativeWindowType又是什么呢?

    frameworks/native/opengl/include/EGL/eglplatform.h

    1. typedef struct ANativeWindow*           EGLNativeWindowType;  
    2. typedef EGLNativeWindowType  NativeWindowType;  

    原来NativeWindowType在Android环境下,就是ANativeWindow*,也就是Surface*!

    总结一下,

    native_handle/native_handle_t是private_handle_t的抽象表示方法,消除平台相关性,方便private_handle_t所表示的memory信息在android各个层次之间传递.而buffer_handle_t是指向他们的指针.

    ANativeWindowBuffer将buffer_handle_t进行了包装,ANativeWindow和ANativeWindowBuffer都继承于android_native_base_t,定义了common.incRef和common.decRef两个函数指针,但是并没有为函数指针赋值,所以ANativeWindow和ANativeWindowBuffer仍然是抽象类.

    GraphicBuffer和Surface通过继承模版类ANativeObjectBase并指定其中一个模版是RefBase,为incRef和decRef两个指针分别赋值为RefBase的incStrong和decStrong,这样

    GraphicBuffer继承了ANativeWindowBuffer,Surface继承了ANativeWindow,并且两者都具有的和RefBase同样的incStong decStrong成员函数.

    Surface的成员BufferSlot mSlots[NUM_BUFFER_SLOTS];可以看作是sp<GraphicBuffer>类型的数组,也就是说每个Surface中都包含有NUM_BUFFER_SLOTS个sp<GraphicBuffer>.


    关于ANativeWindow的使用方法,我们可以在SurfaceFlinger中找到一个很好的列子,就是SF的captureScreen接口.

  • 相关阅读:
    iSCSI又称为IPSAN
    文档类型定义DTD
    HDU 2971 Tower
    HDU 1588 Gauss Fibonacci
    URAL 1005 Stone Pile
    URAL 1003 Parity
    URAL 1002 Phone Numbers
    URAL 1007 Code Words
    HDU 3306 Another kind of Fibonacci
    FZU 1683 纪念SlingShot
  • 原文地址:https://www.cnblogs.com/shakin/p/7234742.html
Copyright © 2011-2022 走看看