Exemplo n.º 1
0
DirectResult
fusion_ref_init (FusionRef         *ref,
                 const char        *name,
                 const FusionWorld *world)
{
     D_ASSERT( ref != NULL );
     D_ASSERT( name != NULL );
     D_MAGIC_ASSERT( world, FusionWorld );

     D_DEBUG_AT( Fusion_Ref, "fusion_ref_init( %p, '%s' )\n", ref, name ? : "" );
     
     ref->multi.id = ++world->shared->ref_ids;
     
     ref->multi.builtin.local  = 0;
     ref->multi.builtin.global = 0;
     
     fusion_skirmish_init( &ref->multi.builtin.lock, name, world );
     
     ref->multi.builtin.call = NULL;

     /* Keep back pointer to shared world data. */
     ref->multi.shared  = world->shared;
     ref->multi.creator = fusion_id( world );

     return DR_OK;
}
Exemplo n.º 2
0
Arquivo: osx.c Projeto: ysei/uclinux-2
static DFBResult
system_initialize( CoreDFB *core, void **data )
{
     char       *driver;
     CoreScreen *screen;

     D_ASSERT( dfb_osx == NULL );

     dfb_osx = (DFBOSX*) SHCALLOC( dfb_core_shmpool(dfb_osx_core), 1, sizeof(DFBOSX) );
     if (!dfb_osx) {
          D_ERROR( "DirectFB/OSX: Couldn't allocate shared memory!\n" );
          return D_OOSHM();
     }

     dfb_osx_core = core;

     /* Initialize OSX */
     fusion_skirmish_init( &dfb_osx->lock, "OSX System", dfb_core_world(core) );

     fusion_call_init( &dfb_osx->call, dfb_osx_call_handler, NULL, dfb_core_world(core) );

     screen = dfb_screens_register( NULL, NULL, &osxPrimaryScreenFuncs );

     dfb_layers_register( screen, NULL, &osxPrimaryLayerFuncs );

     fusion_arena_add_shared_field( dfb_core_arena( core ), "OSX", dfb_osx );

     *data = dfb_osx;

     return DFB_OK;
}
Exemplo n.º 3
0
static void
bench_skirmish()
{
     DirectResult   ret;
     FusionSkirmish skirmish;

     ret = fusion_skirmish_init( &skirmish, "Benchmark", world );
     if (ret) {
          fprintf( stderr, "Fusion Error %d\n", ret );
          return;
     }


     /* skirmish prevail/dismiss */
     BENCH_START();

     BENCH_LOOP() {
          fusion_skirmish_prevail( &skirmish );
          fusion_skirmish_dismiss( &skirmish );
     }

     BENCH_STOP();

     printf( "skirmish prevail/dismiss              -> %8.2f k/sec\n", BENCH_RESULT() );


     fusion_skirmish_destroy( &skirmish );

     printf( "\n" );
}
Exemplo n.º 4
0
DirectResult
fusion_skirmish_init2( FusionSkirmish    *skirmish,
                       const char        *name,
                       const FusionWorld *world,
                       bool               local )
{
     D_ASSERT( skirmish != NULL );
     D_ASSERT( name != NULL );
     D_MAGIC_ASSERT( world, FusionWorld );

     D_DEBUG_AT( Fusion_Skirmish, "fusion_skirmish_init2( %p, '%s', %s )\n", skirmish, name ? : "", local ? "local" : "shared" );

     if (!local)
          return fusion_skirmish_init( skirmish, name, world );


     skirmish->single = D_CALLOC( 1, sizeof(FusionSkirmishSingle) + strlen(name) + 1 );
     if (skirmish->single == 0)
          return DR_NOLOCALMEMORY;

     skirmish->single->name = (char*)(skirmish->single + 1);
     strcpy( skirmish->single->name, name );

     direct_util_recursive_pthread_mutex_init( &skirmish->single->lock );
     pthread_cond_init( &skirmish->single->cond, NULL );

     /* Keep back pointer to shared world data. */
     skirmish->multi.shared = world->shared;

     return DR_OK;
}
Exemplo n.º 5
0
static DFBResult
system_initialize( CoreDFB *core, void **data )
{
     CoreScreen *core_screen;

     D_ASSERT( dfb_vnc == NULL );

     dfb_vnc = (DFBVNC*) SHCALLOC( dfb_core_shmpool(core), 1, sizeof(DFBVNC) );
     if (!dfb_vnc) {
          D_ERROR( "DirectFB/VNC: Couldn't allocate shared memory!\n" );
          return D_OOSHM();
     }

     dfb_vnc_core = core;

     fusion_skirmish_init( &dfb_vnc->lock, "VNC System", dfb_core_world(core) );

     fusion_call_init( &dfb_vnc->call, dfb_vnc_call_handler, NULL, dfb_core_world(core) );

     core_screen = dfb_screens_register( NULL, NULL, &vncPrimaryScreenFuncs );

     dfb_layers_register( core_screen, NULL, &vncPrimaryLayerFuncs );

     fusion_arena_add_shared_field( dfb_core_arena( core ), "vnc", dfb_vnc );

     *data = dfb_vnc;

     return DFB_OK;
}
Exemplo n.º 6
0
static int
dfb_core_arena_initialize( FusionArena *arena,
                           void        *ctx )
{
     DFBResult            ret;
     CoreDFB             *core = ctx;
     CoreDFBShared       *shared;
     FusionSHMPoolShared *pool;

     D_MAGIC_ASSERT( core, CoreDFB );

     D_DEBUG_AT( DirectFB_Core, "Initializing...\n" );

     /* Create the shared memory pool first! */
     ret = fusion_shm_pool_create( core->world, "DirectFB Main Pool", 0x400000,
                                   fusion_config->debugshm, &pool );
     if (ret)
          return ret;

     /* Allocate shared structure in the new pool. */
     shared = SHCALLOC( pool, 1, sizeof(CoreDFBShared) );
     if (!shared) {
          fusion_shm_pool_destroy( core->world, pool );
          return D_OOSHM();
     }

     core->shared = shared;
     core->master = true;

     shared->shmpool = pool;

     D_MAGIC_SET( shared, CoreDFBShared );

     /* Initialize. */
     ret = dfb_core_initialize( core );
     if (ret) {
          D_MAGIC_CLEAR( shared );
          SHFREE( pool, shared );
          fusion_shm_pool_destroy( core->world, pool );
          return ret;
     }

     fusion_skirmish_init( &shared->lock, "DirectFB Core", core->world );

     CoreDFB_Init_Dispatch( core, core, &shared->call );

     fusion_call_add_permissions( &shared->call, 0, FUSION_CALL_PERMIT_EXECUTE );

     /* Register shared data. */
     fusion_arena_add_shared_field( arena, "Core/Shared", shared );

     return DFB_OK;
}
Exemplo n.º 7
0
static DFBResult
system_initialize( CoreDFB *core, void **data )
{
     char       *driver;
     CoreScreen *screen;

     D_ASSERT( dfb_sdl == NULL );

     dfb_sdl = (DFBSDL*) SHCALLOC( dfb_core_shmpool(core), 1, sizeof(DFBSDL) );
     if (!dfb_sdl) {
          D_ERROR( "DirectFB/SDL: Couldn't allocate shared memory!\n" );
          return D_OOSHM();
     }

     dfb_sdl_core = core;

     dfb_fbdev_read_modes();  /* use same mode list as a fake */

     driver = getenv( "SDL_VIDEODRIVER" );
     if (driver && !strcasecmp( driver, "directfb" )) {
          D_INFO( "DirectFB/SDL: SDL_VIDEODRIVER is 'directfb', unsetting it.\n" );
          unsetenv( "SDL_VIDEODRIVER" );
     }

     /* Initialize SDL */
     if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
          D_ERROR( "DirectFB/SDL: Couldn't initialize SDL: %s\n", SDL_GetError() );

          SHFREE( dfb_core_shmpool(core), dfb_sdl );
          dfb_sdl = NULL;

          return DFB_INIT;
     }

     fusion_skirmish_init( &dfb_sdl->lock, "SDL System", dfb_core_world(core) );

     fusion_call_init( &dfb_sdl->call, dfb_sdl_call_handler, NULL, dfb_core_world(core) );

     screen = dfb_screens_register( NULL, NULL, sdlPrimaryScreenFuncs );

     dfb_layers_register( screen, NULL, sdlPrimaryLayerFuncs );

     fusion_arena_add_shared_field( dfb_core_arena( core ), "sdl", dfb_sdl );

     dfb_surface_pool_initialize( core, &sdlSurfacePoolFuncs, &dfb_sdl->sdl_pool );

     *data = dfb_sdl;

     return DFB_OK;
}
Exemplo n.º 8
0
DFBResult
dfb_layer_region_create( CoreLayerContext  *context,
                         CoreLayerRegion  **ret_region )
{
     CoreLayer       *layer;
     CoreLayerRegion *region;

     D_ASSERT( context != NULL );
     D_ASSERT( ret_region != NULL );

     layer = dfb_layer_at( context->layer_id );

     /* Create the object. */
     region = dfb_core_create_layer_region( layer->core );
     if (!region)
          return DFB_FUSION;

     /* Link the context into the structure. */
     if (dfb_layer_context_link( &region->context, context )) {
          fusion_object_destroy( &region->object );
          return DFB_FUSION;
     }

     /* Initialize the lock. */
     if (fusion_skirmish_init( &region->lock, "Layer Region", dfb_core_world(layer->core) )) {
          dfb_layer_context_unlink( &region->context );
          fusion_object_destroy( &region->object );
          return DFB_FUSION;
     }

     /* Change global reaction lock. */
     fusion_object_set_lock( &region->object, &region->lock );

     region->state = CLRSF_FROZEN;

     /* Activate the object. */
     fusion_object_activate( &region->object );

     /* Add the region to the context. */
     dfb_layer_context_add_region( context, region );

     /* Return the new region. */
     *ret_region = region;

     return DFB_OK;
}
Exemplo n.º 9
0
static DFBResult
dfb_clipboard_core_initialize( CoreDFB                *core,
                               DFBClipboardCore       *data,
                               DFBClipboardCoreShared *shared )
{
     D_DEBUG_AT( Core_Clipboard, "dfb_clipboard_core_initialize( %p, %p, %p )\n", core, data, shared );

     D_ASSERT( data != NULL );
     D_ASSERT( shared != NULL );

     data->core   = core;
     data->shared = shared;

     shared->shmpool = dfb_core_shmpool( core );

     fusion_skirmish_init( &shared->lock, "Clipboard Core", dfb_core_world(core) );

     D_MAGIC_SET( data, DFBClipboardCore );
     D_MAGIC_SET( shared, DFBClipboardCoreShared );

     return DFB_OK;
}
Exemplo n.º 10
0
SurfaceManager *
dfb_surfacemanager_create( unsigned int     length,
                           CardLimitations *limits )
{
     Chunk          *chunk;
     SurfaceManager *manager;

     manager = SHCALLOC( 1, sizeof(SurfaceManager) );
     if (!manager)
          return NULL;

     chunk = SHCALLOC( 1, sizeof(Chunk) );
     if (!chunk) {
          SHFREE( manager );
          return NULL;
     }

     chunk->offset = 0;
     chunk->length = length;

     manager->chunks           = chunk;
     manager->length           = length;
     manager->available        = length;
     manager->byteoffset_align = limits->surface_byteoffset_alignment;
     manager->pixelpitch_align = limits->surface_pixelpitch_alignment;
     manager->bytepitch_align  = limits->surface_bytepitch_alignment;
     manager->max_power_of_two_pixelpitch = limits->surface_max_power_of_two_pixelpitch;
     manager->max_power_of_two_bytepitch  = limits->surface_max_power_of_two_bytepitch;
     manager->max_power_of_two_height     = limits->surface_max_power_of_two_height;

     fusion_skirmish_init( &manager->lock, "Surface Manager" );

     D_MAGIC_SET( chunk, _Chunk_ );

     D_MAGIC_SET( manager, SurfaceManager );

     return manager;
}
Exemplo n.º 11
0
static void
bench_skirmish_threaded()
{
     int            i;
     DirectResult   ret;
     FusionSkirmish skirmish;

     ret = fusion_skirmish_init( &skirmish, "Threaded Benchmark", world );
     if (ret) {
          fprintf( stderr, "Fusion Error %d\n", ret );
          return;
     }


     /* skirmish prevail/dismiss (2-5 threads) */
     for (i=2; i<=5; i++) {
          int       t;
          pthread_t threads[i];

          BENCH_START();

          for (t=0; t<i; t++)
               pthread_create( &threads[t], NULL, prevail_dismiss_loop, &skirmish );

          for (t=0; t<i; t++)
               pthread_join( threads[t], NULL );

          BENCH_STOP();

          printf( "skirmish prevail/dismiss (%d threads)  -> %8.2f k/sec\n", i, BENCH_RESULT() );
     }


     fusion_skirmish_destroy( &skirmish );

     printf( "\n" );
}
Exemplo n.º 12
0
static DFBResult
dfb_colorhash_core_initialize( CoreDFB                *core,
                               DFBColorHashCore       *data,
                               DFBColorHashCoreShared *shared )
{
     D_DEBUG_AT( Core_ColorHash, "dfb_colorhash_core_initialize( %p, %p, %p )\n", core, data, shared );

     D_ASSERT( data != NULL );
     D_ASSERT( shared != NULL );

     core_colorhash = data; /* FIXME */

     data->core   = core;
     data->shared = shared;

     shared->shmpool = dfb_core_shmpool( core );

     fusion_skirmish_init( &shared->hash_lock, "Colorhash Core", dfb_core_world(core) );

     D_MAGIC_SET( data, DFBColorHashCore );
     D_MAGIC_SET( shared, DFBColorHashCoreShared );

     return DFB_OK;
}
Exemplo n.º 13
0
DirectResult
fusion_shm_init( FusionWorld *world )
{
     int              i;
     int              num;
     DirectResult     ret;
     FusionSHM       *shm;
     FusionSHMShared *shared;

     D_MAGIC_ASSERT( world, FusionWorld );
     D_MAGIC_ASSERT( world->shared, FusionWorldShared );

     shm    = &world->shm;
     shared = &world->shared->shm;

     /* Initialize local data. */
     memset( shm, 0, sizeof(FusionSHM) );

     shm->world  = world;
     shm->shared = shared;

     /* Initialize shared data. */
     if (fusion_master( world )) {
          memset( shared, 0, sizeof(FusionSHMShared) );

          if (fusion_config->tmpfs) {
               snprintf( shared->tmpfs, FUSION_SHM_TMPFS_PATH_NAME_LEN, fusion_config->tmpfs );
          }
          else if (!find_tmpfs( shared->tmpfs, FUSION_SHM_TMPFS_PATH_NAME_LEN )) {
               D_ERROR( "Fusion/SHM: Could not find tmpfs mount point, falling back to /dev/shm!\n" );
               snprintf( shared->tmpfs, FUSION_SHM_TMPFS_PATH_NAME_LEN, "/dev/shm" );
          }

          shared->world = world->shared;

          /* Initialize shared lock. */
          ret = fusion_skirmish_init( &shared->lock, "Fusion SHM", world );
          if (ret) {
               D_DERROR( ret, "Fusion/SHM: Failed to create skirmish!\n" );
               return ret;
          }

          /* Initialize static pool array. */
          for (i=0; i<FUSION_SHM_MAX_POOLS; i++)
               shared->pools[i].index = i;

          D_MAGIC_SET( shm, FusionSHM );
          D_MAGIC_SET( shared, FusionSHMShared );
     }
     else {
          D_MAGIC_ASSERT( shared, FusionSHMShared );

          ret = fusion_skirmish_prevail( &shared->lock );
          if (ret)
               return ret;

          D_MAGIC_SET( shm, FusionSHM );

          for (i=0, num=0; i<FUSION_SHM_MAX_POOLS; i++) {
               if (shared->pools[i].active) {
                    D_MAGIC_ASSERT( &shared->pools[i], FusionSHMPoolShared );

                    ret = fusion_shm_pool_attach( shm, &shared->pools[i] );
                    if (ret) {
                         for (--i; i>=0; i--) {
                              if (shared->pools[i].active)
                                   fusion_shm_pool_detach( shm, &shared->pools[i] );
                         }

                         fusion_skirmish_dismiss( &shared->lock );

                         D_MAGIC_CLEAR( shm );

                         return ret;
                    }

                    num++;
               }
          }

          D_ASSERT( num == shared->num_pools );

          fusion_skirmish_dismiss( &shared->lock );
     }

     return DR_OK;
}
Exemplo n.º 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;
}
Exemplo n.º 15
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;
}
Exemplo n.º 16
0
static DirectResult
init_pool( FusionSHM           *shm,
           FusionSHMPool       *pool,
           FusionSHMPoolShared *shared,
           const char          *name,
           unsigned int         max_size,
           bool                 debug )
{
     DirectResult         ret;
     int                  fd;
     int                  size;
     FusionWorld         *world;
     FusionSHMPoolNew     pool_new    = { .pool_id = 0 };
     FusionSHMPoolAttach  pool_attach = { .pool_id = 0 };
     FusionEntryInfo      info;
     char                 buf[FUSION_SHM_TMPFS_PATH_NAME_LEN + 32];

     D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p, '%s', %d, %sdebug )\n",
                 __FUNCTION__, shm, pool, shared, name, max_size, debug ? "" : "non-" );

     D_MAGIC_ASSERT( shm, FusionSHM );
     D_MAGIC_ASSERT( shm->shared, FusionSHMShared );
     D_ASSERT( name != NULL );
     D_ASSERT( max_size > sizeof(shmalloc_heap) );

     world = shm->world;

     D_MAGIC_ASSERT( world, FusionWorld );

     D_ASSERT( pool != NULL );
     D_ASSERT( shared != NULL );

     /* Fill out information for new pool. */
     pool_new.max_size = max_size;

     pool_new.max_size += BLOCKALIGN(sizeof(shmalloc_heap)) +
                          BLOCKALIGN( (max_size + BLOCKSIZE-1) / BLOCKSIZE * sizeof(shmalloc_info) );

     /* Create the new pool. */
     while (ioctl( world->fusion_fd, FUSION_SHMPOOL_NEW, &pool_new )) {
          if (errno == EINTR)
               continue;

          D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_NEW failed!\n" );
          return DR_FUSION;
     }

     /* Set the pool info. */
     info.type = FT_SHMPOOL;
     info.id   = pool_new.pool_id;

     snprintf( info.name, sizeof(info.name), "%s", name );

     ioctl( world->fusion_fd, FUSION_ENTRY_SET_INFO, &info );


     /* Set pool to attach to. */
     pool_attach.pool_id = pool_new.pool_id;

     /* Attach to the pool. */
     while (ioctl( world->fusion_fd, FUSION_SHMPOOL_ATTACH, &pool_attach )) {
          if (errno == EINTR)
               continue;

          D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_ATTACH failed!\n" );

          while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DESTROY, &shared->pool_id )) {
               if (errno != EINTR) {
                    D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DESTROY failed!\n" );
                    break;
               }
          }

          return DR_FUSION;
     }


     /* Generate filename. */
     snprintf( buf, sizeof(buf), "%s/fusion.%d.%d", shm->shared->tmpfs,
               fusion_world_index( shm->world ), pool_new.pool_id );

     /* Initialize the heap. */
     ret = __shmalloc_init_heap( shm, buf, pool_new.addr_base, max_size, &fd, &size );
     if (ret) {
          while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DESTROY, &shared->pool_id )) {
               if (errno != EINTR) {
                    D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DESTROY failed!\n" );
                    break;
               }
          }

          return ret;
     }


     /* Initialize local data. */
     pool->attached = true;
     pool->shm      = shm;
     pool->shared   = shared;
     pool->pool_id  = pool_new.pool_id;
     pool->fd       = fd;
     pool->filename = D_STRDUP( buf );

     /* Initialize shared data. */
     shared->active     = true;
     shared->debug      = debug;
     shared->shm        = shm->shared;
     shared->max_size   = pool_new.max_size;
     shared->pool_id    = pool_new.pool_id;
     shared->addr_base  = pool_new.addr_base;
     shared->heap       = pool_new.addr_base;
     shared->heap->pool = shared;

     fusion_skirmish_init( &shared->lock, name, world );


     D_MAGIC_SET( pool, FusionSHMPool );
     D_MAGIC_SET( shared, FusionSHMPoolShared );


     shared->name = SHSTRDUP( shared, name );

     return DR_OK;
}

