ANativeWindow

  1. ANativeWindow : opengl工作的绘图画布本地窗口,按标准定义好函数(下面好多代码都简化)

struct ANativeWindow
{
   .....
   
   //上层定义好函数指针,传给opengl后,opengl在必要的时候会调用相应的函数
   int     (*dequeueBuffer )(struct ANativeWindow* window ,
                struct ANativeWindowBuffer ** buffer, int* fenceFd );
   
   int     (*queueBuffer )(struct ANativeWindow* window ,
                struct ANativeWindowBuffer * buffer, int fenceFd );

   int     (*cancelBuffer )(struct ANativeWindow* window ,
                struct ANativeWindowBuffer * buffer, int fenceFd );
}

ANativeWindowBuffer:绘制的图像缓冲区
struct ANativeWindowBuffer
{
    intwidth;
    int height ;
    int usage;
     .....
   //通过这个handle就跟Gralloc模块申请的图片缓存关联起来了,可能在fb申请也能是共享内存中申请的(看他了usage
    buffer_handle_t handle
}

fenceFd:暂时把他当作这个buffer的锁,因为缓存区需要cpu,gpu,composer共享,普通锁不管用啊。


   2.android中的本地窗口
      (1.)操作显存的,surfaceflinger服务中应用的。最总渲染到屏幕的
FramebufferNativeWindow: public ANativeObjectBase <
        ANativeWindow FramebufferNativeWindow,
        LightRefBase<FramebufferNativeWindow > >
别看上面的这么复杂其实就是 FramebufferNativeWindow: public ANativeWindow,看名字就是包装了fb显存了,用它直接绘制到屏幕上的
  
构造函数:
FramebufferNativeWindow ::FramebufferNativeWindow()
    : BASE(), fbDev (0), grDev(0), mUpdateOnDemand(false )
{
    hw_module_t const * module;
    //打开Gralloc硬件抽象层模块
    hw_get_module (GRALLOC_HARDWARE_MODULE_ID, & module);
    //获取抽象层中的fb设备定义,渲染到屏幕的
    framebuffer_open (module, & fbDev); 
    //获取抽象层图像缓存申请设备,获取一段内存或显存的
    gralloc_open (module, & grDev);
       
    //看一下fb支持缓冲区大小,可能有多个离屏缓冲,初始化一下这些缓冲区 
    if(fbDev ->numFramebuffers >= MIN_NUM_FRAME_BUFFERS && fbDev->numFramebuffers <= MAX_NUM_FRAME_BUFFERS){
        mNumBuffers = fbDev ->numFramebuffers;
    } else {
        mNumBuffers = MIN_NUM_FRAME_BUFFERS ;
    }   
    for (i = 0; i < mNumBuffers; i++)
    {
         //  NativeBuffer : public ANativeWindowBuffer 从ANativeWindowBuffer继承
         buffers[i] = new  NativeBuffer(fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB );
         grDev ->alloc( grDev, fbDev->width , fbDev-> height, fbDev ->format, GRALLOC_USAGE_HW_FB, &buffers [i]-> handle, &buffers[i ]->stride);          
    }

    //opengl需要的本地窗口定义了
    const_cast<uint32_t &>(ANativeWindow:: flags) = fbDev ->flags;
    const_cast<float &>(ANativeWindow:: xdpi) = fbDev ->xdpi;
    const_cast<float &>(ANativeWindow:: ydpi) = fbDev ->ydpi;
    const_cast<int &>(ANativeWindow:: minSwapInterval) = fbDev->minSwapInterval ;
    const_cast<int &>(ANativeWindow:: maxSwapInterval) = fbDev->maxSwapInterval ;
    ANativeWindow::setSwapInterval = setSwapInterval;
    ANativeWindow::dequeueBuffer = dequeueBuffer;
    ANativeWindow::queueBuffer = queueBuffer;
    ANativeWindow::query = query;
    ANativeWindow::perform = perform;
    ANativeWindow::dequeueBuffer_DEPRECATED = dequeueBuffer_DEPRECATED;
    ANativeWindow::lockBuffer_DEPRECATED = lockBuffer_DEPRECATED;
    ANativeWindow::queueBuffer_DEPRECATED = queueBuffer_DEPRECATED;
}   

int FramebufferNativeWindow ::setSwapInterval( ANativeWindow* window , int interval)
{
    return fb ->setSwapInterval( fb, interval );
}

//opengl要一个图像缓冲区,要后台绘制了
int FramebufferNativeWindow ::dequeueBuffer( ANativeWindow* window ANativeWindowBuffer** buffer , int* fenceFd)
{
    //根据一系列条件找到一个空闲的缓冲区,如果没有空闲的了,还的等待queuebuffer释放一个缓存
    int index =???
    * buffer = self ->buffers[ index].get ();
    * fenceFd = -1;
}

