Exemple #1
0
static bool
ep9xBlit( void *drv, void *dev, DFBRectangle *rect, int dx, int dy )
{

     EP9XDriverData *ep9xdrv = (EP9XDriverData *) drv;
     EP9XDeviceData *ep9xdev = (EP9XDeviceData *) dev;
     struct fb_image image;

     D_DEBUG_AT(ep9x,"%s:enter\n",__FUNCTION__);

     if (!(ep9xdev->clip.x1 <= dx) || !(ep9xdev->clip.y1 <= dy) || 
         !( ep9xdev->clip.x2 >= (dx + rect->w - 1) ) || !( ep9xdev->clip.y2 >= (dy + rect->h - 1) )) {
          D_ERROR("the blit region is not vaild\n");
          return false;
     }

     image.dx = ep9xdev->destaddr + dx;
     image.dy = dy;
     image.width = rect->w; 
     image.height = rect->h;
     image.depth = ep9xdev->pixeldepth;
     if ( ep9xdev->fb_store == true )
          image.data = (void*)ep9xdev->fb_addr + ep9xdev->srcaddr + DFB_BYTES_PER_LINE( ep9xdev->pixelformat,rect->x ) + (rect->y * ep9xdev->srcpitch );
     else
          image.data = (void*)ep9xdev->srcaddr + DFB_BYTES_PER_LINE( ep9xdev->pixelformat, rect->x ) + (rect->y * ep9xdev->srcpitch );

     ioctl(ep9xdrv->dfb_fbdev->fd,FBIO_EP9X_BLIT,&image);

     D_DEBUG_AT(ep9x,"%s:exit\n",__FUNCTION__);

     return true;   
}
void Genefx_Aop_xy( GenefxState *gfxs, int x, int y )
{
     int pitch = gfxs->dst_pitch;

     gfxs->Aop[0] = gfxs->dst_org[0];
     gfxs->AopY   = y;

     if (gfxs->dst_caps & DSCAPS_SEPARATED) {
          gfxs->Aop_field = y & 1;
          if (gfxs->Aop_field)
               gfxs->Aop[0] += gfxs->dst_field_offset;

          y /= 2;
     }

     D_ASSUME( !(x & DFB_PIXELFORMAT_ALIGNMENT(gfxs->dst_format)) );

     gfxs->Aop[0] += y * pitch + DFB_BYTES_PER_LINE( gfxs->dst_format, x );

     if (DFB_PLANAR_PIXELFORMAT(gfxs->dst_format)) {
          int dst_field_offset = gfxs->dst_field_offset;

          switch (gfxs->dst_format) {
               case DSPF_YV12:
               case DSPF_I420:
                    dst_field_offset /= 4;
                    pitch /= 2;
                    y /= 2;
                    x /= 2;
                    break;
               case DSPF_YV16:
                    dst_field_offset /= 2;
                    pitch /= 2;
                    x /= 2;
                    break;
               case DSPF_NV12:
               case DSPF_NV21:
                    dst_field_offset /= 2;
                    y /= 2;
               case DSPF_NV16:
                    x &= ~1;
                    break;
               case DSPF_YUV444P: /* nothing to adjust */
               default:
                    break;
          }

          gfxs->Aop[1] = gfxs->dst_org[1];
          gfxs->Aop[2] = gfxs->dst_org[2];

          if (gfxs->dst_caps & DSCAPS_SEPARATED && gfxs->Aop_field) {
               gfxs->Aop[1] += dst_field_offset;
               gfxs->Aop[2] += dst_field_offset;
          }

          gfxs->Aop[1] += y * pitch + x;
          gfxs->Aop[2] += y * pitch + x;
     }
}
int
main( int argc, char *argv[] )
{
     DirectResult           ret;
     SH7722_JPEG_context    info;
     DFBSurfacePixelFormat  format;
     int                    pitch;
     DirectStream          *stream = NULL;

     if (argc != 2) {
          fprintf( stderr, "Usage: %s <filename>\n", argv[0] );
          return -1;
     }

#ifndef STANDALONE
     direct_initialize();

     direct_config->debug = true;
#endif

     ret = SH7722_JPEG_Initialize();
     if (ret)
          return ret;

     ret = direct_stream_create( argv[1], &stream );
     if (ret)
          goto out;

     ret = SH7722_JPEG_Open( stream, &info );
     if (ret)
          goto out;

     D_INFO( "SH7722/JPEGTool: Opened %dx%d image (4:%s)\n", info.width, info.height,
             info.mode420 ? "2:0" : info.mode444 ? "4:4" : "2:2?" );

     format = DSPF_RGB24;// info.mode444 ? DSPF_NV16 : DSPF_NV12;
     pitch  = (DFB_BYTES_PER_LINE( format, info.width ) + 31) & ~31;

     ret = SH7722_JPEG_Decode( &info, NULL, NULL, format, 0x0f800000, NULL, pitch, info.width, info.height );
     if (ret)
          goto out;


//  Use RGB24 format for this
//     write_ppm( "test.ppm", 0x0f800000, pitch, info.width, info.height );

     ret = SH7722_JPEG_Encode( "test.jpg", NULL, format, 0x0f800000, pitch, info.width, info.height, 0 );
     if (ret)
          goto out;


out:
     if (stream)
          direct_stream_destroy( stream );

     SH7722_JPEG_Shutdown();

     return ret;
}
Exemple #4
0
/*
 * Render a filled rectangle using the current hardware state.
 */
bool
vmwareBlit( void *drv, void *dev, DFBRectangle *srect, int dx, int dy )
{
     VMWareDeviceData *vdev = (VMWareDeviceData*) dev;
     void             *dst  = vdev->dst_addr + dy * vdev->dst_pitch +
                              DFB_BYTES_PER_LINE(vdev->dst_format, dx);
     void             *src  = vdev->src_addr + srect->y * vdev->src_pitch +
                              DFB_BYTES_PER_LINE(vdev->src_format, srect->x);

     D_DEBUG_AT( VMWare_2D, "%s( %d,%d-%dx%d -> %d, %d )\n", __FUNCTION__,
                 DFB_RECTANGLE_VALS( srect ), dx, dy );

     while (srect->h--) {
          direct_memcpy( dst, src, srect->w * vdev->dst_bpp );

          dst += vdev->dst_pitch;
          src += vdev->src_pitch;
     }

     return true;
}
Exemple #5
0
/*
 * Render a filled rectangle using the current hardware state.
 */
