static DFBResult
sharedAllocateBuffer( CoreSurfacePool       *pool,
                      void                  *pool_data,
                      void                  *pool_local,
                      CoreSurfaceBuffer     *buffer,
                      CoreSurfaceAllocation *allocation,
                      void                  *alloc_data )
{
    CoreSurface          *surface;
    SharedPoolData       *data  = pool_data;
    SharedAllocationData *alloc = alloc_data;

    D_MAGIC_ASSERT( pool, CoreSurfacePool );
    D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );

    surface = buffer->surface;

    D_MAGIC_ASSERT( surface, CoreSurface );

    /* Create aligned shared system surface buffer if both base address and pitch are non-zero. */
    if (dfb_config->system_surface_align_base && dfb_config->system_surface_align_pitch) {
        /* Make sure base address and pitch are a positive power of two. */
        D_ASSERT( dfb_config->system_surface_align_base >= 2 );
        D_ASSERT( !(dfb_config->system_surface_align_base & (dfb_config->system_surface_align_base-1)) );
        D_ASSERT( dfb_config->system_surface_align_pitch >= 2 );
        D_ASSERT( !(dfb_config->system_surface_align_pitch & (dfb_config->system_surface_align_pitch-1)) );

        dfb_surface_calc_buffer_size( surface, dfb_config->system_surface_align_pitch, 0,
                                      &alloc->pitch, &alloc->size );

        alloc->addr = SHMALLOC( data->shmpool, alloc->size + dfb_config->system_surface_align_base );
        if ( !alloc->addr )
            return D_OOSHM();

        /* Calculate the aligned address. */

        unsigned long addr           = (unsigned long) alloc->addr;
        unsigned long aligned_offset = dfb_config->system_surface_align_base -
                                       (addr % dfb_config->system_surface_align_base );

        alloc->aligned_addr = (void*) (addr + aligned_offset);
    }
    else {
        /* Create un-aligned shared system surface buffer. */

        dfb_surface_calc_buffer_size( surface, 8, 0, &alloc->pitch, &alloc->size );

        alloc->addr = SHMALLOC( data->shmpool, alloc->size );
        if (!alloc->addr)
            return D_OOSHM();

        alloc->aligned_addr = NULL;
    }

    allocation->flags = CSALF_VOLATILE;
    allocation->size  = alloc->size;

    return DFB_OK;
}
static DFBResult
localAllocateBuffer( CoreSurfacePool       *pool,
                     void                  *pool_data,
                     void                  *pool_local,
                     CoreSurfaceBuffer     *buffer,
                     CoreSurfaceAllocation *allocation,
                     void                  *alloc_data )
{
     CoreSurface         *surface;
     LocalAllocationData *alloc = alloc_data;

     D_MAGIC_ASSERT( pool, CoreSurfacePool );
     D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
     D_ASSERT( alloc != NULL );

     surface = buffer->surface;
     D_MAGIC_ASSERT( surface, CoreSurface );
#ifndef ANDROID_NDK
     /* Create aligned local system surface buffer if both base address and pitch are non-zero. */
     if (dfb_config->system_surface_align_base && dfb_config->system_surface_align_pitch) {
          /* Make sure base address and pitch are a positive power of two. */
          D_ASSERT( dfb_config->system_surface_align_base >= 4 );
          D_ASSERT( !(dfb_config->system_surface_align_base & (dfb_config->system_surface_align_base-1)) );
          D_ASSERT( dfb_config->system_surface_align_pitch >= 2 );
          D_ASSERT( !(dfb_config->system_surface_align_pitch & (dfb_config->system_surface_align_pitch-1)) );

          dfb_surface_calc_buffer_size( surface, dfb_config->system_surface_align_pitch, 0,
                                        &alloc->pitch, &alloc->size );

          /* Note: The posix_memalign function requires base alignment to actually be at least four. */
          int tempRet = posix_memalign( &alloc->addr, dfb_config->system_surface_align_base, alloc->size );
          if ( tempRet != 0 ) {
              D_ERROR( "Local surface pool: Error from posix_memalign:%d with base alignment value:%d. "
                       "%s()-%s:%d\n",
                       tempRet, dfb_config->system_surface_align_base,
                       __FUNCTION__, __FILE__, __LINE__ );
              return DFB_FAILURE;
          }
     }
     else {
#endif
          /* Create un-aligned local system surface buffer. */

          dfb_surface_calc_buffer_size( surface, 8, 0, &alloc->pitch, &alloc->size );

          alloc->addr = D_MALLOC( alloc->size );
          if (!alloc->addr)
               return D_OOM();
#ifndef ANDROID_NDK
     }
#endif
     D_MAGIC_SET( alloc, LocalAllocationData );

     allocation->flags = CSALF_VOLATILE;
     allocation->size  = alloc->size;

     return DFB_OK;
}
static DFBResult
x11AllocateBuffer( CoreSurfacePool       *pool,
                   void                  *pool_data,
                   void                  *pool_local,
                   CoreSurfaceBuffer     *buffer,
                   CoreSurfaceAllocation *allocation,
                   void                  *alloc_data )
{
     CoreSurface       *surface;
     x11AllocationData *alloc = alloc_data;
     x11PoolLocalData  *local = pool_local;
     DFBX11            *x11   = local->x11;

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

     D_MAGIC_ASSERT( pool, CoreSurfacePool );
     D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );

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

     dfb_surface_calc_buffer_size( surface, 8, 2, &alloc->pitch, &allocation->size );

     return DFB_OK;
}
static DFBResult
x11AllocateBuffer( CoreSurfacePool       *pool,
                   void                  *pool_data,
                   void                  *pool_local,
                   CoreSurfaceBuffer     *buffer,
                   CoreSurfaceAllocation *allocation,
                   void                  *alloc_data )
{
     CoreSurface       *surface;
     x11AllocationData *alloc = alloc_data;
     x11PoolLocalData  *local = pool_local;
     DFBX11            *x11   = local->x11;

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

     D_MAGIC_ASSERT( pool, CoreSurfacePool );
     D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );

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

     if (x11ImageInit( x11, &alloc->image, surface->config.size.w, surface->config.size.h, surface->config.format ) == DFB_OK) {
          alloc->real  = true;
          alloc->pitch = alloc->image.pitch;

          allocation->size = surface->config.size.h * alloc->image.pitch;
     }
     else
          dfb_surface_calc_buffer_size( surface, 8, 2, &alloc->pitch, &allocation->size );

     return DFB_OK;
}
static DFBResult
sharedAllocateBuffer( CoreSurfacePool       *pool,
                      void                  *pool_data,
                      void                  *pool_local,
                      CoreSurfaceBuffer     *buffer,
                      CoreSurfaceAllocation *allocation,
                      void                  *alloc_data )
{
     CoreSurface          *surface;
     SharedPoolData       *data  = pool_data;
     SharedAllocationData *alloc = alloc_data;

     D_MAGIC_ASSERT( pool, CoreSurfacePool );
     D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );

     surface = buffer->surface;

     D_MAGIC_ASSERT( surface, CoreSurface );

     dfb_surface_calc_buffer_size( surface, 8, 0, &alloc->pitch, &alloc->size );

     alloc->addr = SHMALLOC( data->shmpool, alloc->size );
     if (!alloc->addr)
          return D_OOSHM();

     allocation->flags = CSALF_VOLATILE;
     allocation->size  = alloc->size;

     return DFB_OK;
}
Exemple #6
0
static DFBResult
fbdevAllocateBuffer( CoreSurfacePool       *pool,
                     void                  *pool_data,
                     void                  *pool_local,
                     CoreSurfaceBuffer     *buffer,
                     CoreSurfaceAllocation *allocation,
                     void                  *alloc_data )
{
     DFBResult            ret;
     CoreSurface         *surface;
     FBDevPoolData       *data  = pool_data;
     FBDevPoolLocalData  *local = pool_local;
     FBDevAllocationData *alloc = alloc_data;

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

     D_MAGIC_ASSERT( pool, CoreSurfacePool );
     D_MAGIC_ASSERT( data, FBDevPoolData );
     D_MAGIC_ASSERT( local, FBDevPoolLocalData );
     D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );

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

     if (surface->type & CSTF_LAYER && surface->resource_id == DLID_PRIMARY) {
          D_DEBUG_AT( FBDev_Surfaces, "  -> primary layer buffer (index %d)\n", dfb_surface_buffer_index( buffer ) );

          dfb_surface_calc_buffer_size( surface, 8, 1, NULL, &allocation->size );
     }
     else {
          ret = dfb_surfacemanager_allocate( local->core, data->manager, buffer, allocation, &alloc->chunk );
          if (ret)
               return ret;

          D_MAGIC_ASSERT( alloc->chunk, Chunk );

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

     D_MAGIC_SET( alloc, FBDevAllocationData );

     return DFB_OK;
}
static DFBResult
x11AllocateKey( CoreSurfacePool       *pool,
                void                  *pool_data,
                void                  *pool_local,
                CoreSurfaceBuffer     *buffer,
                const char            *key,
                u64                    handle,
                CoreSurfaceAllocation *allocation,
                void                  *alloc_data )
{
     CoreSurface       *surface;
     x11AllocationData *alloc = alloc_data;

     D_DEBUG_AT( X11_Surfaces, "%s( %s, 0x%08llx )\n", __FUNCTION__, key, (unsigned long long) handle );

     D_MAGIC_ASSERT( pool, CoreSurfacePool );
     D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );

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

     if (!strcmp( key, "Pixmap/X11" )) {
          D_DEBUG_AT( X11_Surfaces, "  -> Pixmap/X11\n" );

          alloc->type = X11_ALLOC_PIXMAP;
     }
     else if (!strcmp( key, "Window/X11" )) {
          D_DEBUG_AT( X11_Surfaces, "  -> Window/X11\n" );

          alloc->type = X11_ALLOC_WINDOW;
     }
     else {
          D_BUG( "unexpected key '%s'", key );
          return DFB_BUG;
     }

     dfb_surface_calc_buffer_size( surface, 8, 8, &alloc->pitch, &allocation->size );

     alloc->xid = (unsigned long) handle;

     return DFB_OK;
}
static DFBResult
x11AllocateBuffer( CoreSurfacePool       *pool,
                   void                  *pool_data,
                   void                  *pool_local,
                   CoreSurfaceBuffer     *buffer,
                   CoreSurfaceAllocation *allocation,
                   void                  *alloc_data )
{
     CoreSurface       *surface;
     x11AllocationData *alloc = alloc_data;
     x11PoolLocalData  *local = pool_local;
     DFBX11            *x11   = local->x11;

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

     D_MAGIC_ASSERT( pool, CoreSurfacePool );
     D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );

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

     dfb_surface_calc_buffer_size( surface, 8, 8, &alloc->pitch, &allocation->size );

     if (buffer->type & CSTF_PREALLOCATED) {
          D_DEBUG_AT( X11_Surfaces, "  -> preallocated from %p\n", buffer->config.preallocated[0].handle );

          alloc->type = X11_ALLOC_PIXMAP;
          alloc->xid  = (unsigned long) buffer->config.preallocated[0].handle;
     }
     else {
          if (x11ImageInit( x11, &alloc->image, surface->config.size.w, surface->config.size.h, surface->config.format ) == DFB_OK) {
               alloc->type  = X11_ALLOC_IMAGE;
               alloc->pitch = alloc->image.pitch;

               allocation->size = surface->config.size.h * alloc->image.pitch;
          }
          else
               alloc->type = X11_ALLOC_SHM;
     }

     return DFB_OK;
}
static DFBResult
x11AllocateKey( CoreSurfacePool       *pool,
                void                  *pool_data,
                void                  *pool_local,
                CoreSurfaceBuffer     *buffer,
                const char            *key,
                u64                    handle,
                CoreSurfaceAllocation *allocation,
                void                  *alloc_data )
{
     CoreSurface       *surface;
     x11AllocationData *alloc = alloc_data;
     x11PoolLocalData  *local = pool_local;
     DFBX11            *x11   = local->x11;

     D_DEBUG_AT( X11_Surfaces, "%s( %s, 0x%08llx )\n", __FUNCTION__, key, (unsigned long long) handle );
     D_DEBUG_AT( X11_Surfaces, "  -> allocation: %s\n", ToString_CoreSurfaceAllocation( allocation ) );

     D_MAGIC_ASSERT( pool, CoreSurfacePool );
     D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );

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

     if (!strcmp( key, "Pixmap/X11" )) {
          D_DEBUG_AT( X11_Surfaces, "  -> Pixmap/X11\n" );

          alloc->type = X11_ALLOC_PIXMAP;
     }
     else if (!strcmp( key, "Window/X11" )) {
          D_DEBUG_AT( X11_Surfaces, "  -> Window/X11\n" );

          alloc->type = X11_ALLOC_WINDOW;
     }
     else {
          D_BUG( "unexpected key '%s'", key );
          return DFB_BUG;
     }

     dfb_surface_calc_buffer_size( surface, 8, 8, &alloc->pitch, &allocation->size );

