Beispiel #1
0
DirectResult
fusion_ref_set_name (FusionRef  *ref,
                     const char *name)
{
     FusionEntryInfo info;

     D_ASSERT( ref != NULL );
     D_ASSERT( name != NULL );

     info.type = FT_REF;
     info.id   = ref->multi.id;

     direct_snputs( info.name, name, sizeof(info.name) );

     while (ioctl (_fusion_fd( ref->multi.shared ), FUSION_ENTRY_SET_INFO, &info)) {
          switch (errno) {
               case EINTR:
                    continue;
               case EAGAIN:
                    return DR_LOCKED;
               case EINVAL:
                    D_ERROR ("Fusion/Reference: invalid reference\n");
                    return DR_DESTROYED;
               default:
                    break;
          }

          D_PERROR ("FUSION_ENTRY_SET_NAME");

          return DR_FAILURE;
     }

     return DR_OK;
}
Beispiel #2
0
DirectResult
fusion_call_set_name( FusionCall *call,
                      const char *name )
{
     FusionEntryInfo info;

     D_ASSERT( call != NULL );
     D_ASSERT( name != NULL );

     info.type = FT_CALL;
     info.id   = call->call_id;

     direct_snputs( info.name, name, sizeof(info.name) );

     while (ioctl (_fusion_fd( call->shared ), FUSION_ENTRY_SET_INFO, &info)) {
          perror("FUSION_ENTRY_SET_INFO");
          switch (errno) {
               case EINTR:
                    continue;
               case EAGAIN:
                    return DR_LOCKED;
               case EINVAL:
                    D_ERROR ("Fusion/Call: invalid call\n");
                    return DR_DESTROYED;
               default:
                    break;
          }

          D_PERROR ("FUSION_ENTRY_SET_NAME");

          return DR_FAILURE;
     }

     return DR_OK;
}
Beispiel #3
0
DirectResult
fusion_skirmish_init( FusionSkirmish    *skirmish,
                      const char        *name,
                      const FusionWorld *world )
{
     FusionEntryInfo info;

     D_ASSERT( skirmish != NULL );
     D_ASSERT( name != NULL );
     D_MAGIC_ASSERT( world, FusionWorld );
     
     D_DEBUG_AT( Fusion_Skirmish, "fusion_skirmish_init( %p, '%s' )\n", skirmish, name ? : "" );

     while (ioctl( world->fusion_fd, FUSION_SKIRMISH_NEW, &skirmish->multi.id )) {
          if (errno == EINTR)
               continue;

          D_PERROR( "FUSION_SKIRMISH_NEW" );
          return DFB_FUSION;
     }

     D_DEBUG_AT( Fusion_Skirmish, "  -> new skirmish %p [%d]\n", skirmish, skirmish->multi.id );
     
     info.type = FT_SKIRMISH;
     info.id   = skirmish->multi.id;

     direct_snputs( info.name, name, sizeof(info.name) );

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

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

     return DFB_OK;
}
Beispiel #4
0
int
main( int argc, char *argv[] )
{
     DFBResult       ret;
     int             i;
     VoodooPlayInfo  info;
     VoodooPlayer   *player = NULL;

     /* Initialize DirectFB including command line parsing. */
     ret = DirectFBInit( &argc, &argv );
     if (ret) {
          DirectFBError( "DirectFBInit() failed", ret );
          return -1;
     }

     /* Parse the command line. */
     if (!parse_command_line( argc, argv ))
          return -2;

     if (m_name) {
          direct_snputs( info.name, m_name, VOODOO_PLAYER_NAME_LENGTH );
     }

     ret = voodoo_player_create( m_name ? &info : NULL, &player );
     if (ret) {
          D_ERROR( "Voodoo/Play: Could not create the player (%s)!\n", DirectFBErrorString(ret) );
          goto out;
     }


     do {
          voodoo_player_broadcast( player );

          direct_thread_sleep( 100000 );

          voodoo_player_enumerate( player, player_callback, NULL );

          if (m_lookup) {
               for (i=1; i<argc; i++) {
                    char buf[100];

                    if (voodoo_player_lookup( player, (const u8 *)argv[i], NULL, buf, sizeof(buf) )) {
                         D_ERROR( "Voodoo/Play: No '%s' found!\n", argv[i] );
                         continue;
                    }

                    D_INFO( "Voodoo/Play: Found '%s' with address %s\n", argv[i], buf );
               }
          }

          direct_thread_sleep( 2000000 );
     } while (m_run);


out:
     if (player)
          voodoo_player_destroy( player );

     return ret;
}
Beispiel #5
0
static DFBResult
drmkmsInitOutput( CoreScreen                  *screen,
                  void                        *driver_data,
                  void                        *screen_data,
                  int                          output,
                  DFBScreenOutputDescription  *description,
                  DFBScreenOutputConfig       *config )
{
     DRMKMSData       *drmkms    = driver_data;
     DRMKMSDataShared *shared    = drmkms->shared;

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

     direct_snputs( description->name, "DRMKMS Output", DFB_SCREEN_OUTPUT_DESC_NAME_LENGTH );


     description->caps            = DSOCAPS_RESOLUTION;

     switch (drmkms->connector[output]->connector_type) {
          case DRM_MODE_CONNECTOR_VGA:
               description->all_connectors = DSOC_VGA;
               description->all_signals    = DSOS_VGA;
               break;
          case DRM_MODE_CONNECTOR_SVIDEO:
               description->all_connectors = DSOC_YC;
               description->all_signals    = DSOS_YC;
               break;
          case DRM_MODE_CONNECTOR_Composite:
               description->all_connectors = DSOC_CVBS;
               description->all_signals    = DSOS_CVBS;
               break;
          case DRM_MODE_CONNECTOR_Component:
               description->all_connectors = DSOC_COMPONENT;
               description->all_signals    = DSOS_YCBCR;
               break;
          case DRM_MODE_CONNECTOR_HDMIA:
          case DRM_MODE_CONNECTOR_HDMIB:
               description->all_connectors = DSOC_HDMI;
               description->all_signals    = DSOS_HDMI;
               break;
          default:
               description->all_connectors = DSOC_UNKNOWN;
               description->all_signals    = DSOC_UNKNOWN;
     }

     description->all_resolutions = drmkms_modes_to_dsor_bitmask( output );

     config->flags                = DSOCONF_RESOLUTION;

     drmkms_mode_to_dsor_dsef( &shared->mode[output], &config->resolution, NULL );

     return DFB_OK;
}
Beispiel #6
0
static DFBResult
dummyInitScreen( CoreScreen           *screen,
                 CoreGraphicsDevice   *device,
                 void                 *driver_data,
                 void                 *screen_data,
                 DFBScreenDescription *description )
{
     description->caps = DSCCAPS_NONE;

     direct_snputs( description->name, "Dummy", DFB_SCREEN_DESC_NAME_LENGTH );

     return DFB_OK;
}
Beispiel #7
0
static DFBResult
drmkmsInitEncoder( CoreScreen                  *screen,
                   void                        *driver_data,
                   void                        *screen_data,
                   int                          encoder,
                   DFBScreenEncoderDescription *description,
                   DFBScreenEncoderConfig      *config )
{
     DRMKMSData       *drmkms    = driver_data;
     DRMKMSDataShared *shared    = drmkms->shared;

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

     direct_snputs( description->name, "DRMKMS Encoder", DFB_SCREEN_ENCODER_DESC_NAME_LENGTH );

     description->caps = DSECAPS_RESOLUTION | DSECAPS_FREQUENCY;

     config->flags     = DSECONF_RESOLUTION | DSECONF_FREQUENCY | DSECONF_MIXER;
     config->mixer     = encoder;

     if (drmkms->encoder[encoder]) {
          switch (drmkms->encoder[encoder]->encoder_type) {
               case DRM_MODE_ENCODER_DAC:
                    description->type = DSET_CRTC;
                    break;
               case DRM_MODE_ENCODER_LVDS:
               case DRM_MODE_ENCODER_TMDS:
                    description->type = DSET_DIGITAL;
                    break;
               case DRM_MODE_ENCODER_TVDAC:
                    description->type = DSET_TV;
                    break;
               default:
                    description->type = DSET_UNKNOWN;
          }

          drmkms_mode_to_dsor_dsef( &shared->mode[encoder], &config->resolution, &config->frequency );

          description->all_resolutions = drmkms_modes_to_dsor_bitmask( encoder );
     }
     else {
          description->type            = DSET_DIGITAL;
          description->all_resolutions = DSOR_1280_720;

          config->resolution           = DSOR_1280_720;
          config->frequency            = DSEF_60HZ;
     }

     return DFB_OK;
}
Beispiel #8
0
int
fusion_find_tmpfs( char *name, int len )
{
    int    largest = 0;
    char   buffer[1024];
    FILE  *mounts_handle;

    mounts_handle = fopen( "/proc/mounts", "r" );
    if (!mounts_handle)
        return 0;

    while (fgets( buffer, sizeof(buffer), mounts_handle )) {
        char *mount_point;
        char *mount_fs;
        char *pointer = buffer;

        strsep( &pointer, " " );

        mount_point = strsep( &pointer, " " );
        mount_fs = strsep( &pointer, " " );

        if (mount_fs && mount_point && !access( mount_point, W_OK ) &&
                (!strcmp( mount_fs, "tmpfs" ) || !strcmp( mount_fs, "shmfs" ) || !strcmp( mount_fs, "ramfs" )))
        {
            struct statfs stat;
            s64           bytes;

            if (statfs( mount_point, &stat )) {
                D_PERROR( "Fusion/SHM: statfs on '%s' failed!\n", mount_point );
                continue;
            }

            bytes = stat.f_blocks * stat.f_bsize;

            if (bytes > largest || (bytes == largest && !strcmp(mount_point,"/dev/shm"))) {
                largest = bytes;

                direct_snputs( name, mount_point, len );
            }
        }
    }

    fclose( mounts_handle );

    return largest;
}
Beispiel #9
0
void
direct_perf_count( DirectPerfCounterInstallation *installation, int diff )
{
     DirectPerfCounter *counter;

     D_ASSERT( installation != NULL );

     direct_mutex_lock( &counter_lock );

     if (installation->counter_id == 0) {
          counter = D_CALLOC( 1, sizeof(DirectPerfCounter) );
          if (!counter) {
               direct_mutex_unlock( &counter_lock );
               D_OOM();
               return;
          }

          installation->counter_id = ++counter_ids;
          D_ASSERT( installation->counter_id != 0 );
          D_ASSERT( installation->counter_id != ~0 );   // FIXME: can there be more than 4 billion counters?

          direct_snputs( counter->name, installation->name, sizeof(counter->name) );

          counter->reset_on_dump = installation->reset_on_dump;

          direct_hash_insert( &counter_hash, installation->counter_id, counter );
     }
     else {
          counter = direct_hash_lookup( &counter_hash, installation->counter_id );
          if (!counter) {
               direct_mutex_unlock( &counter_lock );
               D_BUG( "unknown performance counter installation (%lu)", installation->counter_id );
               return;
          }
     }

     counter->count += diff;

     if (!counter->start)
          counter->start = direct_clock_get_time( DIRECT_CLOCK_SESSION );

     direct_mutex_unlock( &counter_lock );
}
Beispiel #10
0
int
main( int argc, char *argv[] )
{
     DFBResult       ret;
     VoodooPlayInfo  info;
     VoodooPlayer   *player = NULL;

     /* Initialize DirectFB including command line parsing. */
     ret = DirectFBInit( &argc, &argv );
     if (ret) {
          DirectFBError( "DirectFBInit() failed", ret );
          return -1;
     }

     /* Parse the command line. */
     if (!parse_command_line( argc, argv ))
          return -2;

     if (m_name) {
          direct_snputs( info.name, m_name, VOODOO_PLAYER_NAME_LENGTH );
     }

     ret = voodoo_player_create( m_name ? &info : NULL, &player );
     if (ret) {
          D_ERROR( "Voodoo/Play: Could not create the player (%s)!\n", DirectFBErrorString(ret) );
          goto out;
     }


     voodoo_player_broadcast( player );

     sleep( 1 );

     voodoo_player_enumerate( player, player_callback, NULL );


out:
     if (player)
          voodoo_player_destroy( player );

     return ret;
}
Beispiel #11
0
static DFBResult
drmkmsInitLayer( CoreLayer                  *layer,
                 void                       *driver_data,
                 void                       *layer_data,
                 DFBDisplayLayerDescription *description,
                 DFBDisplayLayerConfig      *config,
                 DFBColorAdjustment         *adjustment )
{
     DRMKMSData       *drmkms = driver_data;
     DRMKMSDataShared *shared = drmkms->shared;
     DRMKMSLayerData  *data   = layer_data;

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


     data->index       = shared->layerplane_index_count++;
     data->layer_index = shared->layer_index_count++;
     data->level       = 0;

     description->type             = DLTF_GRAPHICS;
     description->caps             = DLCAPS_SURFACE;
     description->surface_caps     = DSCAPS_NONE;
     description->surface_accessor = CSAID_LAYER0;

     direct_snputs( description->name, "DRMKMS Layer", DFB_DISPLAY_LAYER_DESC_NAME_LENGTH );


     config->flags       = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE;
     config->width       = dfb_config->mode.width  ?: shared->mode[data->layer_index].hdisplay;
     config->height      = dfb_config->mode.height ?: shared->mode[data->layer_index].vdisplay;

     config->pixelformat = dfb_config->mode.format ?: DSPF_ARGB;
     config->buffermode  = DLBM_FRONTONLY;

     direct_mutex_init( &data->lock );

     direct_waitqueue_init( &data->wq_event );

     return DFB_OK;
}
Beispiel #12
0
static DFBResult
mesaInitLayer( CoreLayer                  *layer,
               void                       *driver_data,
               void                       *layer_data,
               DFBDisplayLayerDescription *description,
               DFBDisplayLayerConfig      *config,
               DFBColorAdjustment         *adjustment )
{
     MesaData *mesa = driver_data;


     mesa->drmeventcontext.version = DRM_EVENT_CONTEXT_VERSION;
     mesa->drmeventcontext.vblank_handler = NULL;
     mesa->drmeventcontext.page_flip_handler = page_flip_handler;

     description->type             = DLTF_GRAPHICS;
     description->caps             = DLCAPS_SURFACE;
     description->surface_caps     = DSCAPS_NONE;
     description->surface_accessor = CSAID_LAYER0;

     direct_snputs( description->name, "Mesa Layer", DFB_DISPLAY_LAYER_DESC_NAME_LENGTH );


     config->flags       = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT;
     config->width       = dfb_config->mode.width  ?: mesa->mode.hdisplay;
     config->height      = dfb_config->mode.height ?: mesa->mode.vdisplay;
     config->pixelformat = dfb_config->mode.format ?: DSPF_ARGB;
     config->buffermode  = DLBM_FRONTONLY;


     direct_mutex_init( &mesa->lock );
     direct_waitqueue_init( &mesa->wq_event );
     direct_waitqueue_init( &mesa->wq_flip );

     mesa->thread = direct_thread_create( DTT_CRITICAL, Mesa_BufferThread_Main, mesa, "Mesa/Buffer" );

     return DFB_OK;
}
Beispiel #13
0
static DFBResult
drmkmsInitMixer( CoreScreen                *screen,
                 void                      *driver_data,
                 void                      *screen_data,
                 int                        mixer,
                 DFBScreenMixerDescription *description,
                 DFBScreenMixerConfig      *config )
{
     DRMKMSData *drmkms = driver_data;

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

     direct_snputs( description->name, "DRMKMS Mixer", DFB_SCREEN_ENCODER_DESC_NAME_LENGTH );

     description->caps       = DSMCAPS_FULL | DSMCAPS_SUB_LAYERS;
     description->layers     = drmkms->layer_ids[mixer];
     description->sub_layers = description->layers;

     config->flags           = DSMCONF_LAYERS;
     config->layers          = description->layers;

     return DFB_OK;
}
Beispiel #14
0
DirectResult
fusion_ref_init (FusionRef         *ref,
                 const char        *name,
                 const FusionWorld *world)
{
     FusionEntryInfo info;

     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 ? : "" );

     while (ioctl( world->fusion_fd, FUSION_REF_NEW, &ref->multi.id )) {
          if (errno == EINTR)
               continue;

          D_PERROR( "FUSION_REF_NEW" );
          return DR_FUSION;
     }

     D_DEBUG_AT( Fusion_Ref, "  -> new ref %p [%d]\n", ref, ref->multi.id );

     info.type = FT_REF;
     info.id   = ref->multi.id;

     direct_snputs( info.name, name, sizeof(info.name) );

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

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

     return DR_OK;
}
Beispiel #15
0
DirectResult
voodoo_config_set( const char *name, const char *value )
{
     if (strcmp (name, "player-name" ) == 0) {
          if (value) {
               direct_snputs( voodoo_config->play_info.name, value, VOODOO_PLAYER_NAME_LENGTH );
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "player-vendor" ) == 0) {
          if (value) {
               direct_snputs( voodoo_config->play_info.vendor, value, VOODOO_PLAYER_VENDOR_LENGTH );
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "player-model" ) == 0) {
          if (value) {
               direct_snputs( voodoo_config->play_info.model, value, VOODOO_PLAYER_MODEL_LENGTH );
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "player-uuid" ) == 0) {
          if (value) {
               sscanf( value, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
                       (unsigned int*)&voodoo_config->play_info.uuid[0], (unsigned int*)&voodoo_config->play_info.uuid[1], (unsigned int*)&voodoo_config->play_info.uuid[2], (unsigned int*)&voodoo_config->play_info.uuid[3], (unsigned int*)&voodoo_config->play_info.uuid[4],
                       (unsigned int*)&voodoo_config->play_info.uuid[5], (unsigned int*)&voodoo_config->play_info.uuid[6], (unsigned int*)&voodoo_config->play_info.uuid[7], (unsigned int*)&voodoo_config->play_info.uuid[8], (unsigned int*)&voodoo_config->play_info.uuid[9],
                       (unsigned int*)&voodoo_config->play_info.uuid[10], (unsigned int*)&voodoo_config->play_info.uuid[11], (unsigned int*)&voodoo_config->play_info.uuid[12], (unsigned int*)&voodoo_config->play_info.uuid[13], (unsigned int*)&voodoo_config->play_info.uuid[14],
                       (unsigned int*)&voodoo_config->play_info.uuid[15] );
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "proxy-memory-max" ) == 0) {
          if (value) {
               unsigned int max;

               if (direct_sscanf( value, "%u", &max ) != 1) {
                    D_ERROR( "Voodoo/Config '%s': Invalid value specified!\n", name );
                    return DR_INVARG;
               }

               voodoo_config->memory_max = max * 1024;
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "proxy-surface-max" ) == 0) {
          if (value) {
               unsigned int max;

               if (direct_sscanf( value, "%u", &max ) != 1) {
                    D_ERROR( "Voodoo/Config '%s': Invalid value specified!\n", name );
                    return DR_INVARG;
               }

               voodoo_config->surface_max = max * 1024;
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "proxy-layer-mask" ) == 0) {
          if (value) {
               unsigned int mask;

               if (direct_sscanf( value, "%u", &mask ) != 1) {
                    D_ERROR( "Voodoo/Config '%s': Invalid value specified!\n", name );
                    return DR_INVARG;
               }

               voodoo_config->layer_mask = mask;
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "proxy-stacking-mask" ) == 0) {
          if (value) {
               unsigned int mask;

               if (direct_sscanf( value, "%u", &mask ) != 1) {
                    D_ERROR( "Voodoo/Config '%s': Invalid value specified!\n", name );
                    return DR_INVARG;
               }

               voodoo_config->stacking_mask = mask;
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "proxy-resource-id" ) == 0) {
          if (value) {
               unsigned int resource_id;

               if (direct_sscanf( value, "%u", &resource_id ) != 1) {
                    D_ERROR( "Voodoo/Config '%s': Invalid value specified!\n", name );
                    return DR_INVARG;
               }

               voodoo_config->resource_id = resource_id;
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "server-fork" ) == 0) {
          voodoo_config->server_fork = true;
     } else
     if (strcmp (name, "no-server-fork" ) == 0) {
          voodoo_config->server_fork = false;
     } else
     if (strcmp (name, "server-single" ) == 0) {
          if (value) {
               if (voodoo_config->server_single)
                    D_FREE( voodoo_config->server_single );

               voodoo_config->server_single = D_STRDUP( value );
               if (!voodoo_config->server_single)
                    D_OOM();
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "play-broadcast" ) == 0) {
          if (value) {
               if (voodoo_config->play_broadcast)
                    D_FREE( voodoo_config->play_broadcast );

               voodoo_config->play_broadcast = D_STRDUP( value );
               if (!voodoo_config->play_broadcast)
                    D_OOM();
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "compression-min" ) == 0) {
          if (value) {
               unsigned int min;

               if (direct_sscanf( value, "%u", &min ) != 1) {
                    D_ERROR( "Voodoo/Config '%s': Invalid value specified!\n", name );
                    return DR_INVARG;
               }

               voodoo_config->compression_min = min;
          }
          else {
               D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
               return DR_INVARG;
          }
     } else
     if (strcmp (name, "link-raw" ) == 0) {
          voodoo_config->link_raw = true;
     } else
     if (strcmp (name, "no-link-raw" ) == 0) {
          voodoo_config->link_raw = false;
     } else
     if (strcmp (name, "link-packet" ) == 0) {
          voodoo_config->link_packet = true;
     } else
     if (strcmp (name, "no-link-packet" ) == 0) {
          voodoo_config->link_packet = false;
     } else
          return DR_UNSUPPORTED;

     return DR_OK;
}
Beispiel #16
0
static DFBResult
drmkmsInitScreen( CoreScreen           *screen,
                  CoreGraphicsDevice   *device,
                  void                 *driver_data,
                  void                 *screen_data,
                  DFBScreenDescription *description )
{
     DRMKMSData       *drmkms = driver_data;
     DRMKMSDataShared *shared = drmkms->shared;

     drmModeRes       *resources;
     drmModeConnector *connector = NULL;
     drmModeEncoder   *encoder   = NULL;
     uint32_t          crtc      = 0;

     int               i, j, k, l, found;

     description->caps = DSCCAPS_ENCODERS | DSCCAPS_OUTPUTS;
     description->encoders = 0;
     shared->enabled_crtcs = 0;

     direct_snputs( description->name, "DRMKMS Screen", DFB_SCREEN_DESC_NAME_LENGTH );

     resources = drmkms->resources;

     D_INFO( "DirectFB/DRMKMS: Got %d connectors, %d encoders\n", resources->count_connectors, resources->count_encoders );

     for (i = 0; i < resources->count_connectors; i++) {
          crtc = 0;
          connector = drmModeGetConnector( drmkms->fd, resources->connectors[i] );
          if (!connector)
               continue;

          if ((connector->connection == DRM_MODE_CONNECTED || connector->connection == DRM_MODE_UNKNOWNCONNECTION) && connector->count_modes > 0) {
               D_INFO( "DirectFB/DRMKMS: found connected connector id %d.\n", connector->connector_id );

               if (connector->encoder_id) {
                    D_INFO( "DirectFB/DRMKMS: connector %d is already bound to encoder %d.\n", connector->connector_id, connector->encoder_id );
                    encoder = drmModeGetEncoder(drmkms->fd, connector->encoder_id);
               }

               if (encoder)
                    crtc = encoder->crtc_id;

               if (crtc)
                    D_INFO( "DirectFB/DRMKMS: encoder %d is already bound to ctrc %d.\n", connector->encoder_id, encoder->crtc_id );
               else {
                    D_INFO( "DirectFB/DRMKMS: Seaching for appropriate encoder/crtc for connector %d.\n", connector->connector_id );
                    for (j = 0; j < resources->count_encoders; j++) {
                         int busy = 0;
                         encoder = drmModeGetEncoder( drmkms->fd, resources->encoders[j] );

                         if (encoder == NULL)
                              continue;

                         for (k=0; k<shared->enabled_crtcs; k++) {
                              if (drmkms->encoder[k]->encoder_id == encoder->encoder_id) {
                                   D_INFO( "DirectFB/DRMKMS: encoder %d is already in use by connector %d\n", encoder->encoder_id, drmkms->connector[k]->connector_id );
                                   busy = 1;
                              }
                         }

                         if (busy)
                              continue;

                         found = 0;
                         for (k = 0; k < resources->count_crtcs; k++) {
                              busy = 0;
                              if (!(encoder->possible_crtcs & (1 << k)))
                                   continue;

                              for (l=0; l<shared->enabled_crtcs; l++) {
                                   if (drmkms->encoder[l]->crtc_id == resources->crtcs[k])
                                        busy = 1;
                              }
                              if (busy)
                                   continue;


                              crtc = resources->crtcs[k];
                              D_INFO( "DirectFB/DRMKMS: using encoder %d and crtc %d for connector %d.\n", encoder->encoder_id, crtc, connector->connector_id );
                              found = 1;
                              break;
                         }

                         if (found)
                              break;
                    }
               }

               if (encoder && crtc) {
                    drmkms->connector[shared->enabled_crtcs] = connector;
                    drmkms->encoder[shared->enabled_crtcs] = encoder;
                    drmkms->encoder[shared->enabled_crtcs]->crtc_id = crtc;
                    shared->mode[shared->enabled_crtcs] = connector->modes[0];

                    shared->enabled_crtcs++;

                    if (!shared->multihead && !shared->mirror_outputs)
                         break;

                    if (shared->multihead && shared->enabled_crtcs > 1) {
                         dfb_layers_register( drmkms->screen, drmkms, drmkmsLayerFuncs );
                    }

               }
               else if (encoder)
                    drmModeFreeEncoder( encoder );

               encoder = NULL;
          }
          else
               drmModeFreeConnector( connector );
     }

     if (!shared->enabled_crtcs) {
          D_ERROR( "DirectFB/DRMKMS: No currently active connector found.\n");
          return DFB_INIT;
     }

     if (dfb_config->mode.width && dfb_config->mode.height) {
          drmModeModeInfo *mode  = drmkms_find_mode( 0, dfb_config->mode.width, dfb_config->mode.height, 0 );
          if (mode)
               shared->mode[0] = *mode;
     }

     if (shared->mirror_outputs || (dfb_config->mode.width && dfb_config->mode.height)) {
          for (int i=1; i<shared->enabled_crtcs; i++)
               shared->mode[i] = shared->mode[0];
     }

     if (shared->clone_outputs) {
          if (drmkms->encoder[0]->possible_clones) {
               for (i = 0; i < resources->count_crtcs; i++) {
                   if (drmkms->encoder[0]->possible_clones & (1 << i)) {
                         shared->cloned_connectors[shared->cloned_count++] = resources->connectors[0];
                         shared->cloned_connectors[shared->cloned_count++] = resources->connectors[1];
                         D_INFO( "DirectFB/DRMKMS: cloning on connector %d and %d enabled \n", resources->connectors[0], resources->connectors[1]);
                         break;
                   }
               }
               if (shared->cloned_count < 2) {
                    D_WARN( "DirectFB/DRMKMS: cloning is not possible on enough connectors, disabling.\n" );
                    shared->cloned_count = 0;
                    shared->clone_outputs = false;
               }
          }
          else {
                    D_WARN( "DirectFB/DRMKMS: cloning is not possible, disabling.\n" );
                    shared->clone_outputs = false;
          }
     }

     D_INFO( "DirectFB/DRMKMS: Default mode is %dx%d, we have %d modes in total\n", shared->mode[0].hdisplay, shared->mode[0].vdisplay, drmkms->connector[0]->count_modes );

     drmkms->resources = resources;
     drmkms->saved_crtc = drmModeGetCrtc( drmkms->fd, drmkms->encoder[0]->crtc_id );

     description->outputs   = shared->enabled_crtcs;
     description->encoders  = shared->enabled_crtcs;

     return DFB_OK;
}
Beispiel #17
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) {
            direct_snputs( shared->tmpfs, fusion_config->tmpfs, FUSION_SHM_TMPFS_PATH_NAME_LEN );
        }
        else if (!fusion_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" );
            direct_snputs( shared->tmpfs, "/dev/shm", FUSION_SHM_TMPFS_PATH_NAME_LEN );
        }

        shared->world = world->shared;

        /* Initialize shared lock. */
        ret = fusion_skirmish_init2( &shared->lock, "Fusion SHM", world, fusion_config->secure_fusion );
        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 );

        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] );
                    }

                    D_MAGIC_CLEAR( shm );

                    return ret;
                }

                num++;
            }
        }

        D_ASSERT( num == shared->num_pools );
    }

    return DR_OK;
}