DirectFB内存分配与管理:surface pool

来源:互联网 发布:啥软件可以看禁播动漫 编辑:程序博客网 时间:2024/04/30 15:34

    1.1版本之前,DFB只有基本的系统内存概念,即使用局部或共享内存;或者视频内存概念,即固定的物理地址和一定大小的连续的内存块,该内存直接由CPU映射或者由DFB内置的内存管理器Surface Manager管理。Surface Manager是一个一维的内存管理器,它会踢出(kick-out)过时的(即不再需要的)内存。这些内存一般是本地备份的内存。只有很少的情况,系统或驱动模块可以控制或自己实现内存分配。通过调用显示层(Display Driver)驱动API: AllocateSurface()ReallocateSurface()DeallocateSurface().这些内存分配和释放通常不是由驱动实现的,因此通常使用video内存中的标准分配。

    1.1版本以后,DFB引入了平面池surface pool的概念,因此程序员可以以自己的方式管理平面缓存(surface buffer)。Surface Pool最大的优势是将hardcodedsystem<->video堆(heap)逻辑(包括synctransfer,locking等),转移到通用的机制。你可以创建任意多的heaps/pools

     Surface Pool Negotiation是关键的一步,因为它把surface buffer内存分配请求路由到正确的pool.如果有多个pool满足条件,则从中选择一个最合适的。这些条件包括:支持必要的访问flagaccess flags,CPU/GPU),surface类型标记(如Layer font)和其他必要的标准。

     当一个CoreSurface基于选定的CoreSurfaceConfiguration配置创建好以后,CoreSurfaceBuffer结构就分配和添加好了,然而其实并没有任何像素数据的分配发生。第一个lockwrite操作会触发negotiation操作。

 

 

      例如,当用户需要进行画图操作时,会在获取显卡状态时,首先对buffer进行lock.即调用dfb_surface_buffer_lock。该函数检查有没有合适内存分配对象allocation存在,如果没有则调用dfb_surface_pools_allocate( buffer, accessor, access, &allocation );去创建一个allocation对象。

     dfb_surface_pools_allocate会做些什么操作呢?关键的一步,是去作平面池协商Surface Pool Negotiation,调用: dfb_surface_pools_negotiate( buffer, accessor, access, pools, pool_count, &num_pools )。

      这个协商主要作什么呢?前面讲过,它把surface buffer内存分配请求路由到正确的pool。何为正确的pool?当然是那些能满足内存分配需求的pool.所以,我们会看到,在这个协商函数里,它会遍历各个pool, 来找到那个满足我们需求的pool.它会调用system module(如 fbdev)的Testconfig.Testconfig会计算出我们需要分配的buffer大小并使用framebuffer驱动的ioctrl,查询我们是否能完成满足内存分配的能力。

    当pool找到了,下一步就是调用dfb_surface_pool_allocate( pool, buffer, &allocation )为这些pool创建allocation对象。这个allocation对象到底是什么个东东呢?请参考下图。

  

      我们假设system module采用fbdev。那么,在上面这个allocate函数里,会出现 funcs->AllocateBuffer( pool, pool->data, get_local(pool), buffer, allocation, allocation->data )这样的代码,最终将调用fbdevAllocateBuffer分配内存。allocation的buffer、surface、pool、access、size和offset成员将得到赋值。其中size和offset是通过fbdev的AllocateBuffer 并通过ioctrl获取而赋值的。接着我们调用dfb_surface_allocation_update对buffer的allocation进行更新,主要是written和read成员。

     在allocation创建和更新后,我们会对该allocation进行锁定,它的实现由dfb_surface_pool_lock( allocation->pool, allocation, lock )来完成。参数lock是CoreSurfaceBufferLock类型,是读、写锁的抽象,这个锁是显卡状态的一个成员变量。

    可见,先将lock的allocation成员与我们分配的allocation对象关联起来。然后,调用fbdevLock函数,完成其他成员的赋值。如下图:

 

 上面的alloc是在fbdevAllocateBuffer通过ioctrl从底层获取的。它通过allocation的成员变量data进行传递。

 

   

 

Smith先生版权所有,如需转载,请注明出处:http://blog.csdn.net/acs713/article/details/7879545