android graphic(2)—EGL和OpenGL ES

http://blog.csdn.net/lewif/article/details/50532011

目录(?)[+]


前面提到Android EGL库的主要作用就是将OpenGL ES和本地窗口系统结合起来。OpenGL ES就像是一个打印机,各个厂商打印机的内部实现不同(不同的OpenGL ES的实现,软件、硬件等,实现的库由EGL加载),但是只要打印的文档内容相同,按下打印键,其输出的结果都是相同的。当然打印机可以在不同种类的纸张上打印,A4A5或者牛皮纸、塑料纸等等,打印机对这些都需要支持。OpenGL ES和打印机一样,需要兼容windows、塞班、android等多个不同的系统,所以它的实现是平台无关的,而windowsandroid等系统需要给OpenGL ES提供纸,这个纸就是本地窗口,而不同系统的实现肯定是不同的。打印机打印的最终内容需要呈现在纸上,对软件来说本地窗口里面肯定有buffer的存在来保存OpenGL ES画的图。

2016/03/25 注:android 4.4中已经不使用FramebufferNativeWindow了,而是使用FramebufferSurfacehwcomposer去做composer

Android的本地窗口

上面提到,如果需要使用OpenGL ES就需要本地窗口的加入,而在前面文章中提到有两处使用OpenGL ES的地方:一是上层的3D绘图,二是SurfaceFlingerlayer的合成(先不考虑Canvasoverlay)。那么我们可以想象下面这幅图画:

我们需要两种本地窗口,一种是面对app的,一种是面对SurfaceFlinger。那么本地窗口在android中到底是什么?我们从EGL函数的调用开始,在eglCreateWindowSurface函数中,有个和平台无关的结构体为NativeWindowType

EGLSurface eglCreateWindowSurface(  EGLDisplay dpy, EGLConfig config,

                                   NativeWindowType window,

                                    const EGLint*attrib_list)

{

    return createWindowSurface(dpy, config, window, attrib_list);

}

typedefEGLNativeWindowType  NativeWindowType;

从下面的定义可以看到,在系统为android的宏下,本地窗口其实为ANativeWindow

#elifdefined(__ANDROID__) || defined(ANDROID)

 

struct ANativeWindow;

structegl_native_pixmap_t;

 

typedefstructANativeWindow*          EGLNativeWindowType;

typedefstructegl_native_pixmap_t*    EGLNativePixmapType;

typedefvoid*                          EGLNativeDisplayType;

下面是ANativeWindow结构体,里面有一组函数指针,我们能够猜到,两个本地窗口都是继承了ANativeWindow,然后对函数进行赋值,实现协议

struct ANativeWindow

{

 

    structandroid_native_base_t common;

 

    /* flags describing some attributes ofthis surface or its updater */

    const uint32_t flags;

 

    /* min swap interval supported by this updated */

    constint   minSwapInterval;

 

    /* max swap interval supported by thisupdated */

    constint   maxSwapInterval;

 

    /* horizontal and vertical resolution inDPI */

    constfloat xdpi;

    constfloat ydpi;

 

    /* Some storage reserved for the OEM'sdriver. */

    intptr_t    oem[4];

 

 

    int     (*setSwapInterval)(struct ANativeWindow*window,

                int interval);

 

 

    int     (*query)(conststruct ANativeWindow*window,

                int what, int* value);

 

 

    int     (*perform)(struct ANativeWindow*window,

                int operation, ...);

 

 

    int     (*cancelBuffer_DEPRECATED)(struct ANativeWindow*window,

                structANativeWindowBuffer* buffer);

 

 

    int     (*dequeueBuffer)(struct ANativeWindow*window,

                structANativeWindowBuffer** buffer, int* fenceFd);

 

 

    int     (*queueBuffer)(struct ANativeWindow*window,

                structANativeWindowBuffer* buffer, int fenceFd);

 

 