//     alloc->depth  = DefaultDepthOfScreen( x11->screenptr );
//     alloc->visual = DefaultVisualOfScreen( x11->screenptr );
     alloc->visual = x11->visuals[DFB_PIXELFORMAT_INDEX(buffer->format)];
     alloc->depth  = DFB_COLOR_BITS_PER_PIXEL( buffer->format ) + DFB_ALPHA_BITS_PER_PIXEL( buffer->format );

     if (alloc->depth == DefaultDepthOfScreen( x11->screenptr ))
          alloc->visual = DefaultVisualOfScreen( x11->screenptr );

     D_DEBUG_AT( X11_Surfaces, "  -> visual %p (id %lu), depth %d\n", alloc->visual, alloc->visual->visualid, alloc->depth );

     if (handle) {
          switch (alloc->type) {
               case X11_ALLOC_PIXMAP:
                    XLockDisplay( x11->display );

                    alloc->xid = (unsigned long) handle;
                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> pixmap 0x%08lx\n", (long) alloc->xid );

                    XUnlockDisplay( x11->display );

                    D_INFO( "X11/Windows: Import Pixmap 0x%08lx\n", alloc->xid );
                    break;

               case X11_ALLOC_WINDOW: {
                    XLockDisplay( x11->display );

                    alloc->window = (unsigned long) handle;
                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> window 0x%08lx\n", (long) alloc->window );

                    XCompositeRedirectWindow( x11->display, alloc->window, CompositeRedirectManual );
                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> redirected\n" );

                    alloc->xid = XCompositeNameWindowPixmap( x11->display, alloc->window );
//                    alloc->xid = alloc->window;
                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> pixmap 0x%08lx\n", (long) alloc->xid );

                    XUnmapWindow( x11->display, alloc->window );
                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> unmapped\n" );

                    XUnlockDisplay( x11->display );

                    D_INFO( "X11/Windows: Import Window 0x%08lx with Pixmap handle 0x%08lx\n", alloc->window, alloc->xid );
                    break;
               }

               default:
                    D_BUG( "unexpected allocation type %d\n", alloc->type );
                    return DFB_BUG;
          }
     }
     else {
//          alloc->type = X11_ALLOC_PIXMAP;

          switch (alloc->type) {
               case X11_ALLOC_PIXMAP:
                    XLockDisplay( x11->display );

                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> creating pixmap...\n" );

                    alloc->xid = XCreatePixmap( x11->display, DefaultRootWindow(x11->display),
                                                allocation->config.size.w, allocation->config.size.h, alloc->depth );
                    x11->Sync( x11 );
                    XSync( x11->display, False );
                    D_DEBUG_AT( X11_Surfaces, "  -> pixmap 0x%08lx\n", (long) alloc->xid );

                    XUnlockDisplay( x11->display );

                    D_INFO( "X11/Windows: New Pixmap 0x%08lx\n", alloc->xid );

                    alloc->created = true;
                    break;

               case X11_ALLOC_WINDOW: {
                    Window w = (Window) (long) buffer->surface->data;


                    XSetWindowAttributes attr;

                    attr.event_mask =
                           ButtonPressMask
                         | ButtonReleaseMask
                         | PointerMotionMask
                         | KeyPressMask
                         | KeyReleaseMask
                         | ExposureMask
                         | StructureNotifyMask;

                    attr.background_pixmap = 0;

                    XLockDisplay( x11->display );

                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> creating window...\n" );

                    alloc->window = w?:XCreateWindow( x11->display,
                                                   DefaultRootWindow(x11->display),
                                                   600, 200, allocation->config.size.w, allocation->config.size.h, 0,
                                                   alloc->depth, InputOutput,
                                                   alloc->visual, CWEventMask, &attr );
                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> window 0x%08lx\n", (long) alloc->window );
                    buffer->surface->data = (void*) (long) alloc->window;

                    XMapRaised( x11->display, alloc->window );
                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> raised\n" );

                    XCompositeRedirectWindow( x11->display, alloc->window, CompositeRedirectManual );
                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> redirected\n" );

                    alloc->xid = XCompositeNameWindowPixmap( x11->display, alloc->window );
//                    alloc->xid = alloc->window;
                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> pixmap 0x%08lx\n", (long) alloc->xid );

                    XUnmapWindow( x11->display, alloc->window );
                    x11->Sync( x11 );
                    D_DEBUG_AT( X11_Surfaces, "  -> unmapped\n" );

                    XUnlockDisplay( x11->display );

                    D_INFO( "X11/Windows: New Window 0x%08lx with Pixmap handle 0x%08lx\n", alloc->window, alloc->xid );

                    alloc->created = !w;
                    break;
               }

               default:
                    D_BUG( "unexpected allocation type %d\n", alloc->type );
                    return DFB_BUG;
          }
     }

     alloc->gc = XCreateGC( x11->display, alloc->xid, 0, NULL );

     allocation->offset = alloc->type;

     return DFB_OK;
}