//这个buffer绘制完成,可以绘制到屏幕上了
int FramebufferNativeWindow ::queueBuffer( ANativeWindow* window , ANativeWindowBuffer* buffer , int fenceFd)
{
    //等待其他硬件都这个buffer操作完成
    sp<Fence> fence(newFence(fenceFd));
    fence->wait (Fence:: TIMEOUT_NEVER);  
    //绘制到屏幕上
    fb-> post(fb , handle);
}

egl中定义了:
typedef struct ANativeWindow*           EGLNativeWindowType;

  (2.)app端,临时用的的ANativeWindow,最终这个buffer会间接的提交到Framebuffer那面,显示到屏幕上。
 
class Surface : public ANativeObjectBase<ANativeWindow, Surface, RefBase>
构造函数,跟上面的差不多吧,都先初始化ANativeWindow相关函数接口
Surface::Surface ( const sp <IGraphicBufferProducer>& bufferProducer, bool controlledByApp )
    : mGraphicBufferProducer(bufferProducer )
{
    ANativeWindow::setSwapInterval   = hook_setSwapInterval;
    ANativeWindow::dequeueBuffer     = hook_dequeueBuffer;
    ANativeWindow::cancelBuffer      = hook_cancelBuffer;
    ANativeWindow::queueBuffer       = hook_queueBuffer;
    ANativeWindow::query             = hook_query;
    ANativeWindow::perform           = hook_perform;

    ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED ;
    ANativeWindow::cancelBuffer_DEPRECATED   = hook_cancelBuffer_DEPRECATED ;
    ANativeWindow::lockBuffer_DEPRECATED     = hook_lockBuffer_DEPRECATED ;
    ANativeWindow::queueBuffer_DEPRECATED    = hook_queueBuffer_DEPRECATED ;
    const_cast<int &>(ANativeWindow:: minSwapInterval) = 0;
    const_cast<int &>(ANativeWindow:: maxSwapInterval) = 1;

    mReqWidth = 0;
    mReqHeight = 0;
    mReqFormat = 0;
    .....
}

//opengl要一个图像缓冲区,要后台绘制了  
int Surface ::dequeueBuffer( android_native_buffer_t** buffer , int* fenceFd) { 
    sp<Fence > fence;

    // producer(BufferQueue)中获取一段空闲的图像缓冲区,这个内部也是通过硬件抽象层的Gralloc申请的
    status_t result = mGraphicBufferProducer-> dequeueBuffer(&buf , &fence, mSwapIntervalZero , reqW, reqH , mReqFormat, mReqUsage);
    sp<GraphicBuffer >& gbuf( mSlots[buf ].buffer);
    if ((result & IGraphicBufferProducer:: BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
        result = mGraphicBufferProducer ->requestBuffer( buf, &gbuf );
    }

    * fenceFd = fence ->dup();
    * buffer = gbuf .get();
    return OK ;
}

//这个buffer绘制完成,可以用了啊 
int Surface ::queueBuffer( android_native_buffer_t* buffer , int fenceFd) {

    Rect crop ;
    mCrop.intersect (Rect( buffer->width , buffer-> height), &crop );
    sp<Fence > fence( fenceFd >= 0 ? new Fence( fenceFd) : Fence::NO_FENCE );
    IGraphicBufferProducer::QueueBufferOutput output;
    IGraphicBufferProducer::QueueBufferInput input( timestamp, isAutoTimestamp,
            crop, mScalingMode , mTransform, mSwapIntervalZero, fence );

    //producer(BufferQueue)添加一段填充好的buffer,需要渲染buffer的就看着办吧
    status_t err = mGraphicBufferProducer-> queueBuffer(i , input, &output);
    uint32_t numPendingBuffers = 0;
    output.deflate (&mDefaultWidth, & mDefaultHeight, &mTransformHint ,
            & numPendingBuffers);
    return err ;
}

mGraphicBufferProducer  (BufferQueue)入队,出队是 一个跨进程的操作,他们通过Binder通讯。
   BufferQueue是一个典型的生产消费结构,生产者加工好数据丢进来,消耗者发现有数据后马上消耗掉,这个以后再分析。

3.opengl如何使用这个ANativeWindow的呢
   android中opengl环境的搭建是由EGL帮忙完成的,opengl是一组跨进程的api,


NativeWindowType就是一个ANativeWindow
typedef struct ANativeWindow*           EGLNativeWindowType;
  
EGLSurface eglCreateWindowSurface EGLDisplay dpy, EGLConfig config, NativeWindowType window , const EGLint *attrib_list)
{
    //保存了加载的opengl相关的so导出接口,egl接口
    egl_connection_t* cnx = NULL;
    egl_display_ptr dp = validate_display_connection( dpy, cnx );

    //可以想象一下就是吧window包装成一个EGlSurface,cnx-> egl是so提供的一系类函数指针
    EGLSurface surface = cnx-> egl.eglCreateWindowSurface ( iDpy, config , window, attrib_list);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值