static DFBResult
osdJoinPool( CoreDFB         *core,
             CoreSurfacePool *pool,
             void            *pool_data,
             void            *pool_local,
             void            *system_data )
{
     OSDPoolData       *data  = pool_data;
     OSDPoolLocalData  *local = pool_local;
     DavinciDriverData *ddrv  = dfb_gfxcard_get_driver_data();
     DavinciDeviceData *ddev  = dfb_gfxcard_get_device_data();

     D_DEBUG_AT( OSD_Surfaces, "%s()\n", __FUNCTION__ );

     D_ASSERT( core != NULL );
     D_MAGIC_ASSERT( pool, CoreSurfacePool );
     D_MAGIC_ASSERT( data, OSDPoolData );
     D_ASSERT( local != NULL );

     (void) data;

     local->core = core;
     local->mem  = ddrv->fb[OSD0].mem;
     local->phys = ddev->fix[OSD0].smem_start;

     D_MAGIC_SET( local, OSDPoolLocalData );

     return DFB_OK;
}
static DFBResult
osdInitPool( CoreDFB                    *core,
             CoreSurfacePool            *pool,
             void                       *pool_data,
             void                       *pool_local,
             void                       *system_data,
             CoreSurfacePoolDescription *ret_desc )
{
     OSDPoolData       *data  = pool_data;
     OSDPoolLocalData  *local = pool_local;
     DavinciDriverData *ddrv  = dfb_gfxcard_get_driver_data();
     DavinciDeviceData *ddev  = dfb_gfxcard_get_device_data();

     D_DEBUG_AT( OSD_Surfaces, "%s()\n", __FUNCTION__ );

     D_ASSERT( core != NULL );
     D_MAGIC_ASSERT( pool, CoreSurfacePool );
     D_ASSERT( data != NULL );
     D_ASSERT( local != NULL );
     D_ASSERT( ret_desc != NULL );

     ret_desc->caps     = CSPCAPS_NONE;
     ret_desc->access   = CSAF_CPU_READ | CSAF_CPU_WRITE | CSAF_GPU_READ | CSAF_GPU_WRITE | CSAF_SHARED;
     ret_desc->types    = CSTF_LAYER | CSTF_SHARED | CSTF_EXTERNAL;
     ret_desc->priority = CSPP_DEFAULT;

     snprintf( ret_desc->name, DFB_SURFACE_POOL_DESC_NAME_LENGTH, "OSD Pool" );

     local->core = core;
     local->mem  = ddrv->fb[OSD0].mem;
     local->phys = ddev->fix[OSD0].smem_start;

     D_MAGIC_SET( data, OSDPoolData );
     D_MAGIC_SET( local, OSDPoolLocalData );

     return DFB_OK;
}
static DFBResult
stmfbdevUnlock (CoreSurfacePool       *pool,
                void                  *pool_data,
                void                  *pool_local,
                CoreSurfaceAllocation *allocation,
                void                  *alloc_data,
                CoreSurfaceBufferLock *lock)
{
  const STMfbdevPoolData           * const data = pool_data;
  const STMfbdevPoolLocalData      * const local = pool_local;
  const STMfbdevPoolAllocationData * const alloc = alloc_data;

  D_MAGIC_ASSERT (pool, CoreSurfacePool);
  D_MAGIC_ASSERT (data, STMfbdevPoolData);
  D_MAGIC_ASSERT (local, STMfbdevPoolLocalData);
  D_MAGIC_ASSERT (allocation, CoreSurfaceAllocation);
  D_MAGIC_ASSERT (alloc, STMfbdevPoolAllocationData);
  D_MAGIC_ASSERT (lock, CoreSurfaceBufferLock);

  D_DEBUG_AT (STMfbdev_SurfLock, "%s (%p)\n", __FUNCTION__, lock->buffer);

  (void) data;
  (void) local;
  (void) alloc;

#if D_DEBUG_ENABLED
  {
  /* heavy performance hit */
  char *accessor = _accessor_str (lock->accessor);
  char *access   = _access_str (lock->access);
  D_DEBUG_AT (STMfbdev_SurfLock, "  -> by %s for %s\n", accessor,  access);
  free (access);
  free (accessor);
  }
#endif

#if STGFX_DRIVER == 2
  if (unlikely (lock->buffer->format == DSPF_RGB32
                && lock->accessor != CSAID_GPU
                && lock->access & CSAF_WRITE))
    {
      /* if a non-GPU accessor did a write access to an RGB32 surface, we
         should make sure the alpha is forced to 0xff, as the BDisp doesn't
         support this format natively */
      STGFX2DriverData * const stdrv = dfb_gfxcard_get_driver_data ();
      STGFX2DeviceData * const stdev = dfb_gfxcard_get_device_data ();
      DFBRectangle      rect = { .x = 0, .y = 0,
                                 .w = lock->buffer->surface->config.size.w,
                                 .h = lock->buffer->surface->config.size.h };

      D_DEBUG_AT (STMfbdev_SurfLock, "  -> rgb32 write release!\n");
      dfb_gfxcard_lock (GDLF_WAIT);
      _bdisp_aq_RGB32_fixup (stdrv, stdev,
                             lock->phys, lock->pitch,
                             &rect);
      dfb_gfxcard_unlock ();
    }
#endif

  return DFB_OK;
}
static DFBResult
stmfbdevAllocateBuffer (CoreSurfacePool       *pool,
                        void                  *pool_data,
                        void                  *pool_local,
                        CoreSurfaceBuffer     *buffer,
                        CoreSurfaceAllocation *allocation,
                        void                  *alloc_data)
{
  CoreSurface                *surface;
  STMfbdevPoolData           * const data  = pool_data;
  STMfbdevPoolLocalData      * const local = pool_local;
  STMfbdevPoolAllocationData * const alloc = alloc_data;
  DFBResult                   ret;
  Chunk                      *chunk;

  D_DEBUG_AT (STMfbdev_Surfaces, "%s (%p)\n", __FUNCTION__, buffer);

  D_MAGIC_ASSERT (pool, CoreSurfacePool);
  D_MAGIC_ASSERT (data, STMfbdevPoolData);
  D_MAGIC_ASSERT (local, STMfbdevPoolLocalData);
  D_MAGIC_ASSERT (buffer, CoreSurfaceBuffer);
  D_MAGIC_ASSERT (allocation, CoreSurfaceAllocation);

  surface = buffer->surface;
  D_MAGIC_ASSERT (surface, CoreSurface);

  ret = dfb_surfacemanager_allocate (local->core, data->manager, buffer,
                                     allocation, &chunk);
  if (ret)
    return ret;

  D_MAGIC_ASSERT (chunk, Chunk);

  alloc->chunk = chunk;

  D_DEBUG_AT (STMfbdev_Surfaces,
              "  -> offset 0x%.8x (%u), format: %s, pitch %d, size %d\n",
              chunk->offset, chunk->offset,
              dfb_pixelformat_name (buffer->format), chunk->pitch,
              chunk->length);

  allocation->size   = chunk->length;
  allocation->offset = chunk->offset;

#if STGFX_DRIVER == 2
  if (unlikely (buffer->format == DSPF_RGB32))
    {
      /* for RGB32, we need to set the alpha to 0xff */
      STGFX2DriverData * const stdrv = dfb_gfxcard_get_driver_data ();
      STGFX2DeviceData * const stdev = dfb_gfxcard_get_device_data ();
      DFBRectangle      rect = { .x = 0, .y = 0,
                                 .w = buffer->surface->config.size.w,
                                 .h = buffer->surface->config.size.h };

      D_WARN ("BDisp/Surfaces: RGB32 support is experimental and slow!");
      if (dfb_system_type () != CORE_STMFBDEV)
        D_WARN ("BDisp/Surfaces: RGB32 is only supported in STMfbdev system!");

      D_DEBUG_AT (STMfbdev_Surfaces, "  -> rgb32 allocation!\n");
      dfb_gfxcard_lock (GDLF_WAIT);

      _bdisp_aq_RGB32_init (stdrv, stdev,
                            data->physical + chunk->offset, chunk->pitch,
                            &rect);
      dfb_gfxcard_unlock ();
    }
#endif

  D_MAGIC_SET (alloc, STMfbdevPoolAllocationData);

  return DFB_OK;
}