bool
vmwareFillRectangle( void *drv, void *dev, DFBRectangle *rect )
{
     VMWareDeviceData *vdev = (VMWareDeviceData*) dev;
     void             *addr = vdev->dst_addr + rect->y * vdev->dst_pitch +
                              DFB_BYTES_PER_LINE(vdev->dst_format, rect->x);

     D_DEBUG_AT( VMWare_2D, "%s( %d,%d-%dx%d )\n", __FUNCTION__, DFB_RECTANGLE_VALS( rect ) );

     switch (vdev->dst_bpp) {
          case 4:
               while (rect->h--) {
                    int  w   = rect->w;
                    u32 *dst = addr;

                    while (w--)
                         *dst++ = vdev->color_pixel;

                    addr += vdev->dst_pitch;
               }
               break;

          case 2:
               while (rect->h--) {
                    int  w   = rect->w;
                    u16 *dst = addr;

                    while (w--)
                         *dst++ = vdev->color_pixel;

                    addr += vdev->dst_pitch;
               }
               break;

          case 1:
               while (rect->h--) {
                    int  w   = rect->w;
                    u8  *dst = addr;

                    while (w--)
                         *dst++ = vdev->color_pixel;

                    addr += vdev->dst_pitch;
               }
               break;
     }

     return true;
}
static DFBResult
preallocAllocateBuffer( CoreSurfacePool       *pool,
                        void                  *pool_data,
                        void                  *pool_local,
                        CoreSurfaceBuffer     *buffer,
                        CoreSurfaceAllocation *allocation,
                        void                  *alloc_data )
{
     int                     index;
     CoreSurface            *surface;
     PreallocAllocationData *alloc = alloc_data;

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

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

     for (index=0; index<MAX_SURFACE_BUFFERS; index++) {
          if (surface->buffers[index] == buffer)
               break;
     }

     if (index == MAX_SURFACE_BUFFERS)
          return DFB_BUG;

     if (!(surface->config.flags & CSCONF_PREALLOCATED))
          return DFB_BUG;

     if (!surface->config.preallocated[index].addr ||
          surface->config.preallocated[index].pitch < DFB_BYTES_PER_LINE(surface->config.format,
                                                                         surface->config.size.w))
          return DFB_INVARG;

     alloc->addr  = surface->config.preallocated[index].addr;
     alloc->pitch = surface->config.preallocated[index].pitch;

     allocation->flags = CSALF_PREALLOCATED | CSALF_VOLATILE;
     allocation->size  = surface->config.preallocated[index].pitch *
                         DFB_PLANE_MULTIPLY( surface->config.format, surface->config.size.h );

     return DFB_OK;
}
DFBResult dfb_surfacemanager_allocate( SurfaceManager *manager,
                                       SurfaceBuffer  *buffer )
{
     int pitch;
     int length;
     Chunk *c;

     Chunk *best_free = NULL;
     Chunk *best_occupied = NULL;

     CoreSurface *surface = buffer->surface;

     D_MAGIC_ASSERT( manager, SurfaceManager );

     if (!manager->length || manager->suspended)
          return DFB_NOVIDEOMEMORY;

     /* calculate the required length depending on limitations */
     pitch = MAX( surface->width, surface->min_width );

     if (pitch < manager->max_power_of_two_pixelpitch &&
         surface->height < manager->max_power_of_two_height)
          pitch = 1 << direct_log2( pitch );

     if (manager->pixelpitch_align > 1) {
          pitch += manager->pixelpitch_align - 1;
          pitch -= pitch % manager->pixelpitch_align;
     }

     pitch = DFB_BYTES_PER_LINE( buffer->format, pitch );

     if (pitch < manager->max_power_of_two_bytepitch &&
         surface->height < manager->max_power_of_two_height)
          pitch = 1 << direct_log2( pitch );

     if (manager->bytepitch_align > 1) {
          pitch += manager->bytepitch_align - 1;
          pitch -= pitch % manager->bytepitch_align;
     }

     length = DFB_PLANE_MULTIPLY( buffer->format,
                                  MAX( surface->height, surface->min_height ) * pitch );

     if (manager->byteoffset_align > 1) {
          length += manager->byteoffset_align - 1;
          length -= length % manager->byteoffset_align;
     }

     /* Do a pre check before iterating through all chunks. */
     if (length > manager->available - manager->heap_offset)
          return DFB_NOVIDEOMEMORY;

     buffer->video.pitch = pitch;

     /* examine chunks */
     c = manager->chunks;
     while (c) {
          if (c->length >= length) {
               if (c->buffer) {
                    c->tolerations++;
                    if (c->tolerations > 0xff)
                         c->tolerations = 0xff;

                    if (!c->buffer->video.locked              &&
                        c->buffer->policy <= buffer->policy   &&
                        c->buffer->policy != CSP_VIDEOONLY    &&

                        ((buffer->policy > c->buffer->policy) ||
                         (c->tolerations > manager->min_toleration/8 + 2)))
                    {
                         /* found a nice place to chill */
                         if (!best_occupied  ||
                              best_occupied->length > c->length  ||
                              best_occupied->tolerations < c->tolerations)
                              /* first found or better one? */
                              best_occupied = c;
                    }
               }
               else {
                    /* found a nice place to chill */
                    if (!best_free  ||  best_free->length > c->length)
                         /* first found or better one? */
                         best_free = c;
               }
          }

          c = c->next;
     }

     /* if we found a place */
     if (best_free) {
          occupy_chunk( manager, best_free, buffer, length );

          return DFB_OK;
     }

     if (best_occupied) {
          CoreSurface *kicked = best_occupied->buffer->surface;

          D_DEBUG_AT( Core_SM, "Kicking out buffer at %d (%d) with tolerations %d...\n",
                      best_occupied->offset,
                      best_occupied->length, best_occupied->tolerations );

          dfb_surfacemanager_assure_system( manager, best_occupied->buffer );

          best_occupied->buffer->video.health = CSH_INVALID;
          dfb_surface_notify_listeners( kicked, CSNF_VIDEO );

          best_occupied = free_chunk( manager, best_occupied );

          dfb_gfxcard_sync();


          occupy_chunk( manager, best_occupied, buffer, length );

          return DFB_OK;
     }


     D_DEBUG_AT( Core_SM, "Couldn't allocate enough heap space for video memory surface!\n" );

     /* no luck */
     return DFB_NOVIDEOMEMORY;
}
static DFBResult
prealloc_transfer_readwrite( CoreSurface             *surface,
                             CoreSurfacePoolTransfer *transfer,
                             CoreSurfaceAllocation   *alloc,
                             CoreSurfaceAccessFlags   flags,
                             CoreSlave               *slave )
{
     DFBResult ret = DFB_OK;
     int       index;
     int       i, y;

     D_MAGIC_ASSERT( surface, CoreSurface );
     D_ASSERT( transfer != NULL );
     CORE_SURFACE_ALLOCATION_ASSERT( alloc );

     index = dfb_surface_buffer_index( alloc->buffer );

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

     D_DEBUG_AT( PreAlloc_Bridge, "  ->Transfer read/write %s Fusion ID %lu (index %d)\n",
                 (flags & CSAF_WRITE) ? "from" : "to", surface->object.identity, index );


     for (i=0; i<transfer->num_rects; i++) {
          const DFBRectangle *rect   = &transfer->rects[i];
          int                 offset = DFB_BYTES_PER_LINE( surface->config.format, rect->x );
          int                 length = DFB_BYTES_PER_LINE( surface->config.format, rect->w );
          u8                 *temp   = alloca( length );    // FIXME

          for (y=0; y<rect->h; y++) {
               DFBRectangle lrect = { rect->x, rect->y + y, rect->w, 1 };

               if (flags & CSAF_WRITE) {
                    ret = CoreSlave_GetData( slave,
                                             surface->config.preallocated[index].addr +
                                             (rect->y + y) * surface->config.preallocated[index].pitch + offset,
                                             length,
                                             temp );
                    if (ret)
                         break;

                    ret = dfb_surface_pool_write( alloc->pool, alloc, temp, length, &lrect );
               }
               else {
                    ret = dfb_surface_pool_read( alloc->pool, alloc, temp, length, &lrect );
                    if (ret)
                         break;

                    ret = CoreSlave_PutData( slave,
                                             surface->config.preallocated[index].addr +
                                             (rect->y + y) * surface->config.preallocated[index].pitch + offset,
                                             length,
                                             temp );
               }
               if (ret)
                    break;
          }
          if (ret)
               break;
     }


     return ret;
}
static DFBResult
prealloc_transfer_locked( CoreSurface             *surface,
                          CoreSurfacePoolTransfer *transfer,
                          CoreSurfaceAllocation   *locked,
                          CoreSurfaceAccessFlags   flags,
                          CoreSlave               *slave )
{
     DFBResult             ret;
     CoreSurfaceBufferLock lock;
     int                   index;
     int                   i, y;

     D_MAGIC_ASSERT( surface, CoreSurface );
     D_ASSERT( transfer != NULL );
     CORE_SURFACE_ALLOCATION_ASSERT( locked );

     index = dfb_surface_buffer_index( locked->buffer );

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

     D_DEBUG_AT( PreAlloc_Bridge, "  -> Transfer locked %s Fusion ID %lu (index %d)\n",
                 (flags & CSAF_WRITE) ? "from" : "to", surface->object.identity, index );


     dfb_surface_buffer_lock_init( &lock, CSAID_CPU, flags );

     ret = dfb_surface_pool_lock( locked->pool, locked, &lock );
     if (ret) {
          dfb_surface_buffer_lock_deinit( &lock );
          return ret;
     }


     for (i=0; i<transfer->num_rects; i++) {
          const DFBRectangle *rect   = &transfer->rects[i];
          int                 offset = DFB_BYTES_PER_LINE( surface->config.format, rect->x );
          int                 length = DFB_BYTES_PER_LINE( surface->config.format, rect->w );

          for (y=0; y<rect->h; y++) {
               if (flags & CSAF_WRITE)
                    ret = CoreSlave_GetData( slave,
                                             surface->config.preallocated[index].addr +
                                             (rect->y + y) * surface->config.preallocated[index].pitch + offset,
                                             length,
                                             lock.addr + (rect->y + y) * lock.pitch + offset );
               else
                    ret = CoreSlave_PutData( slave,
                                             surface->config.preallocated[index].addr +
                                             (rect->y + y) * surface->config.preallocated[index].pitch + offset,
                                             length,
                                             lock.addr + (rect->y + y) * lock.pitch + offset );
               if (ret)
                    break;
          }
          if (ret)
               break;
     }


     dfb_surface_pool_unlock( locked->pool, locked, &lock );

     dfb_surface_buffer_lock_deinit( &lock );

     return ret;
}
Exemple #10
0
static DFBResult
driver_init_device( CoreGraphicsDevice *device,
                    GraphicsDeviceInfo *device_info,
                    void               *driver_data,
                    void               *device_data )
{
    SH7722DriverData *sdrv = driver_data;
    SH7722DeviceData *sdev = device_data;

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

    /* FIXME: Add a runtime option / config file. */
    sdev->lcd_format = DSPF_RGB16;

    /* Check format of LCD buffer. */
    switch (sdev->lcd_format) {
    case DSPF_RGB16:
    case DSPF_NV16:
        break;

    default:
        return DFB_UNSUPPORTED;
    }

    /*
     * Setup LCD buffer.
     */
    sdev->lcd_width  = SH7722_LCD_WIDTH;
    sdev->lcd_height = SH7722_LCD_HEIGHT;
    sdev->lcd_pitch  = (DFB_BYTES_PER_LINE( sdev->lcd_format, sdev->lcd_width ) + 0xf) & ~0xf;
    sdev->lcd_size   = DFB_PLANE_MULTIPLY( sdev->lcd_format, sdev->lcd_height ) * sdev->lcd_pitch;
    sdev->lcd_offset = dfb_gfxcard_reserve_memory( device, sdev->lcd_size );

    if (sdev->lcd_offset < 0) {
        D_ERROR( "SH7722/Driver: Allocating %d bytes for the LCD buffer failed!\n", sdev->lcd_size );
        return DFB_FAILURE;
    }

    sdev->lcd_phys = dfb_gfxcard_memory_physical( device, sdev->lcd_offset );

    /* Get virtual addresses for JPEG reload buffers in master here,
       slaves do it in driver_init_driver(). */
    sdrv->lcd_virt = dfb_gfxcard_memory_virtual( device, sdev->lcd_offset );

    D_INFO( "SH7722/LCD: Allocated %dx%d %s Buffer (%d bytes) at 0x%08lx (%p)\n",
            sdev->lcd_width, sdev->lcd_height, dfb_pixelformat_name(sdev->lcd_format),
            sdev->lcd_size, sdev->lcd_phys, sdrv->lcd_virt );

    D_ASSERT( ! (sdev->lcd_pitch & 0xf) );
    D_ASSERT( ! (sdev->lcd_phys & 0xf) );


    /*
     * Setup JPEG reload buffers.
     */
    sdev->jpeg_size   = SH7722GFX_JPEG_RELOAD_SIZE * 2 + SH7722GFX_JPEG_LINEBUFFER_SIZE * 2;
    sdev->jpeg_offset = dfb_gfxcard_reserve_memory( device, sdev->jpeg_size );

    if (sdev->jpeg_offset < 0) {
        D_ERROR( "SH7722/Driver: Allocating %d bytes for the JPEG reload and line buffers failed!\n", sdev->jpeg_size );
        return DFB_FAILURE;
    }

    sdev->jpeg_phys = dfb_gfxcard_memory_physical( device, sdev->jpeg_offset );
    sdev->jpeg_lb1  = sdev->jpeg_phys + SH7722GFX_JPEG_RELOAD_SIZE * 2;
    sdev->jpeg_lb2  = sdev->jpeg_lb1  + SH7722GFX_JPEG_LINEBUFFER_SIZE;

    /* Get virtual addresses for JPEG reload buffers in master here,
       slaves do it in driver_init_driver(). */
    sdrv->jpeg_virt = dfb_gfxcard_memory_virtual( device, sdev->jpeg_offset );

    D_INFO( "SH7722/JPEG: Allocated reload and line buffers (%d bytes) at 0x%08lx (%p)\n",
            sdev->jpeg_size, sdev->jpeg_phys, sdrv->jpeg_virt );

    D_ASSERT( ! (sdev->jpeg_size & 0xff) );
    D_ASSERT( ! (sdev->jpeg_phys & 0xf) );


    /* Fill in the device info. */
    snprintf( device_info->name,   DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH,   "SH7722" );
    snprintf( device_info->vendor, DFB_GRAPHICS_DEVICE_INFO_VENDOR_LENGTH, "Renesas" );

    /* Set device limitations. */
    device_info->limits.surface_byteoffset_alignment = 16;
    device_info->limits.surface_bytepitch_alignment  = 8;

    /* Set device capabilities. */
    device_info->caps.flags    = CCF_CLIPPING | CCF_RENDEROPTS;
    device_info->caps.accel    = SH7722_SUPPORTED_DRAWINGFUNCTIONS |
                                 SH7722_SUPPORTED_BLITTINGFUNCTIONS;
    device_info->caps.drawing  = SH7722_SUPPORTED_DRAWINGFLAGS;
    device_info->caps.blitting = SH7722_SUPPORTED_BLITTINGFLAGS;

    /* Change font format for acceleration. */
    if (!dfb_config->software_only) {
        dfb_config->font_format  = DSPF_ARGB;
        dfb_config->font_premult = false;
    }


    /*
     * Initialize hardware.
     */

    /* Reset the drawing engine. */
    sh7722EngineReset( sdrv, sdev );

    /* Wait for idle BEU. */
    while (SH7722_GETREG32( sdrv, BSTAR ) & 1);

    /* Disable all inputs. */
    SH7722_SETREG32( sdrv, BESTR, 0 );

    /* Disable all multi windows. */
    SH7722_SETREG32( sdrv, BMWCR0, SH7722_GETREG32( sdrv, BMWCR0 ) & ~0xf );

    /* Clear LCD buffer. */
    switch (sdev->lcd_format) {
    case DSPF_RGB16:
        memset( (void*) sdrv->lcd_virt, 0x00, sdev->lcd_height * sdev->lcd_pitch );
        break;

    case DSPF_NV16:
        memset( (void*) sdrv->lcd_virt, 0x10, sdev->lcd_height * sdev->lcd_pitch );
        memset( (void*) sdrv->lcd_virt + sdev->lcd_height * sdev->lcd_pitch, 0x80, sdev->lcd_height * sdev->lcd_pitch );
        break;

    default:
        D_BUG( "unsupported format" );
        return DFB_BUG;
    }

    /*
     * TODO: Make LCD Buffer format and primary BEU format runtime configurable.
     */

    /* Set output pixel format of the BEU. */
    switch (sdev->lcd_format) {
    case DSPF_RGB16:
        SH7722_SETREG32( sdrv, BPKFR, BPKFR_RY_RGB | WPCK_RGB16 );
        break;

    case DSPF_NV16:
        SH7722_SETREG32( sdrv, BPKFR, BPKFR_RY_RGB | BPKFR_TE_ENABLED | CHDS_YCBCR422 );
        SH7722_SETREG32( sdrv, BDACR, sdev->lcd_phys + sdev->lcd_height * sdev->lcd_pitch );
        break;

    default:
        D_BUG( "unsupported format" );
        return DFB_BUG;
    }

    SH7722_SETREG32( sdrv, BPROCR, 0x00000000 );

    /* Have BEU render into LCD buffer. */
    SH7722_SETREG32( sdrv, BBLCR1, MT_MEMORY );
    SH7722_SETREG32( sdrv, BDAYR, sdev->lcd_phys & 0xfffffffc );
    SH7722_SETREG32( sdrv, BDMWR, sdev->lcd_pitch & 0x0003fffc );

    /* Setup LCD controller to show the buffer. */
    sh7722_lcd_setup( sdrv, sdev->lcd_width, sdev->lcd_height,
                      sdev->lcd_phys, sdev->lcd_pitch, sdev->lcd_format, false );

    /* Initialize BEU lock. */
    fusion_skirmish_init( &sdev->beu_lock, "BEU", dfb_core_world(sdrv->core) );

    /* Initialize JPEG lock. */
    fusion_skirmish_init( &sdev->jpeg_lock, "JPEG", dfb_core_world(sdrv->core) );

    return DFB_OK;
}
static bool
stretch_hvx_planar( CardState *state, DFBRectangle *srect, DFBRectangle *drect, bool down )
{
     GenefxState *gfxs;
     void        *dst;
     void        *src;
     DFBRegion    clip;

     D_ASSERT( state != NULL );
     DFB_RECTANGLE_ASSERT( srect );
     DFB_RECTANGLE_ASSERT( drect );

     gfxs = state->gfxs;

     if (state->blittingflags)
          return false;

     if (gfxs->dst_format != gfxs->src_format)
          return false;

     clip = state->clip;

     if (!dfb_region_rectangle_intersect( &clip, drect ))
          return false;

     dfb_region_translate( &clip, - drect->x, - drect->y );

     dst = gfxs->dst_org[0] + drect->y * gfxs->dst_pitch + DFB_BYTES_PER_LINE( gfxs->dst_format, drect->x );
     src = gfxs->src_org[0] + srect->y * gfxs->src_pitch + DFB_BYTES_PER_LINE( gfxs->src_format, srect->x );

     switch (gfxs->dst_format) {
          case DSPF_NV12:
          case DSPF_NV21:
               if (down)
                    stretch_hvx_8_down( dst, gfxs->dst_pitch, src, gfxs->src_pitch,
                                        srect->w, srect->h, drect->w, drect->h, &clip );
               else
                    stretch_hvx_8_up( dst, gfxs->dst_pitch, src, gfxs->src_pitch,
                                      srect->w, srect->h, drect->w, drect->h, &clip );

               clip.x1 /= 2;
               clip.x2 /= 2;
               clip.y1 /= 2;
               clip.y2 /= 2;

               dst = gfxs->dst_org[1] + drect->y/2 * gfxs->dst_pitch + DFB_BYTES_PER_LINE( gfxs->dst_format, drect->x );
               src = gfxs->src_org[1] + srect->y/2 * gfxs->src_pitch + DFB_BYTES_PER_LINE( gfxs->src_format, srect->x );

               if (down)
                    stretch_hvx_88_down( dst, gfxs->dst_pitch, src, gfxs->src_pitch,
                                         srect->w/2, srect->h, drect->w/2, drect->h, &clip );
               else
                    stretch_hvx_88_up( dst, gfxs->dst_pitch, src, gfxs->src_pitch,
                                       srect->w/2, srect->h, drect->w/2, drect->h, &clip );
               break;

          default:
               break;
     }

     return true;
}
Exemple #12
0
static int
do_face( const Face *face )
{
     int              i, ret;
     int              align        = DFB_PIXELFORMAT_ALIGNMENT( m_format );
     int              num_glyphs   = 0;
     int              num_rows     = 1;
     int              row_index    = 0;
     int              row_offset   = 0;
     int              next_face    = sizeof(DGIFFFaceHeader);
     int              total_height = 0;

     Entity::vector   glyph_vector;
     unsigned int     glyph_count = 0;

     DGIFFFaceHeader  header;
     DGIFFGlyphInfo  *glyphs;
     DGIFFGlyphRow   *rows;
     void           **row_data;

     DFBSurfaceDescription *descs;

     D_DEBUG_AT( mkdgiff, "%s( %p )\n", __FUNCTION__, face );

     get_entities( face->buf, face->length, glyph_vector );

     glyph_count = glyph_vector.size();


     /* Clear to not leak any data into file. */
     memset( &header, 0, sizeof(header) );


     /* Allocate glyph info array. */
     glyphs   = (DGIFFGlyphInfo*)        D_CALLOC( glyph_count, sizeof(DGIFFGlyphInfo) );
     rows     = (DGIFFGlyphRow*)         D_CALLOC( glyph_count, sizeof(DGIFFGlyphRow) );            /* WORST case :) */
     row_data = (void**)                 D_CALLOC( glyph_count, sizeof(void*) );                    /* WORST case :) */
     descs    = (DFBSurfaceDescription*) D_CALLOC( glyph_count, sizeof(DFBSurfaceDescription) );    /* WORST case :) */

     for (Entity::vector::const_iterator iter = glyph_vector.begin(); iter != glyph_vector.end(); iter++) {
          const Glyph *glyph = dynamic_cast<const Glyph*>( *iter );

          glyph->Dump();


          DGIFFGlyphInfo *info = &glyphs[num_glyphs];
          DGIFFGlyphRow  *row  = &rows[num_rows - 1];

          D_DEBUG_AT( mkdgiff, "  -> code %3u\n", glyph->unicode );

          ret = load_image( glyph->file.c_str(), &descs[num_glyphs] );
          if (ret)
               continue;

          info->unicode = glyph->unicode;

          info->width   = descs[num_glyphs].width;
          info->height  = descs[num_glyphs].height;

          info->left    = glyph->left;
          info->top     = glyph->top;
          info->advance = glyph->advance;

          num_glyphs++;

          if (row->width > 0 && row->width + info->width > MAX_ROW_WIDTH) {
               num_rows++;
               row++;
          }

          row->width += (info->width + align) & ~align;

          if (row->height < info->height)
               row->height = info->height;
     }

     for (i=0; i<num_rows; i++) {
          DGIFFGlyphRow *row = &rows[i];

          D_DEBUG_AT( mkdgiff, "  ->   row %d, width %d, height %d\n", i, row->width, row->height );

          total_height += row->height;

          row->pitch = (DFB_BYTES_PER_LINE( m_format, row->width ) + 7) & ~7;

          row_data[i] = D_CALLOC( row->height, row->pitch );

          next_face += row->height * row->pitch;
     }

     D_DEBUG_AT( mkdgiff, "  -> %d glyphs, %d rows, total height %d\n", num_glyphs, num_rows, total_height );

     next_face += num_glyphs * sizeof(DGIFFGlyphInfo);
     next_face += num_rows * sizeof(DGIFFGlyphRow);

     for (i=0; i<num_glyphs; i++) {
          DGIFFGlyphInfo *glyph = &glyphs[i];

          D_DEBUG_AT( mkdgiff, "  -> writing character 0x%x (%d)\n", glyph->unicode, i );

          if (row_offset > 0 && row_offset + glyph->width > MAX_ROW_WIDTH) {
               row_index++;
               row_offset = 0;
          }


          D_DEBUG_AT( mkdgiff, "  -> row offset %d\n", row_offset );

          write_glyph( glyph, descs[i],
                       (char*) row_data[row_index] + DFB_BYTES_PER_LINE( m_format, row_offset ),
                       rows[row_index].pitch );

          glyph->row    = row_index;
          glyph->offset = row_offset;

          row_offset += (glyph->width + align) & ~align;
     }

     D_ASSERT( row_index == num_rows - 1 );

     header.next_face   = next_face;
     header.size        = face->size;

     header.ascender    = face->ascender;
     header.descender   = face->descender;
     header.height      = face->height;

     header.max_advance = face->maxadvance;

     header.pixelformat = m_format;

     header.num_glyphs  = num_glyphs;
     header.num_rows    = num_rows;

     header.blittingflags = face->blittingflags;

     D_DEBUG_AT( mkdgiff, "  -> ascender %d, descender %d\n", header.ascender, header.descender );
     D_DEBUG_AT( mkdgiff, "  -> height %d, max advance %d\n", header.height, header.max_advance );

     fwrite( &header, sizeof(header), 1, stdout );

     fwrite( glyphs, sizeof(*glyphs), num_glyphs, stdout );

     for (i=0; i<num_rows; i++) {
          DGIFFGlyphRow *row = &rows[i];

          fwrite( row, sizeof(*row), 1, stdout );

          fwrite( row_data[i], row->pitch, row->height, stdout );
     }

     for (i=0; i<num_rows; i++) {
          if (row_data[i])
               D_FREE( row_data[i] );
     }

     D_FREE( row_data );
     D_FREE( rows );
     D_FREE( glyphs );

     return 0;
}
Exemple #13
0
static DFBResult
update_screen( DFBX11 *x11, const DFBRectangle *clip, CoreSurfaceBufferLock *lock, XWindow *xw )
{
     void                  *dst;
     void                  *src;
     unsigned int           offset = 0;
     XImage                *ximage;
     CoreSurface           *surface;
     CoreSurfaceAllocation *allocation;
     DFBX11Shared          *shared;
     DFBRectangle           rect;
     bool                   direct = false;

     D_ASSERT( x11 != NULL );
     DFB_RECTANGLE_ASSERT( clip );

     D_DEBUG_AT( X11_Update, "%s( %4d,%4d-%4dx%4d )\n", __FUNCTION__, DFB_RECTANGLE_VALS( clip ) );

     CORE_SURFACE_BUFFER_LOCK_ASSERT( lock );

     shared = x11->shared;
     D_ASSERT( shared != NULL );

     XLockDisplay( x11->display );

     if (!xw) {
          XUnlockDisplay( x11->display );
          return DFB_OK;
     }

     allocation = lock->allocation;
     CORE_SURFACE_ALLOCATION_ASSERT( allocation );

     surface = allocation->surface;
     D_ASSERT( surface != NULL );


     rect.x = rect.y = 0;
     rect.w = xw->width;
     rect.h = xw->height;

     if (!dfb_rectangle_intersect( &rect, clip )) {
          XUnlockDisplay( x11->display );
          return DFB_OK;
     }

     D_DEBUG_AT( X11_Update, "  -> %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS( &rect ) );

#ifdef USE_GLX
     /* Check for GLX allocation... */
     if (allocation->pool == shared->glx_pool && lock->handle) {
          LocalPixmap *pixmap = lock->handle;

          D_MAGIC_ASSERT( pixmap, LocalPixmap );

          /* ...and just call SwapBuffers... */
          //D_DEBUG_AT( X11_Update, "  -> Calling glXSwapBuffers( 0x%lx )...\n", alloc->drawable );
          //glXSwapBuffers( x11->display, alloc->drawable );


          D_DEBUG_AT( X11_Update, "  -> Copying from GLXPixmap...\n" );

          glXWaitGL();

          XCopyArea( x11->display, pixmap->pixmap, xw->window, xw->gc,
                     rect.x, rect.y, rect.w, rect.h, rect.x, rect.y );

          glXWaitX();

          XUnlockDisplay( x11->display );

          return DFB_OK;
     }
#endif

     /* Check for our special native allocation... */
     if (allocation->pool == shared->x11image_pool && lock->handle) {
          x11Image *image = lock->handle;

          D_MAGIC_ASSERT( image, x11Image );

          /* ...and directly XShmPutImage from that. */
          ximage = image->ximage;

          direct = true;
     }
     else {
          /* ...or copy or convert into XShmImage or XImage allocated with the XWindow. */
          ximage = xw->ximage;
          offset = xw->ximage_offset;

          xw->ximage_offset = (offset ? 0 : ximage->height / 2);

          /* make sure the 16-bit input formats are properly 2-pixel-clipped */
          switch (surface->config.format) {
               case DSPF_I420:
               case DSPF_YV12:
               case DSPF_NV12:
               case DSPF_NV21:
                    if (rect.y & 1) {
                         rect.y--;
                         rect.h++;
                    }
                    /* fall through */
               case DSPF_YUY2:
               case DSPF_UYVY:
               case DSPF_NV16:
                    if (rect.x & 1) {
                         rect.x--;
                         rect.w++;
                    }
               default: /* no action */
                    break;
          }

          dst = xw->virtualscreen + rect.x * xw->bpp + (rect.y + offset) * ximage->bytes_per_line;
          src = lock->addr + DFB_BYTES_PER_LINE( surface->config.format, rect.x ) + rect.y * lock->pitch;

          switch (xw->depth) {
               case 32:
                    dfb_convert_to_argb( surface->config.format, src, lock->pitch,
                                         surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h );
                    break;

               case 24:
                    dfb_convert_to_rgb32( surface->config.format, src, lock->pitch,
                                          surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h );
                    break;

               case 16:
                    if (surface->config.format == DSPF_LUT8) {
                         int width = rect.w; int height = rect.h;
                         const u8    *src8    = src;
                         u16         *dst16   = dst;
                         CorePalette *palette = surface->palette;
                         int          x;
                         while (height--) {

                              for (x=0; x<width; x++) {
                                   DFBColor color = palette->entries[src8[x]];
                                   dst16[x] = PIXEL_RGB16( color.r, color.g, color.b );
                              }

                              src8  += lock->pitch;
                              dst16 += ximage->bytes_per_line / 2;
                         }
                    }
                    else {
                    dfb_convert_to_rgb16( surface->config.format, src, lock->pitch,
                                          surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h );
                    }
                    break;

               case 15:
                    dfb_convert_to_rgb555( surface->config.format, src, lock->pitch,
                                           surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h );
                    break;

               default:
                    D_ONCE( "unsupported depth %d", xw->depth );
          }
     }

     D_ASSERT( ximage != NULL );


     /* Wait for previous data to be processed... */
     XSync( x11->display, False );

     /* ...and immediately queue or send the next! */
     if (x11->use_shm) {
          /* Just queue the command, it's XShm :) */
          XShmPutImage( xw->display, xw->window, xw->gc, ximage,
                        rect.x, rect.y + offset, rect.x, rect.y, rect.w, rect.h, False );

          /* Make sure the queue has really happened! */
          XFlush( x11->display );
     }
     else
          /* Initiate transfer of buffer... */
          XPutImage( xw->display, xw->window, xw->gc, ximage,
                     rect.x, rect.y + offset, rect.x, rect.y, rect.w, rect.h );

     /* Wait for display if single buffered and not converted... */
     if (direct && !(surface->config.caps & DSCAPS_FLIPPING))
          XSync( x11->display, False );

     XUnlockDisplay( x11->display );

     return DFB_OK;
}
Exemple #14
0
static DFBResult
driver_init_device( CoreGraphicsDevice *device,
                    GraphicsDeviceInfo *device_info,
                    void               *driver_data,
                    void               *device_data )
{
     SH7722DriverData *sdrv = driver_data;
     SH7722DeviceData *sdev = device_data;

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

     /* FIXME: Add a runtime option / config file. */
     sdev->lcd_format = DSPF_RGB16;

     /* Check format of LCD buffer. */
     switch (sdev->lcd_format) {
          case DSPF_RGB16:
          case DSPF_NV16:
               break;

          default:
               return DFB_UNSUPPORTED;
     }

     if (sdev->sh772x == 7723)
          memset( dfb_gfxcard_memory_virtual(device,0), 0, dfb_gfxcard_memory_length() );

     /*
      * Setup LCD buffer.
      */
#ifdef SH772X_FBDEV_SUPPORT
     { 
     	  struct fb_fix_screeninfo fsi;
     	  struct fb_var_screeninfo vsi;
		  int fbdev;

		  if ((fbdev = open("/dev/fb", O_RDONLY)) < 0) {
			   D_ERROR( "SH7722/Driver: Can't open fbdev to get LCDC info!\n" );
			   return DFB_FAILURE;
		  }

		  if (ioctl(fbdev, FBIOGET_FSCREENINFO, &fsi) < 0) {
			   D_ERROR( "SH7722/Driver: FBIOGET_FSCREEINFO failed.\n" );
			   close(fbdev);
			   return DFB_FAILURE;
		  }

		  if (ioctl(fbdev, FBIOGET_VSCREENINFO, &vsi) < 0) {
			   D_ERROR( "SH7722/Driver: FBIOGET_VSCREEINFO failed.\n" );
			   close(fbdev);
			   return DFB_FAILURE;
		  }

		  sdev->lcd_width  = vsi.xres;
		  sdev->lcd_height = vsi.yres;
		  sdev->lcd_pitch  = fsi.line_length;
		  sdev->lcd_size   = fsi.smem_len;
		  sdev->lcd_offset = 0;
		  sdev->lcd_phys   = fsi.smem_start;
#if 0
		  sdrv->lcd_virt   = mmap(NULL, fsi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED,
				  				  fbdev, 0);
		  if (sdrv->lcd_virt == MAP_FAILED) {
			   D_PERROR( "SH7722/Driver: mapping fbdev failed.\n" );
			   close(fbdev);
			   return DFB_FAILURE;
		  }

          /* Clear LCD buffer. */
          switch (sdev->lcd_format) {
               case DSPF_RGB16:
                    memset( (void*) sdrv->lcd_virt, 0x00, sdev->lcd_height * sdev->lcd_pitch );
                    break;

               case DSPF_NV16:
                    memset( (void*) sdrv->lcd_virt, 0x10, sdev->lcd_height * sdev->lcd_pitch );
                    memset( (void*) sdrv->lcd_virt + sdev->lcd_height * sdev->lcd_pitch, 0x80, sdev->lcd_height * sdev->lcd_pitch );
                    break;

               default:
                    D_BUG( "unsupported format" );
                    return DFB_BUG;
          }
#endif

		  close(fbdev);
     }     
#else
     sdev->lcd_width  = SH7722_LCD_WIDTH;
     sdev->lcd_height = SH7722_LCD_HEIGHT;
     sdev->lcd_pitch  = (DFB_BYTES_PER_LINE( sdev->lcd_format, sdev->lcd_width ) + 0xf) & ~0xf;
     sdev->lcd_size   = DFB_PLANE_MULTIPLY( sdev->lcd_format, sdev->lcd_height ) * sdev->lcd_pitch;
     sdev->lcd_offset = dfb_gfxcard_reserve_memory( device, sdev->lcd_size );

     if (sdev->lcd_offset < 0) {
          D_ERROR( "SH7722/Driver: Allocating %d bytes for the LCD buffer failed!\n", sdev->lcd_size );
          return DFB_FAILURE;
     }

     sdev->lcd_phys = dfb_gfxcard_memory_physical( device, sdev->lcd_offset );

     /* Get virtual addresses for LCD buffer in master here,
        slaves do it in driver_init_driver(). */
     sdrv->lcd_virt = dfb_gfxcard_memory_virtual( device, sdev->lcd_offset );
#endif

     D_INFO( "SH7722/LCD: Allocated %dx%d %s Buffer (%d bytes) at 0x%08lx (%p)\n",
             sdev->lcd_width, sdev->lcd_height, dfb_pixelformat_name(sdev->lcd_format),
             sdev->lcd_size, sdev->lcd_phys, sdrv->lcd_virt );

     D_ASSERT( ! (sdev->lcd_pitch & 0xf) );
     D_ASSERT( ! (sdev->lcd_phys & 0xf) );

     /*
      * Initialize hardware.
      */

     switch (sdev->sh772x) {
          case 7722:
               /* Reset the drawing engine. */
               sh7722EngineReset( sdrv, sdev );

               /* Fill in the device info. */
               snprintf( device_info->name,   DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH,   "SH7722" );
               snprintf( device_info->vendor, DFB_GRAPHICS_DEVICE_INFO_VENDOR_LENGTH, "Renesas" );

               /* Set device limitations. */
               device_info->limits.surface_byteoffset_alignment = 16;
               device_info->limits.surface_bytepitch_alignment  = 8;

               /* Set device capabilities. */
               device_info->caps.flags    = CCF_CLIPPING | CCF_RENDEROPTS;
               device_info->caps.accel    = SH7722_SUPPORTED_DRAWINGFUNCTIONS |
                                            SH7722_SUPPORTED_BLITTINGFUNCTIONS;
               device_info->caps.drawing  = SH7722_SUPPORTED_DRAWINGFLAGS;
               device_info->caps.blitting = SH7722_SUPPORTED_BLITTINGFLAGS;

               /* Change font format for acceleration. */
               if (!dfb_config->software_only) {
                    dfb_config->font_format  = DSPF_ARGB;
                    dfb_config->font_premult = false;
               }
               break;

          case 7723:
               /* Reset the drawing engine. */
               sh7723EngineReset( sdrv, sdev );

               /* Fill in the device info. */
               snprintf( device_info->name,   DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH,   "SH7723" );
               snprintf( device_info->vendor, DFB_GRAPHICS_DEVICE_INFO_VENDOR_LENGTH, "Renesas" );

               /* Set device limitations. */
               device_info->limits.surface_byteoffset_alignment = 512;
               device_info->limits.surface_bytepitch_alignment  = 64;

               /* Set device capabilities. */
               device_info->caps.flags    = CCF_CLIPPING | CCF_RENDEROPTS;
               device_info->caps.accel    = SH7723_SUPPORTED_DRAWINGFUNCTIONS | \
                                            SH7723_SUPPORTED_BLITTINGFUNCTIONS;
               device_info->caps.drawing  = SH7723_SUPPORTED_DRAWINGFLAGS;
               device_info->caps.blitting = SH7723_SUPPORTED_BLITTINGFLAGS;

               break;

          default:
               D_BUG( "unexpected device" );
               return DFB_BUG;
     }


     /* Wait for idle BEU. */
     while (SH7722_GETREG32( sdrv, BSTAR ) & 1);

     /* Disable all inputs. */
     SH7722_SETREG32( sdrv, BESTR, 0 );

     /* Disable all multi windows. */
     SH7722_SETREG32( sdrv, BMWCR0, SH7722_GETREG32( sdrv, BMWCR0 ) & ~0xf );

#ifndef SH772X_FBDEV_SUPPORT
     /* Clear LCD buffer. */
     switch (sdev->lcd_format) {
          case DSPF_RGB16:
               memset( (void*) sdrv->lcd_virt, 0x00, sdev->lcd_height * sdev->lcd_pitch );
               break;

          case DSPF_NV16:
               memset( (void*) sdrv->lcd_virt, 0x10, sdev->lcd_height * sdev->lcd_pitch );
               memset( (void*) sdrv->lcd_virt + sdev->lcd_height * sdev->lcd_pitch, 0x80, sdev->lcd_height * sdev->lcd_pitch );
               break;

          default:
               D_BUG( "unsupported format" );
               return DFB_BUG;
     }
#endif

     /*
      * TODO: Make LCD Buffer format and primary BEU format runtime configurable.
      */

     /* Set output pixel format of the BEU. */
     switch (sdev->lcd_format) {
          case DSPF_RGB16:
               SH7722_SETREG32( sdrv, BPKFR, BPKFR_RY_RGB | WPCK_RGB16 );
               break;

          case DSPF_NV16:
               SH7722_SETREG32( sdrv, BPKFR, BPKFR_RY_RGB | BPKFR_TE_ENABLED | CHDS_YCBCR422 );
               SH7722_SETREG32( sdrv, BDACR, sdev->lcd_phys + sdev->lcd_height * sdev->lcd_pitch );
               break;

          default:
               D_BUG( "unsupported format" );
               return DFB_BUG;
     }

     SH7722_SETREG32( sdrv, BPROCR, 0x00000000 );

     /* Have BEU render into LCD buffer. */
     SH7722_SETREG32( sdrv, BBLCR1, MT_MEMORY );
     SH7722_SETREG32( sdrv, BDAYR, sdev->lcd_phys & 0xfffffffc );
     SH7722_SETREG32( sdrv, BDMWR, sdev->lcd_pitch & 0x0003fffc );

#ifndef SH772X_FBDEV_SUPPORT
     /* Setup LCD controller to show the buffer. */
     sh7722_lcd_setup( sdrv, sdev->lcd_width, sdev->lcd_height,
                       sdev->lcd_phys, sdev->lcd_pitch, sdev->lcd_format, false );
#endif

     /* Initialize BEU lock. */
     fusion_skirmish_init( &sdev->beu_lock, "BEU", dfb_core_world(sdrv->core) );

     return DFB_OK;
}
Exemple #15
0
static DFBResult
update_screen( int x, int y, int w, int h )
{
#if 0
     int                    i, n;
     void                  *dst;
     void                  *src;
     DFBResult              ret;
     CoreSurface           *surface;
     CoreSurfaceBuffer     *buffer;
     CoreSurfaceBufferLock  lock;
     u16                   *src16, *dst16;
     u8                    *src8;
#endif

     D_DEBUG_AT( SDL_Updates, "%s( %d, %d, %d, %d )\n", __FUNCTION__, x, y, w, h );

     D_DEBUG_AT( SDL_Updates, "  -> locking sdl lock...\n" );

     fusion_skirmish_prevail( &dfb_sdl->lock );
#if 0
     surface = dfb_sdl->primary;
     D_MAGIC_ASSERT_IF( surface, CoreSurface );

     D_DEBUG_AT( SDL_Updates, "  -> primary is %p\n", surface );

     if (!surface) {
          D_DEBUG_AT( SDL_Updates, "  -> unlocking sdl lock...\n" );
          fusion_skirmish_dismiss( &dfb_sdl->lock );
          D_DEBUG_AT( SDL_Updates, "  -> done.\n" );
          return DFB_OK;
     }

     buffer = dfb_surface_get_buffer( surface, CSBR_FRONT );

     D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );

     D_DEBUG_AT( SDL_Updates, "  -> locking sdl surface...\n" );

     if (SDL_LockSurface( screen ) < 0) {
          D_ERROR( "DirectFB/SDL: "
                   "Couldn't lock the display surface: %s\n", SDL_GetError() );
          fusion_skirmish_dismiss( &dfb_sdl->lock );
          return DFB_FAILURE;
     }

     D_DEBUG_AT( SDL_Updates, "  -> locking dfb surface...\n" );

     ret = dfb_surface_buffer_lock( buffer, CSAF_CPU_READ, &lock );
     if (ret) {
          D_ERROR( "DirectFB/SDL: Couldn't lock layer surface: %s\n",
                   DirectFBErrorString( ret ) );
          SDL_UnlockSurface(screen);
          fusion_skirmish_dismiss( &dfb_sdl->lock );
          return ret;
     }

     src = lock.addr;
     dst = screen->pixels;

     src += DFB_BYTES_PER_LINE( surface->config.format, x ) + y * lock.pitch;
     dst += DFB_BYTES_PER_LINE( surface->config.format, x ) + y * screen->pitch;

     D_DEBUG_AT( SDL_Updates, "  -> copying pixels...\n" );

     switch (screen->format->BitsPerPixel) {
          case 16:
               dfb_convert_to_rgb16( surface->config.format,
                                     src, lock.pitch, surface->config.size.h,
                                     dst, screen->pitch, w, h );
               break;

          default:
               direct_memcpy( dst, src, DFB_BYTES_PER_LINE( surface->config.format, w ) );
     }

     D_DEBUG_AT( SDL_Updates, "  -> unlocking dfb surface...\n" );

     dfb_surface_buffer_unlock( &lock );

     D_DEBUG_AT( SDL_Updates, "  -> unlocking sdl surface...\n" );

     SDL_UnlockSurface( screen );
#endif
     D_DEBUG_AT( SDL_Updates, "  -> calling SDL_UpdateRect()...\n" );

     SDL_UpdateRect( dfb_sdl->screen, x, y, w, h );

     D_DEBUG_AT( SDL_Updates, "  -> unlocking sdl lock...\n" );

     fusion_skirmish_dismiss( &dfb_sdl->lock );

     D_DEBUG_AT( SDL_Updates, "  -> done.\n" );

     return DFB_OK;
}
DFBResult dfb_surfacemanager_assure_video( SurfaceManager *manager,
                                           SurfaceBuffer  *buffer )
{
     DFBResult    ret;
     CoreSurface *surface = buffer->surface;

     D_MAGIC_ASSERT( manager, SurfaceManager );

     if (manager->suspended)
          return DFB_NOVIDEOMEMORY;

     switch (buffer->video.health) {
          case CSH_STORED:
               if (buffer->video.chunk)
                    buffer->video.chunk->tolerations = 0;

               return DFB_OK;

          case CSH_INVALID:
               ret = dfb_surfacemanager_allocate( manager, buffer );
               if (ret)
                    return ret;

               /* FALL THROUGH, because after successful allocation
                  the surface health is CSH_RESTORE */

          case CSH_RESTORE:
               if (buffer->system.health != CSH_STORED)
                    D_BUG( "system/video instances both not stored!" );

               if (buffer->flags & SBF_WRITTEN) {
                    int   i;
                    char *src = buffer->system.addr;
                    char *dst = dfb_system_video_memory_virtual( buffer->video.offset );

                    for (i=0; i<surface->height; i++) {
                         direct_memcpy( dst, src,
                                        DFB_BYTES_PER_LINE(buffer->format, surface->width) );
                         src += buffer->system.pitch;
                         dst += buffer->video.pitch;
                    }

                    if (buffer->format == DSPF_YV12 || buffer->format == DSPF_I420) {
                         for (i=0; i<surface->height; i++) {
                              direct_memcpy( dst, src, DFB_BYTES_PER_LINE(buffer->format,
                                                                          surface->width / 2) );
                              src += buffer->system.pitch / 2;
                              dst += buffer->video.pitch  / 2;
                         }
                    }
                    else if (buffer->format == DSPF_NV12 || buffer->format == DSPF_NV21) {
                         for (i=0; i<surface->height/2; i++) {
                              direct_memcpy( dst, src, DFB_BYTES_PER_LINE(buffer->format,
                                                                          surface->width) );
                              src += buffer->system.pitch;
                              dst += buffer->video.pitch;
                         }
                    }
                    else if (buffer->format == DSPF_NV16) {
                         for (i=0; i<surface->height; i++) {
                              direct_memcpy( dst, src, DFB_BYTES_PER_LINE(buffer->format,
                                                                          surface->width) );
                              src += buffer->system.pitch;
                              dst += buffer->video.pitch;
                         }
                    }
               }

               buffer->video.health             = CSH_STORED;
               buffer->video.chunk->tolerations = 0;

               dfb_surface_notify_listeners( surface, CSNF_VIDEO );

               return DFB_OK;

          default:
               break;
     }

     D_BUG( "unknown video instance health" );
     return DFB_BUG;
}
DFBResult dfb_surfacemanager_assure_system( SurfaceManager *manager,
                                            SurfaceBuffer  *buffer )
{
     CoreSurface *surface = buffer->surface;

     D_MAGIC_ASSERT( manager, SurfaceManager );

     if (buffer->policy == CSP_VIDEOONLY) {
          D_BUG( "surface_manager_assure_system() called on video only surface" );
          return DFB_BUG;
     }

     if (buffer->system.health == CSH_STORED)
          return DFB_OK;
     else if (buffer->video.health == CSH_STORED) {
          int   i;
          char *src = dfb_system_video_memory_virtual( buffer->video.offset );
          char *dst = buffer->system.addr;

          /* from video_access_by_software() in surface.c */
          if (buffer->video.access & VAF_HARDWARE_WRITE) {
               dfb_gfxcard_sync();
               buffer->video.access &= ~VAF_HARDWARE_WRITE;
          }
          buffer->video.access |= VAF_SOFTWARE_READ;

          for (i=0; i<surface->height; i++) {
               direct_memcpy( dst, src, DFB_BYTES_PER_LINE(buffer->format, surface->width) );
               src += buffer->video.pitch;
               dst += buffer->system.pitch;
          }

          if (buffer->format == DSPF_YV12 || buffer->format == DSPF_I420) {
               for (i=0; i<surface->height; i++) {
                    direct_memcpy( dst, src, DFB_BYTES_PER_LINE(buffer->format,
                                                                surface->width / 2) );
                    src += buffer->video.pitch  / 2;
                    dst += buffer->system.pitch / 2;
               }
          }
          else if (buffer->format == DSPF_NV12 || buffer->format == DSPF_NV21) {
               for (i=0; i<surface->height/2; i++) {
                    direct_memcpy( dst, src, DFB_BYTES_PER_LINE(buffer->format,
                                                                surface->width) );
                    src += buffer->video.pitch;
                    dst += buffer->system.pitch;
               }
          }
          else if (buffer->format == DSPF_NV16) {
               for (i=0; i<surface->height; i++) {
                    direct_memcpy( dst, src, DFB_BYTES_PER_LINE(buffer->format,
                                                                surface->width) );
                    src += buffer->video.pitch;
                    dst += buffer->system.pitch;
               }
          }

          buffer->system.health = CSH_STORED;

          dfb_surface_notify_listeners( surface, CSNF_SYSTEM );

          return DFB_OK;
     }

     D_BUG( "no valid surface instance" );
     return DFB_BUG;
}
Exemple #18
0
DFBResult
dfb_surface_read_buffer( CoreSurface            *surface,
                         CoreSurfaceBufferRole   role,
                         void                   *destination,
                         int                     pitch,
                         const DFBRectangle     *prect )
{
     DFBResult              ret;
     int                    y;
     int                    bytes;
     DFBRectangle           rect;
     DFBSurfacePixelFormat  format;
     CoreSurfaceAllocation *allocation;

     D_MAGIC_ASSERT( surface, CoreSurface );
     D_ASSERT( destination != NULL );
     D_ASSERT( pitch > 0 );
     DFB_RECTANGLE_ASSERT_IF( prect );

     D_DEBUG_AT( Core_Surface, "%s( %p, %p [%d] )\n", __FUNCTION__, surface, destination, pitch );

     /* Determine area. */
     rect.x = 0;
     rect.y = 0;
     rect.w = surface->config.size.w;
     rect.h = surface->config.size.h;

     if (prect && (!dfb_rectangle_intersect( &rect, prect ) || !DFB_RECTANGLE_EQUAL( rect, *prect )))
          return DFB_INVAREA;

     /* Calculate bytes per read line. */
     format = surface->config.format;
     bytes  = DFB_BYTES_PER_LINE( format, rect.w );

     D_DEBUG_AT( Core_Surface, "  -> %d,%d - %dx%d (%s)\n", DFB_RECTANGLE_VALS(&rect),
                 dfb_pixelformat_name( format ) );

     ret = CoreSurface_PreLockBuffer2( surface, role, CSAID_CPU, CSAF_READ, false, &allocation );
     if (ret == DFB_NOALLOCATION) {
          for (y=0; y<rect.h; y++) {
               memset( destination, 0, bytes );

               destination += pitch;
          }

          return DFB_OK;
     }
     if (ret)
          return ret;

     D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );

     D_DEBUG_AT( Core_Surface, "  -> PreLockBuffer returned allocation %p (%s)\n", allocation, allocation->pool->desc.name );

     /* Try reading from allocation directly... */
     ret = dfb_surface_pool_read( allocation->pool, allocation, destination, pitch, &rect );
     if (ret) {
          /* ...otherwise use fallback method via locking if possible. */
          if (allocation->access[CSAID_CPU] & CSAF_READ) {
               CoreSurfaceBufferLock lock;

               /* Lock the allocation. */
               dfb_surface_buffer_lock_init( &lock, CSAID_CPU, CSAF_READ );

               ret = dfb_surface_pool_lock( allocation->pool, allocation, &lock );
               if (ret) {
                    D_DERROR( ret, "Core/SurfBuffer: Locking allocation failed! [%s]\n",
                              allocation->pool->desc.name );
                    dfb_surface_buffer_lock_deinit( &lock );
                    dfb_surface_allocation_unref( allocation );
                    return ret;
               }

               /* Move to start of read. */
               lock.addr += DFB_BYTES_PER_LINE( format, rect.x ) + rect.y * lock.pitch;

               /* Copy the data. */
               for (y=0; y<rect.h; y++) {
                    direct_memcpy( destination, lock.addr, bytes );

                    destination += pitch;
                    lock.addr   += lock.pitch;
               }

               /* Unlock the allocation. */
               ret = dfb_surface_pool_unlock( allocation->pool, allocation, &lock );
               if (ret)
                    D_DERROR( ret, "Core/SurfBuffer: Unlocking allocation failed! [%s]\n", allocation->pool->desc.name );

               dfb_surface_buffer_lock_deinit( &lock );
          }
     }

     dfb_surface_allocation_unref( allocation );

     return DFB_OK;
}
Exemple #19
0
DFBResult
dfb_surface_write_buffer( CoreSurface            *surface,
                          CoreSurfaceBufferRole   role,
                          const void             *source,
                          int                     pitch,
                          const DFBRectangle     *prect )
{
     DFBResult              ret;
     int                    bytes;
     DFBRectangle           rect;
     DFBSurfacePixelFormat  format;
     CoreSurfaceAllocation *allocation;

     D_MAGIC_ASSERT( surface, CoreSurface );
     D_ASSERT( pitch > 0 || source == NULL );
     DFB_RECTANGLE_ASSERT_IF( prect );

     D_DEBUG_AT( Core_Surface, "%s( %p, %p [%d] )\n", __FUNCTION__, surface, source, pitch );

     /* Determine area. */
     rect.x = 0;
     rect.y = 0;
     rect.w = surface->config.size.w;
     rect.h = surface->config.size.h;

     if (prect) {
          if (!dfb_rectangle_intersect( &rect, prect )) {
               D_DEBUG_AT( Core_Surface, "  -> no intersection!\n" );
               return DFB_INVAREA;
          }

          if (!DFB_RECTANGLE_EQUAL( rect, *prect )) {
               D_DEBUG_AT( Core_Surface, "  -> got clipped to %d,%d-%dx%d!\n", DFB_RECTANGLE_VALS(&rect) );
               return DFB_INVAREA;
          }
     }

     /* Calculate bytes per read line. */
     format = surface->config.format;
     bytes  = DFB_BYTES_PER_LINE( format, rect.w );

     D_DEBUG_AT( Core_Surface, "  -> %d,%d - %dx%d (%s)\n", DFB_RECTANGLE_VALS(&rect),
                 dfb_pixelformat_name( format ) );

     ret = CoreSurface_PreLockBuffer2( surface, role, CSAID_CPU, CSAF_WRITE, false, &allocation );
     if (ret)
          return ret;

     D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );

     D_DEBUG_AT( Core_Surface, "  -> PreLockBuffer returned allocation %p (%s)\n", allocation, allocation->pool->desc.name );

     /* Try writing to allocation directly... */
     ret = source ? dfb_surface_pool_write( allocation->pool, allocation, source, pitch, &rect ) : DFB_UNSUPPORTED;
     if (ret) {
          /* ...otherwise use fallback method via locking if possible. */
          if (allocation->access[CSAID_CPU] & CSAF_WRITE) {
               int                   y;
               int                   bytes;
               DFBSurfacePixelFormat format;
               CoreSurfaceBufferLock lock;

               /* Calculate bytes per written line. */
               format = surface->config.format;
               bytes  = DFB_BYTES_PER_LINE( format, rect.w );

               /* Lock the allocation. */
               dfb_surface_buffer_lock_init( &lock, CSAID_CPU, CSAF_WRITE );

               ret = dfb_surface_pool_lock( allocation->pool, allocation, &lock );
               if (ret) {
                    D_DERROR( ret, "Core/SurfBuffer: Locking allocation failed! [%s]\n",
                              allocation->pool->desc.name );
                    dfb_surface_buffer_lock_deinit( &lock );
                    dfb_surface_allocation_unref( allocation );
                    return ret;
               }

               /* Move to start of write. */
               lock.addr += DFB_BYTES_PER_LINE( format, rect.x ) + rect.y * lock.pitch;

               /* Copy the data. */
               for (y=0; y<rect.h; y++) {
                    if (source) {
                         direct_memcpy( lock.addr, source, bytes );

                         source += pitch;
                    }
                    else
                         memset( lock.addr, 0, bytes );

                    lock.addr += lock.pitch;
               }

               /* Unlock the allocation. */
               ret = dfb_surface_pool_unlock( allocation->pool, allocation, &lock );
               if (ret)
                    D_DERROR( ret, "Core/SurfBuffer: Unlocking allocation failed! [%s]\n", allocation->pool->desc.name );

               dfb_surface_buffer_lock_deinit( &lock );
          }
     }

     dfb_surface_allocation_unref( allocation );

     return DFB_OK;
}
Exemple #20
0
static DFBResult
load_image (const char            *filename,
            DFBSurfaceDescription *desc)
{
     DFBSurfacePixelFormat dest_format;
     DFBSurfacePixelFormat src_format;
     FILE          *fp;
     png_structp    png_ptr  = NULL;
     png_infop      info_ptr = NULL;
     png_uint_32    width, height;
     unsigned char *data     = NULL;
     int            type;
     char           header[8];
     int            bytes, pitch;

     dest_format = (desc->flags & DSDESC_PIXELFORMAT) ? desc->pixelformat : DSPF_UNKNOWN;

     desc->flags                = DSDESC_NONE;
     desc->preallocated[0].data = NULL;

     if (!(fp = fopen (filename, "rb"))) {
          fprintf (stderr, "Failed to open file '%s': %s.\n",
                   filename, strerror (errno));
          goto cleanup;
     }

     bytes = fread (header, 1, sizeof(header), fp);
     if (png_sig_cmp ((unsigned char*) header, 0, bytes)) {
          fprintf (stderr, "File '%s' doesn't seem to be a PNG image file.\n",
                   filename);
          goto cleanup;
     }

     png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING,
                                       NULL, NULL, NULL);
     if (!png_ptr)
          goto cleanup;

     if (setjmp (png_jmpbuf(png_ptr))) {
          if (desc->preallocated[0].data) {
               free (desc->preallocated[0].data);
               desc->preallocated[0].data = NULL;
          }

          /* data might have been clobbered,
             set it to NULL and leak instead of crashing */
          data = NULL;

          goto cleanup;
     }

     info_ptr = png_create_info_struct (png_ptr);
     if (!info_ptr)
          goto cleanup;

     png_init_io (png_ptr, fp);
     png_set_sig_bytes (png_ptr, bytes);

     png_read_info (png_ptr, info_ptr);

     png_get_IHDR (png_ptr, info_ptr,
                   &width, &height, &bytes, &type, NULL, NULL, NULL);

     if (bytes == 16)
          png_set_strip_16 (png_ptr);

