DirectFB 2.0: Surface Pools
From DirectFB
Introduction
- DirectFB 1.0 just had basic notion of system memory using local or shared memory and video memory with a fixed physical address and size of a contiguous block of memory, directly mappable by the CPU and managed solely by DirectFB's builtin surface manager - a one-dimensional memory manager with kick-out of older allocations backed up in local memory.
- There was only a minor case where a system or driver module could control or implement allocations itself, as part of the display layer driver API: AllocateSurface(), ReallocateSurface() and DeallocateSurface(). These were usually not implemented by drivers, thus using the standard allocation in video memory.
New Surface Core
- Surface Pools are the new key abstraction to break out of this limited model, which only did a good job for Linux' Frame Buffer Device or other Low Level APIs, also (part of) /dev/mem.
- The big step was moving away from the hardcoded system<->video heap logic including sync, transfer, locking, etc. to a generic mechanism with any number of heaps/pools with totally different capabilities, allowing system/driver module to provide their own implementations (pools) just like input drivers (devices).
- Surface Pool Negotiation is one of the key aspects, because it routes allocation requests for surface buffers to the correct pool, or the best suitable when more than one is supporting all required access flags, e.g. CPU/GPU, surface type flags, e.g. Layer or Font, and other criteria that will be added.
- After a surface has been created as a CoreSurface (FusionObject), based on the chosen CoreSurfaceConfiguration, the CoreSurfaceBuffer structures are allocated and added without any actual allocation of pixel data happening. Even after returning, the buffers are still virtual entities. The first Lock or Write will trigger the negotiation, before allocation/locking in the right pool happens.
Surface Pool API
The following gives an overview of what an implementor/integrator has to provide:
- Initialization or Attach and Deinitialization or Detach of a Surface Pool
- Initialize() (returning caps/flags) and Shutdown() in the master process
- TestConfig() adds another way for system modules and drivers to refine negotiation
- Join() and Leave() are called in slave processes for attaching/detaching
- Allocating Buffers within a Surface Pool
- AllocateBuffer()
- DeallocateBuffer()
- Locking Allocations for CPU, GPU, Display Controller and other entities
- Lock() returns a virtual or physical address, just a handle, or a combination
- Unlock() releases the Allocation, allowing it to move or deallocate (if volatile)
- Reading and Writing in buffers not directly addressable
- Read() from or Write() to an Allocation