    int     (*cancelBuffer)(struct ANativeWindow*window,

                structANativeWindowBuffer* buffer, int fenceFd);

};

最终找到的两个本地窗口为FramebufferNativeWindowSurface

FramebufferNativeWindow

SurfaceFlinger对应的本地窗口为FramebufferNativeWindow,继承了ANativeWindow,里面有个sp<NativeBuffer>buffers[MAX_NUM_FRAME_BUFFERS];,这应该就是本地的纸,而且还有和ANativeWindow对应的函数实现。

class FramebufferNativeWindow

    : publicANativeObjectBase<

       ANativeWindow,

        FramebufferNativeWindow,

       LightRefBase<FramebufferNativeWindow> >

{

public:

    FramebufferNativeWindow();

 

   framebuffer_device_t const * getDevice() const { return fbDev; }

 

    boolisUpdateOnDemand() const { returnmUpdateOnDemand; }

    status_tsetUpdateRectangle(const Rect&updateRect);

    status_tcompositionComplete();

 

    voiddump(String8& result);

 

    // for debugging only

    intgetCurrentBufferIndex() const;

 

private:

    friend classLightRefBase<FramebufferNativeWindow>;   

   ~FramebufferNativeWindow(); // this class cannot be overloaded

    staticintsetSwapInterval(ANativeWindow* window, int interval);

    staticintdequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer, int* fenceFd);

    staticint queueBuffer(ANativeWindow*window, ANativeWindowBuffer* buffer, int fenceFd);

    staticint query(const ANativeWindow*window, int what, int* value);

    staticintperform(ANativeWindow* window, int operation, ...);

 

    staticint dequeueBuffer_DEPRECATED(ANativeWindow*window, ANativeWindowBuffer** buffer);

    staticintqueueBuffer_DEPRECATED(ANativeWindow* window, ANativeWindowBuffer* buffer);

    staticintlockBuffer_DEPRECATED(ANativeWindow* window, ANativeWindowBuffer* buffer);

 

   framebuffer_device_t* fbDev;

    alloc_device_t*grDev;

 

   sp<NativeBuffer> buffers[MAX_NUM_FRAME_BUFFERS];

   sp<NativeBuffer> front;

 

    mutable Mutexmutex;

    ConditionmCondition;

    int32_tmNumBuffers;

    int32_tmNumFreeBuffers;

    int32_t mBufferHead;

    int32_tmCurrentBufferIndex;

    boolmUpdateOnDemand;

};

Surface

众多App对应的本地窗口为Surface,继承了ANativeWindow,类似的也有个BufferSlot mSlots[NUM_BUFFER_SLOTS];,是App本地的纸,而且还有和ANativeWindow对应的函数实现。

class Surface

    : public ANativeObjectBase<ANativeWindow,Surface, RefBase>