static DirectResult
join_pool( FusionSHM           *shm,
           FusionSHMPool       *pool,
           FusionSHMPoolShared *shared )
{
     DirectResult         ret;
     int                  fd;
     FusionWorld         *world;
     FusionSHMPoolAttach  pool_attach = { .pool_id = 0 };
     char                 buf[FUSION_SHM_TMPFS_PATH_NAME_LEN + 32];

     D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p )\n", __FUNCTION__, shm, pool, shared );

     D_MAGIC_ASSERT( shm, FusionSHM );
     D_MAGIC_ASSERT( shm->shared, FusionSHMShared );
     D_MAGIC_ASSERT( shared, FusionSHMPoolShared );

#if !DIRECT_BUILD_DEBUGS
     if (shared->debug) {
          D_ERROR( "Fusion/SHM: Can't join debug enabled pool with pure-release library!\n" );
          return DR_UNSUPPORTED;
     }
#endif

     world = shm->world;

     D_MAGIC_ASSERT( world, FusionWorld );


     /* Set pool to attach to. */
     pool_attach.pool_id = shared->pool_id;

     /* Attach to the pool. */
     while (ioctl( world->fusion_fd, FUSION_SHMPOOL_ATTACH, &pool_attach )) {
          if (errno == EINTR)
               continue;

          D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_ATTACH failed!\n" );
          return DR_FUSION;
     }


     /* Generate filename. */
     snprintf( buf, sizeof(buf), "%s/fusion.%d.%d", shm->shared->tmpfs,
               fusion_world_index( shm->world ), shared->pool_id );

     /* Join the heap. */
     ret = __shmalloc_join_heap( shm, buf, pool_attach.addr_base, shared->max_size, &fd );
     if (ret) {
          while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DETACH, &shared->pool_id )) {
               if (errno != EINTR) {
                    D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DETACH failed!\n" );
                    break;
               }
          }

          return ret;
     }


     /* Initialize local data. */
     pool->attached = true;
     pool->shm      = shm;
     pool->shared   = shared;
     pool->pool_id  = shared->pool_id;
     pool->fd       = fd;
     pool->filename = D_STRDUP( buf );


     D_MAGIC_SET( pool, FusionSHMPool );

     return DR_OK;
}