#ifdef WORDS_BIGENDIAN
     png_set_swap_alpha (png_ptr);
#else
     png_set_bgr (png_ptr);
#endif

     src_format = (type & PNG_COLOR_MASK_ALPHA) ? DSPF_ARGB : DSPF_RGB32;
     switch (type) {
          case PNG_COLOR_TYPE_GRAY:
               if (dest_format == DSPF_A8) {
                    src_format = DSPF_A8;
                    break;
               }
               /* fallthru */
          case PNG_COLOR_TYPE_GRAY_ALPHA:
               png_set_gray_to_rgb (png_ptr);
//               if (rgbformat)
//                    dest_format = rgbformat;
               break;

          case PNG_COLOR_TYPE_PALETTE:
               png_set_palette_to_rgb (png_ptr);
               /* fallthru */
          case PNG_COLOR_TYPE_RGB:
//               if (rgbformat)
//                    dest_format = rgbformat;
          case PNG_COLOR_TYPE_RGB_ALPHA:
               if (dest_format == DSPF_RGB24) {
                    png_set_strip_alpha (png_ptr);
                    src_format = DSPF_RGB24;
               }
               break;
       }

     switch (src_format) {
          case DSPF_RGB32:
                png_set_filler (png_ptr, 0xFF,
#ifdef WORDS_BIGENDIAN
                                PNG_FILLER_BEFORE
#else
                                PNG_FILLER_AFTER
#endif
                                );
                break;
          case DSPF_ARGB:
          case DSPF_A8:
               if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
                    png_set_tRNS_to_alpha (png_ptr);
               break;
          default:
               break;
     }

     pitch = (DFB_BYTES_PER_LINE( src_format, width ) + 7) & ~7;

     data  = (unsigned char*) malloc (height * pitch);
     if (!data) {
          fprintf (stderr, "Failed to allocate %lu bytes.\n", (unsigned long)(height * pitch));
          goto cleanup;
     }

     {
          unsigned int i;
          png_bytep bptrs[height];

          for (i = 0; i < height; i++)
               bptrs[i] = data + i * pitch;

          png_read_image (png_ptr, bptrs);
     }

     if (!dest_format)
          dest_format = src_format;

     if (DFB_BYTES_PER_PIXEL(src_format) != DFB_BYTES_PER_PIXEL(dest_format)) {
          unsigned char *s, *d, *dest;
          int            d_pitch, h;

          D_ASSERT( DFB_BYTES_PER_PIXEL(src_format) == 4 );

          d_pitch = (DFB_BYTES_PER_LINE(dest_format, width) + 7) & ~7;

          dest = (unsigned char*) malloc (height * d_pitch);
          if (!dest) {
               fprintf (stderr, "Failed to allocate %lu bytes.\n", (unsigned long)(height * d_pitch));
               goto cleanup;
          }

          h = height;
          switch (dest_format) {
               case DSPF_RGB16:
                    for (s = data, d = dest; h; h--, s += pitch, d += d_pitch)
                         dfb_argb_to_rgb16 ((u32 *) s, (u16 *) d, width);
                    break;
               case DSPF_ARGB8565:
                    for (s = data, d = dest; h; h--, s += pitch, d += d_pitch)
                         dfb_argb_to_argb8565 ((u32 *) s, (u8 *) d, width);
                    break;
               case DSPF_ARGB1555:
                    for (s = data, d = dest; h; h--, s += pitch, d += d_pitch)
                         dfb_argb_to_argb1555 ((u32 *) s, (u16 *) d, width);
                    break;
               case DSPF_RGBA5551:
                    for (s = data, d = dest; h; h--, s += pitch, d += d_pitch)
                         dfb_argb_to_rgba5551 ((u32 *) s, (u16 *) d, width);
                    break;
               case DSPF_ARGB2554:
                    for (s = data, d = dest; h; h--, s += pitch, d += d_pitch)
                         dfb_argb_to_argb2554 ((u32 *) s, (u16 *) d, width);
                    break;
               case DSPF_ARGB4444:
                    for (s = data, d = dest; h; h--, s += pitch, d += d_pitch)
                         dfb_argb_to_argb4444 ((u32 *) s, (u16 *) d, width);
                    break;
               case DSPF_RGB332:
                    for (s = data, d = dest; h; h--, s += pitch, d += d_pitch)
                         dfb_argb_to_rgb332 ((u32 *) s, (u8 *) d, width);
                    break;
               case DSPF_A8:
                    for (s = data, d = dest; h; h--, s += pitch, d += d_pitch)
                         dfb_argb_to_a8 ((u32 *) s, (u8 *) d, width);
                    break;
               default:
                    fprintf (stderr,
                             "Sorry, unsupported format conversion.\n");
                    goto cleanup;
          }

          free (data);
          data = dest;
          pitch = d_pitch;
     }

     desc->flags = (DFBSurfaceDescriptionFlags)(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT |
                                                DSDESC_PREALLOCATED);
     desc->width       = width;
     desc->height      = height;
     desc->pixelformat = dest_format;
     desc->preallocated[0].pitch = pitch;
     desc->preallocated[0].data  = data;

     data = NULL;

 cleanup:
     if (fp)
          fclose (fp);

     if (png_ptr)
          png_destroy_read_struct (&png_ptr, &info_ptr, NULL);

     if (data)
          free (data);

     return ((desc->flags) ? DFB_OK : DFB_FAILURE);
}