{

public:

 

    /*

     * creates aSurface from the given IGraphicBufferProducer (which concrete

     *implementation is a BufferQueue).

     *

     * Surface is mainlystate-less while it'sdisconnected, it can be

     * viewed as a glorifiedIGraphicBufferProducer holder. It's therefore

     * safe tocreate other Surfaces from the same IGraphicBufferProducer.

     *

     * However,once a Surface is connected,it'll prevent other Surfaces

     * referring tothe same IGraphicBufferProducer to become connected and

     * thereforeprevent them to be used as actual producers of buffers.

     *

     * thecontrolledByApp flag indicates that thisSurface (producer) is

     * controlledby the application. This flag is used at connect time.

     */

    Surface(constsp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp= false);

 

    /* getIGraphicBufferProducer() returnsthe IGraphicBufferProducer this

     * Surface was created with. Usually it'san error to use the

     * IGraphicBufferProducer while the Surfaceis connected.

     */

   sp<IGraphicBufferProducer> getIGraphicBufferProducer() const;

 

    /* convenience function to check thatthe given surface is non NULL as

     * well as its IGraphicBufferProducer */

    staticbool isValid(constsp<Surface>& surface) {

        return surface != NULL&& surface->getIGraphicBufferProducer() != NULL;

    }

 

protected:

    virtual ~Surface();

 

private:

    // can't becopied

    Surface& operator = (const Surface&rhs);

    Surface(const Surface&rhs);

 

    // ANativeWindow hooks

    staticinthook_cancelBuffer(ANativeWindow* window,

           ANativeWindowBuffer* buffer, int fenceFd);

    staticint hook_dequeueBuffer(ANativeWindow*window,

           ANativeWindowBuffer** buffer, int* fenceFd);

    staticinthook_perform(ANativeWindow* window, int operation, ...);

    staticint hook_query(const ANativeWindow*window, int what, int* value);

    staticinthook_queueBuffer(ANativeWindow* window,

           ANativeWindowBuffer* buffer, int fenceFd);

    staticinthook_setSwapInterval(ANativeWindow* window, int interval);

 

    staticinthook_cancelBuffer_DEPRECATED(ANativeWindow* window,

            ANativeWindowBuffer* buffer);

    staticinthook_dequeueBuffer_DEPRECATED(ANativeWindow* window,

           ANativeWindowBuffer** buffer);

    staticinthook_lockBuffer_DEPRECATED(ANativeWindow* window,

           ANativeWindowBuffer* buffer);

    staticinthook_queueBuffer_DEPRECATED(ANativeWindow* window,

           ANativeWindowBuffer* buffer);

 

    intdispatchConnect(va_list args);

    intdispatchDisconnect(va_list args);

    intdispatchSetBufferCount(va_list args);

    intdispatchSetBuffersGeometry(va_list args);

    intdispatchSetBuffersDimensions(va_list args);

    intdispatchSetBuffersUserDimensions(va_list args);

    intdispatchSetBuffersFormat(va_list args);

    intdispatchSetScalingMode(va_list args);

    int dispatchSetBuffersTransform(va_listargs);

    intdispatchSetBuffersTimestamp(va_list args);

    intdispatchSetCrop(va_list args);

    intdispatchSetPostTransformCrop(va_list args);

    intdispatchSetUsage(va_list args);

    intdispatchLock(va_list args);

    intdispatchUnlockAndPost(va_list args);

 

protected:

    virtualintdequeueBuffer(ANativeWindowBuffer**buffer, int* fenceFd);

    virtualintcancelBuffer(ANativeWindowBuffer* buffer, int fenceFd);

    virtualintqueueBuffer(ANativeWindowBuffer* buffer, int fenceFd);

    virtualint perform(int operation,va_list args);

    virtualint query(int what, int* value) const;

    virtualintsetSwapInterval(int interval);

 

    virtualintlockBuffer_DEPRECATED(ANativeWindowBuffer* buffer);

 

    virtualint connect(int api);

    virtualint disconnect(int api);

    virtualint setBufferCount(int bufferCount);

    virtualintsetBuffersDimensions(int w, int h);

    virtualintsetBuffersUserDimensions(int w, int h);

    virtualintsetBuffersFormat(int format);

    virtualint setScalingMode(int mode);

    virtualintsetBuffersTransform(int transform);

    virtualintsetBuffersTimestamp(int64_t timestamp);

    virtualint setCrop(Rect const* rect);

    virtualintsetUsage(uint32_t reqUsage);

 

public:

    virtualintlock(ANativeWindow_Buffer*outBuffer, ARect* inOutDirtyBounds);

    virtualintunlockAndPost();

 

protected:

    enum {NUM_BUFFER_SLOTS = BufferQueue::NUM_BUFFER_SLOTS };

    enum {DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 };

 

private:

    voidfreeAllBuffers();

    intgetSlotFromBufferLocked(android_native_buffer_t* buffer) const;

 

    struct BufferSlot {

       sp<GraphicBuffer> buffer;

        RegiondirtyRegion;

    };

 

    // mSurfaceTexture is the interface tothe surface texture server. All

    // operations on the surface textureclient ultimately translate into

    // interactions with the server usingthis interface.

    // TODO: rename to mBufferProducer

   sp<IGraphicBufferProducer> mGraphicBufferProducer;

 

    // mSlots stores the buffers that havebeen allocated for each buffer slot.

    // It is initialized to null pointers,and gets filled in with the result of

    // IGraphicBufferProducer::requestBufferwhen the client dequeues a buffer from a

    // slot that has not yet been used. Thebuffer allocated to a slot will also

    // be replaced if the requested bufferusage or geometry differs from that

    // of the buffer allocated to a slot.

    BufferSlotmSlots[NUM_BUFFER_SLOTS];

 

    // mReqWidth is the buffer width thatwill be requested at the next dequeue

    // operation. It is initialized to 1.

    uint32_tmReqWidth;

 

    // mReqHeight is the buffer height thatwill be requested at the next

    // dequeue operation. It is initializedto 1.

    uint32_tmReqHeight;

 

    // mReqFormat is the buffer pixel formatthat will be requested at the next

    // deuque operation. It is initializedto PIXEL_FORMAT_RGBA_8888.

    uint32_tmReqFormat;

 

    // mReqUsage is the set of buffer usageflags that will be requested

    // at the next deuque operation. It isinitialized to 0.

    uint32_tmReqUsage;

 

    // mTimestamp is the timestamp that willbe used for the next buffer queue

    // operation. It defaults toNATIVE_WINDOW_TIMESTAMP_AUTO, which means that

    // a timestamp is auto-generated whenqueueBuffer is called.

    int64_tmTimestamp;

 

    // mCrop is the crop rectangle that willbe used for the next buffer

    // that gets queued. It is set bycalling setCrop.

    Rect mCrop;

 

    // mScalingMode is the scaling mode that will be used forthe next

    // buffers that get queued. It is set bycalling setScalingMode.

    int mScalingMode;

 

    // mTransform is the transformidentifier that will be used for the next

    // buffer that gets queued. It is set bycalling setTransform.

    uint32_tmTransform;

 

     // mDefaultWidth is default width of thebuffers, regardless of the

     // native_window_set_buffers_dimensionscall.

     uint32_tmDefaultWidth;

 

     // mDefaultHeight is default height ofthe buffers, regardless of the

     // native_window_set_buffers_dimensionscall.

     uint32_tmDefaultHeight;

 

     // mUserWidth, if non-zero, is anapplication-specified override

     // of mDefaultWidth.  This is lower priority than the width set by

     // native_window_set_buffers_dimensions.

     uint32_tmUserWidth;

 

     // mUserHeight, if non-zero, is anapplication-specified override

     // of mDefaultHeight.  This is lower priority than the height set

     // by native_window_set_buffers_dimensions.

     uint32_tmUserHeight;

 

    // mTransformHint is the transformprobably applied to buffers of this

    // window. this is only a hint, actualtransform may differ.

    uint32_tmTransformHint;

 

    // mProducerControlledByApp whether thisbuffer producer is controlled

    // by the application

    boolmProducerControlledByApp;

 

    // mSwapIntervalZero set if we shoulddrop buffers at queue() time to

    // achieve an asynchronous swap interval

    boolmSwapIntervalZero;

 

    // mConsumerRunningBehind whether theconsumer is running more than

    // one buffer behind the producer.

    mutable boolmConsumerRunningBehind;

 

    // mMutex is the mutex used to preventconcurrent access to the member

    // variables of Surface objects. It must be locked whenever the

    // member variables are accessed.

    mutable MutexmMutex;

 

    // must be used from the lock/unlockthread

   sp<GraphicBuffer>          mLockedBuffer;

   sp<GraphicBuffer>           mPostedBuffer;

    bool                        mConnectedToCpu;

 

    // must be accessed from lock/unlockthread only

    RegionmDirtyRegion;

};

 

 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值