static void
leave_pool( FusionSHM           *shm,
            FusionSHMPool       *pool,
            FusionSHMPoolShared *shared )
{
     FusionWorld *world;

     D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p )\n", __FUNCTION__, shm, pool, shared );

     D_MAGIC_ASSERT( shm, FusionSHM );
     D_MAGIC_ASSERT( pool, FusionSHMPool );
     D_MAGIC_ASSERT( shared, FusionSHMPoolShared );

     world = shm->world;

     D_MAGIC_ASSERT( world, FusionWorld );

     while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DETACH, &shared->pool_id )) {
          if (errno != EINTR) {
               D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DETACH failed!\n" );
               break;
          }
     }

     if (munmap( shared->addr_base, shared->max_size ))
          D_PERROR( "Fusion/SHM: Could not munmap shared memory file '%s'!\n", pool->filename );

     if (pool->fd != -1 && close( pool->fd ))
          D_PERROR( "Fusion/SHM: Could not close shared memory file '%s'!\n", pool->filename );

     pool->attached = false;

     D_FREE( pool->filename );

     D_MAGIC_CLEAR( pool );
}

static void
shutdown_pool( FusionSHM           *shm,
               FusionSHMPool       *pool,
               FusionSHMPoolShared *shared )
{
     FusionWorld *world;

     D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p )\n", __FUNCTION__, shm, pool, shared );

     D_MAGIC_ASSERT( shm, FusionSHM );
     D_MAGIC_ASSERT( pool, FusionSHMPool );
     D_MAGIC_ASSERT( shared, FusionSHMPoolShared );

     world = shm->world;

     D_MAGIC_ASSERT( world, FusionWorld );

     SHFREE( shared, shared->name );

     fusion_dbg_print_memleaks( shared );

     while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DESTROY, &shared->pool_id )) {
          if (errno != EINTR) {
               D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DESTROY failed!\n" );
               break;
          }
     }

     if (munmap( shared->addr_base, shared->max_size ))
          D_PERROR( "Fusion/SHM: Could not munmap shared memory file '%s'!\n", pool->filename );

     if (pool->fd != -1 && close( pool->fd ))
          D_PERROR( "Fusion/SHM: Could not close shared memory file '%s'!\n", pool->filename );

     if (unlink( pool->filename ))
          D_PERROR( "Fusion/SHM: Could not unlink shared memory file '%s'!\n", pool->filename );

     shared->active = false;

     pool->attached = false;

     D_FREE( pool->filename );

     D_MAGIC_CLEAR( pool );

     fusion_skirmish_destroy( &shared->lock );

     D_MAGIC_CLEAR( shared );
}
Exemplo n.º 17
0
DFBResult
dfb_surface_create( CoreDFB                  *core,
                    const CoreSurfaceConfig  *config,
                    CoreSurfaceTypeFlags      type,
                    unsigned long             resource_id,
                    CorePalette              *palette,
                    CoreSurface             **ret_surface )
{
     DFBResult    ret = DFB_BUG;
     int          i;
     int          buffers;
     CoreSurface *surface;
     char         buf[64];

     D_ASSERT( core != NULL );
     D_FLAGS_ASSERT( type, CSTF_ALL );
     D_MAGIC_ASSERT_IF( palette, CorePalette );
     D_ASSERT( ret_surface != NULL );

     D_DEBUG_AT( Core_Surface, "dfb_surface_create( %p, %p, %p )\n", core, config, ret_surface );

     surface = dfb_core_create_surface( core );
     if (!surface)
          return DFB_FUSION;

     if (config) {
          D_FLAGS_ASSERT( config->flags, CSCONF_ALL );

          surface->config.flags = config->flags;

          if (config->flags & CSCONF_SIZE) {
               D_DEBUG_AT( Core_Surface, "  -> %dx%d\n", config->size.w, config->size.h );

               surface->config.size = config->size;
          }

          if (config->flags & CSCONF_FORMAT) {
               D_DEBUG_AT( Core_Surface, "  -> %s\n", dfb_pixelformat_name( config->format ) );

               surface->config.format = config->format;
          }

          if (config->flags & CSCONF_CAPS) {
               D_DEBUG_AT( Core_Surface, "  -> caps 0x%08x\n", config->caps );

               surface->config.caps = config->caps;
          }

          if (config->flags & CSCONF_PREALLOCATED) {
               D_DEBUG_AT( Core_Surface, "  -> prealloc %p [%d]\n",
                           config->preallocated[0].addr,
                           config->preallocated[0].pitch );

               direct_memcpy( surface->config.preallocated, config->preallocated, sizeof(config->preallocated) );

               type |= CSTF_PREALLOCATED;
          }
     }

     if (surface->config.caps & DSCAPS_SYSTEMONLY)
          surface->type = (type & ~CSTF_EXTERNAL) | CSTF_INTERNAL;
     else if (surface->config.caps & DSCAPS_VIDEOONLY)
          surface->type = (type & ~CSTF_INTERNAL) | CSTF_EXTERNAL;
     else
          surface->type = type & ~(CSTF_INTERNAL | CSTF_EXTERNAL);

     if (surface->config.caps & DSCAPS_SHARED)
          surface->type |= CSTF_SHARED;

     surface->resource_id = resource_id;

     if (surface->config.caps & DSCAPS_TRIPLE)
          buffers = 3;
     else if (surface->config.caps & DSCAPS_DOUBLE)
          buffers = 2;
     else
          buffers = 1;

     surface->notifications = CSNF_ALL & ~CSNF_FLIP;

     surface->alpha_ramp[0] = 0x00;
     surface->alpha_ramp[1] = 0x55;
     surface->alpha_ramp[2] = 0xaa;
     surface->alpha_ramp[3] = 0xff;


     if (surface->config.caps & DSCAPS_STATIC_ALLOC)
          surface->config.min_size = surface->config.size;

     surface->shmpool = dfb_core_shmpool( core );

     direct_serial_init( &surface->serial );

     snprintf( buf, sizeof(buf), "Surface %dx%d %s", surface->config.size.w,
               surface->config.size.h, dfb_pixelformat_name(surface->config.format) );

     fusion_ref_set_name( &surface->object.ref, buf );

     fusion_skirmish_init( &surface->lock, buf, dfb_core_world(core) );

     fusion_object_set_lock( &surface->object, &surface->lock );

     D_MAGIC_SET( surface, CoreSurface );


     if (dfb_config->warn.flags & DCWF_CREATE_SURFACE &&
         dfb_config->warn.create_surface.min_size.w <= surface->config.size.w &&
         dfb_config->warn.create_surface.min_size.h <= surface->config.size.h)
          D_WARN( "create-surface  %4dx%4d %6s, buffers %d, caps 0x%08x, type 0x%08x",
                  surface->config.size.w, surface->config.size.h, dfb_pixelformat_name(surface->config.format),
                  buffers, surface->config.caps, surface->type );


     if (palette) {
          dfb_surface_set_palette( surface, palette );
     }
     else if (DFB_PIXELFORMAT_IS_INDEXED( surface->config.format )) {
          ret = dfb_surface_init_palette( core, surface );
          if (ret)
               goto error;
     }

     /* Create the Surface Buffers. */
     for (i=0; i<buffers; i++) {
          CoreSurfaceBuffer *buffer;

          ret = dfb_surface_buffer_new( surface, CSBF_NONE, &buffer );
          if (ret) {
               D_DERROR( ret, "Core/Surface: Error creating surface buffer!\n" );
               goto error;
          }

          surface->buffers[surface->num_buffers++] = buffer;

          switch (i) {
               case 0:
                    surface->buffer_indices[CSBR_FRONT] = i;
               case 1:
                    surface->buffer_indices[CSBR_BACK] = i;
               case 2:
                    surface->buffer_indices[CSBR_IDLE] = i;
          }
     }

     fusion_object_activate( &surface->object );

     *ret_surface = surface;

     return DFB_OK;

error:
     D_MAGIC_CLEAR( surface );

     for (i=0; i<MAX_SURFACE_BUFFERS; i++) {
          if (surface->buffers[i])
               dfb_surface_buffer_destroy( surface->buffers[i] );
     }

     fusion_skirmish_destroy( &surface->lock );

     direct_serial_deinit( &surface->serial );

     fusion_object_destroy( &surface->object );

     return ret;
}
Exemplo n.º 18
0
static DFBResult
system_initialize( CoreDFB *core, void **data )
{
     int         i, n;
     CoreScreen *screen;

     D_ASSERT( dfb_x11 == NULL );

     dfb_x11 = (DFBX11*) SHCALLOC( dfb_core_shmpool(core), 1, sizeof(DFBX11) );
     if (!dfb_x11) {
          D_ERROR( "DirectFB/X11: Couldn't allocate shared memory!\n" );
          return D_OOSHM();
     }

     dfb_x11_core = core;

     fusion_skirmish_init( &dfb_x11->lock, "X11 System", dfb_core_world(core) );

     fusion_call_init( &dfb_x11->call, call_handler, NULL, dfb_core_world(core) );

     dfb_surface_pool_initialize( core, &x11SurfacePoolFuncs, &dfb_x11->surface_pool );

     screen = dfb_screens_register( NULL, NULL, &x11PrimaryScreenFuncs );

     dfb_layers_register( screen, NULL, &x11PrimaryLayerFuncs );

     fusion_arena_add_shared_field( dfb_core_arena( core ), "x11", dfb_x11 );

     *data = dfb_x11;

     XInitThreads();

     dfb_x11->data_shmpool = dfb_core_shmpool_data( core );

     dfb_x11->display = XOpenDisplay(getenv("DISPLAY"));
     if (!dfb_x11->display) {
          D_ERROR("X11: Error in XOpenDisplay for '%s'\n", getenv("DISPLAY"));
          return DFB_INIT;
     }

     dfb_x11->screenptr = DefaultScreenOfDisplay(dfb_x11->display);
     dfb_x11->screennum = DefaultScreen(dfb_x11->display);

     for (i=0; i<dfb_x11->screenptr->ndepths; i++) {
          const Depth *depth = &dfb_x11->screenptr->depths[i];

          for (n=0; n<depth->nvisuals; n++) {
               Visual *visual = &depth->visuals[n];

               D_DEBUG( "X11/Visual: ID %02lu, depth %d, red 0x%06lx, green 0x%06lx, blue 0x%06lx, %d bits/rgb, %d entries\n",
                        visual->visualid, depth->depth,
                        visual->red_mask, visual->green_mask, visual->blue_mask,
                        visual->bits_per_rgb, visual->map_entries );

               switch (depth->depth) {
                    case 24:
                         if (visual->red_mask   == 0xff0000 &&
                             visual->green_mask == 0x00ff00 &&
                             visual->blue_mask  == 0x0000ff) {
                              dfb_x11->visuals[DFB_PIXELFORMAT_INDEX(DSPF_RGB32)] = visual;
                              dfb_x11->visuals[DFB_PIXELFORMAT_INDEX(DSPF_ARGB)]  = visual;
                         }
                         break;

                    case 16:
                         if (visual->red_mask   == 0xf800 &&
                             visual->green_mask == 0x07e0 &&
                             visual->blue_mask  == 0x001f)
                              dfb_x11->visuals[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)] = visual;
                         break;

                    case 15:
                         if (visual->red_mask   == 0x7c00 &&
                             visual->green_mask == 0x03e0 &&
                             visual->blue_mask  == 0x001f)
                              dfb_x11->visuals[DFB_PIXELFORMAT_INDEX(DSPF_RGB555)] = visual;
                         break;
               }
          }
     }

     return DFB_OK;
}
Exemplo n.º 19
0
static DirectResult
init_pool( FusionSHM           *shm,
           FusionSHMPool       *pool,
           FusionSHMPoolShared *shared,
           const char          *name,
           unsigned int         max_size,
           bool                 debug )
{
     DirectResult   ret;
     int            size;
     long           page_size;
     int            pool_id;
     unsigned int   pool_max_size;
     void          *pool_addr_base = NULL;
     FusionWorld   *world;
     char           buf[FUSION_SHM_TMPFS_PATH_NAME_LEN + 32];

     D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p, '%s', %d, %sdebug )\n",
                 __FUNCTION__, shm, pool, shared, name, max_size, debug ? "" : "non-" );

     D_MAGIC_ASSERT( shm, FusionSHM );
     D_MAGIC_ASSERT( shm->shared, FusionSHMShared );
     D_ASSERT( name != NULL );
     D_ASSERT( max_size > sizeof(shmalloc_heap) );

     world = shm->world;

     D_MAGIC_ASSERT( world, FusionWorld );

     D_ASSERT( pool != NULL );
     D_ASSERT( shared != NULL );

     page_size = direct_pagesize();

     pool_id = ++world->shared->pool_ids;

     pool_max_size = max_size + BLOCKALIGN(sizeof(shmalloc_heap)) +
                                BLOCKALIGN( (max_size + BLOCKSIZE-1) / BLOCKSIZE * sizeof(shmalloc_info) );

     pool_addr_base = world->shared->pool_base;
     world->shared->pool_base += ((pool_max_size + page_size - 1) & ~(page_size - 1)) + page_size;
     /* Exceeded limit? */
     if (world->shared->pool_base > world->shared->pool_max)
          return DR_NOSHAREDMEMORY;

     /* Generate filename. */
     snprintf( buf, sizeof(buf), "%s/fusion.%d.%d", shm->shared->tmpfs,
               fusion_world_index( world ), pool_id );

     /* Initialize the heap. */
     ret = __shmalloc_init_heap( shm, buf, pool_addr_base, max_size, &size );
     if (ret)
          return ret;

     /* initialize local data. */
     pool->attached = true;
     pool->shm      = shm;
     pool->shared   = shared;
     pool->pool_id  = pool_id;
     pool->filename = D_STRDUP( buf );

     /* Initialize shared data. */
     shared->active     = true;
     shared->debug      = debug;
     shared->shm        = shm->shared;
     shared->max_size   = pool_max_size;
     shared->pool_id    = pool_id;
     shared->addr_base  = pool_addr_base;
     shared->heap       = pool_addr_base;
     shared->heap->pool = shared;

     fusion_skirmish_init( &shared->lock, name, world );


     D_MAGIC_SET( pool, FusionSHMPool );
     D_MAGIC_SET( shared, FusionSHMPoolShared );


     shared->name = SHSTRDUP( shared, name );

     return DR_OK;
}
Exemplo n.º 20
0
static DFBResult
system_initialize( CoreDFB *core, void **data )
{
     DFBResult     ret;
     DFBX11       *x11;
     DFBX11Shared *shared;

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

     x11 = D_CALLOC( 1, sizeof(DFBX11) );
     if (!x11)
          return D_OOM();

     shared = SHCALLOC( dfb_core_shmpool( core ), 1, sizeof(DFBX11Shared) );
     if (!shared) {
          D_FREE( x11 );
          return D_OOSHM();
     }

     /* we need the error handler to signal the error to us, so
        use a global static */
     shared_for_error_handler = shared;
     XSetErrorHandler( error_handler );

     /*
      * Local init (master and slave)
      */
     ret = InitLocal( x11, shared, core );
     if (ret) {
          SHFREE( dfb_core_shmpool( core ), shared );
          D_FREE( x11 );
          return ret;
     }


     /*
      * Shared init (master only)
      */
     shared->data_shmpool = dfb_core_shmpool_data( core );

     shared->screen_size.w = x11->screenptr->width;
     shared->screen_size.h = x11->screenptr->height;

     fusion_skirmish_init( &shared->lock, "X11 System", dfb_core_world(core) );

     fusion_call_init( &shared->call, call_handler, x11, dfb_core_world(core) );


     /*
      * Must be set before initializing the pools!
      */
     *data = x11;


     /*
      * Master init
      */
     dfb_surface_pool_initialize( core, &x11SurfacePoolFuncs, &shared->x11image_pool );

#ifdef USE_GLX
     dfb_surface_pool_initialize( core, &glxSurfacePoolFuncs, &shared->glx_pool );
#endif

     if (dfb_config->video_length) {
          shared->vpsmem_length = dfb_config->video_length;

          dfb_surface_pool_initialize( core, &vpsmemSurfacePoolFuncs, &shared->vpsmem_pool );
     }

#ifdef USE_GLX
     dfb_surface_pool_bridge_initialize( core, &x11SurfacePoolBridgeFuncs, x11, &shared->x11_pool_bridge );
#endif

     fusion_arena_add_shared_field( dfb_core_arena( core ), "x11", shared );

     return DFB_OK;
}
Exemplo n.º 21
0
int
fusion_init( int world, int abi_version, int *world_ret )
{
     char        buf[20];
     FusionEnter enter;

     /* Check against multiple initialization. */
     if (_fusion_id) {
          /* Increment local reference counter. */
          fusion_refs++;

          return _fusion_id;
     }

     direct_initialize();

     /* Open Fusion Kernel Device. */
     if (world < 0) {
          for (world=0; world<256; world++) {
               snprintf( buf, sizeof(buf), "/dev/fusion/%d", world );

               _fusion_fd = open (buf, O_RDWR | O_NONBLOCK | O_EXCL);
               if (_fusion_fd < 0) {
                    if (errno == EBUSY)
                         continue;

                    D_PERROR( "Fusion/Init: opening '%s' failed!\n", buf );
                    direct_shutdown();
                    return -1;
               }
               else
                    break;
          }
     }
     else {
          snprintf( buf, sizeof(buf), "/dev/fusion/%d", world );

          _fusion_fd = open (buf, O_RDWR | O_NONBLOCK);
          if (_fusion_fd < 0) {
               D_PERROR( "Fusion/Init: opening '%s' failed!\n", buf );
               direct_shutdown();
               return -1;
          }
     }

     enter.api.major = FUSION_API_MAJOR;
     enter.api.minor = FUSION_API_MINOR;
     enter.fusion_id = 0;

     /* Get our Fusion ID. */
     if (ioctl( _fusion_fd, FUSION_ENTER, &enter )) {
          D_PERROR( "Fusion/Init: FUSION_ENTER failed!\n" );
          goto error;
     }

     if (!enter.fusion_id) {
          D_ERROR( "Fusion/Init: Got no ID from FUSION_ENTER! Kernel module might be too old.\n" );
          goto error;
     }

     _fusion_id = enter.fusion_id;


     /* Initialize local reference counter. */
     fusion_refs = 1;

     /* Initialize shmalloc part. */
     if (!__shmalloc_init( world, _fusion_id == 1 )) {
          D_ERROR( "Fusion/Init: Shared memory initialization failed.\n"
                   "\n"
                   "Please make sure that a tmpfs mount point with at least 4MB of free space\n"
                   "is available for read/write, see the DirectFB README for more instructions.\n" );
          goto error;
     }

     if (_fusion_id == 1) {
          _fusion_shared = __shmalloc_allocate_root( sizeof(FusionShared) );

          _fusion_shared->abi_version = abi_version;

          fusion_skirmish_init( &_fusion_shared->arenas_lock,     "Fusion Arenas" );
          fusion_skirmish_init( &_fusion_shared->reactor_globals, "Fusion Reactor Globals" );

          _sheap->reactor = fusion_reactor_new( sizeof(long), "Shared Memory Heap" );
          if (!_sheap->reactor) {
               __shmalloc_exit( true, true );
               goto error_reactor;
          }

          gettimeofday( &_fusion_shared->start_time, NULL );
     }
     else {
          _fusion_shared = __shmalloc_get_root();

          if (_fusion_shared->abi_version != abi_version) {
               D_ERROR( "Fusion/Init: ABI version mismatch (my: %d, their: %d)\n",
                        abi_version, _fusion_shared->abi_version );
               __shmalloc_exit( false, false );
               goto error;
          }
     }

     __shmalloc_attach();

     direct_clock_set_start( &_fusion_shared->start_time );

     direct_signal_handler_add( SIGSEGV, fusion_signal_handler, NULL, &signal_handler );

     read_loop = direct_thread_create( DTT_MESSAGING, fusion_read_loop, NULL, "Fusion Dispatch" );

     if (world_ret)
          *world_ret = world;

     return _fusion_id;


error_reactor:
     fusion_skirmish_destroy( &_fusion_shared->arenas_lock );
     fusion_skirmish_destroy( &_fusion_shared->reactor_globals );

error:
     _fusion_shared = NULL;
     _fusion_id = 0;

     close( _fusion_fd );
     _fusion_fd = -1;
     direct_shutdown();
     return -1;
}