Beispiel #1
0
static DFBResult
dfb_rtd_set_video_mode( CoreDFB *core, CoreLayerRegionConfig *config )
{
     int                    ret;
     CoreLayerRegionConfig *tmp = NULL;

     D_ASSERT( config != NULL );

     if (dfb_core_is_master( core ))
          return dfb_rtd_set_video_mode_handler( config );

     if (!fusion_is_shared( dfb_core_world(core), config )) {
          tmp = SHMALLOC( dfb_core_shmpool(core), sizeof(CoreLayerRegionConfig) );
          if (!tmp)
               return D_OOSHM();

          direct_memcpy( tmp, config, sizeof(CoreLayerRegionConfig) );
     }

     fusion_call_execute( &dfb_rtd->call, FCEF_NONE, RTD_SET_VIDEO_MODE,
                          tmp ? tmp : config, &ret );

     if (tmp)
          SHFREE( dfb_core_shmpool(core), tmp );

     return ret;
}
Beispiel #2
0
static DFBResult
dfb_rtd_update_screen( CoreDFB *core, DFBRegion *region )
{
     int        ret;
     DFBRegion *tmp = NULL;

     if (dfb_core_is_master( core ))
          return dfb_rtd_update_screen_handler( region );

     if (region) {
          if (!fusion_is_shared( dfb_core_world(core), region )) {
               tmp = SHMALLOC( dfb_core_shmpool(core), sizeof(DFBRegion) );
               if (!tmp)
                    return D_OOSHM();

               direct_memcpy( tmp, region, sizeof(DFBRegion) );
          }
     }

     fusion_call_execute( &dfb_rtd->call, FCEF_NONE, RTD_UPDATE_SCREEN,
                          tmp ? tmp : region, &ret );

     if (tmp)
          SHFREE( dfb_core_shmpool(core), tmp );

     return DFB_OK;
}
Beispiel #3
0
DFBResult
dfb_sdl_set_palette( CorePalette *palette )
{
     int ret;

     fusion_call_execute( &dfb_sdl->call, FCEF_NONE, SDL_SET_PALETTE, palette, &ret );

     return ret;
}
Beispiel #4
0
static DFBResult
dfb_rtd_set_palette( CorePalette *palette )
{
     int ret;

     fusion_call_execute( &dfb_rtd->call, FCEF_NONE, RTD_SET_PALETTE,
                          palette, &ret );

     return ret;
}
Beispiel #5
0
DirectResult
fusion_call_execute2(FusionCall          *call,
                     FusionCallExecFlags  flags,
                     int                  call_arg,
                     void                *ptr,
                     unsigned int         length,
                     int                 *ret_val)
{
     return fusion_call_execute( call, flags, call_arg, ptr, ret_val );
}
Beispiel #6
0
static DFBResult
dfb_x11_destroy_window( DFBX11 *x11 )
{
     int           ret;
     DFBX11Shared *shared = x11->shared;

     if (fusion_call_execute( &shared->call, FCEF_NONE, X11_DESTROY_WINDOW, NULL, &ret ))
          return DFB_FUSION;

     return ret;
}
Beispiel #7
0
static DFBResult
dfb_x11_set_palette( DFBX11 *x11, X11LayerData *lds, CorePalette *palette )
{
     int           ret;
     DFBX11Shared *shared = x11->shared;

     D_ASSERT( palette != NULL );

     if (fusion_call_execute( &shared->call, FCEF_NONE, X11_SET_PALETTE, palette, &ret ))
          return DFB_FUSION;

     return ret;
}
Beispiel #8
0
static DFBResult
dfb_x11_destroy_window( DFBX11 *x11, X11LayerData *lds )
{
     int           ret;
     DFBX11Shared *shared = x11->shared;
     DestroyData   destroy;
     
     destroy.xw = &(lds->xw);

     if (fusion_call_execute( &shared->call, FCEF_NONE, X11_DESTROY_WINDOW, &destroy, &ret ))
          return DFB_FUSION;

     return ret;
}
Beispiel #9
0
static DFBResult
dfb_x11_create_window( DFBX11 *x11, const CoreLayerRegionConfig *config )
{
     int           ret;
     DFBX11Shared *shared = x11->shared;

     D_ASSERT( config != NULL );

     shared->setmode.config = *config;

     if (fusion_call_execute( &shared->call, FCEF_NONE, X11_CREATE_WINDOW, &shared->setmode, &ret ))
          return DFB_FUSION;

     return ret;
}
Beispiel #10
0
DirectResult
_fusion_ref_change (FusionRef *ref, int add, bool global)
{
     DirectResult ret;

     D_ASSERT( ref != NULL );
     D_ASSERT( add != 0 );

     ret = fusion_skirmish_prevail( &ref->multi.builtin.lock );
     if (ret)
          return ret;
     
     if (global) {
          if (ref->multi.builtin.global+add < 0) {
               D_BUG( "ref has no global references" );
               fusion_skirmish_dismiss( &ref->multi.builtin.lock );
               return DR_BUG;
          }

          ref->multi.builtin.global += add;
     }
     else {          
          if (ref->multi.builtin.local+add < 0) {
               D_BUG( "ref has no local references" );
               fusion_skirmish_dismiss( &ref->multi.builtin.lock );
               return DR_BUG;
          }

          ref->multi.builtin.local += add;
          
          _fusion_add_local( _fusion_world(ref->multi.shared), ref, add ); 
     }

     if (ref->multi.builtin.local+ref->multi.builtin.global == 0) {
          fusion_skirmish_notify( &ref->multi.builtin.lock );

          if (ref->multi.builtin.call) {
               fusion_skirmish_dismiss( &ref->multi.builtin.lock );
               return fusion_call_execute( ref->multi.builtin.call, FCEF_ONEWAY, 
                                           ref->multi.builtin.call_arg, NULL, NULL );
          }
     }
     
     fusion_skirmish_dismiss( &ref->multi.builtin.lock );

     return DR_OK;
}
Beispiel #11
0
DFBResult
x11ImageDestroy( x11Image *image )
{
    int ret;

    D_MAGIC_ASSERT( image, x11Image );

    if (fusion_call_execute( &dfb_x11->call, FCEF_NONE, X11_IMAGE_DESTROY, image, &ret ))
        return DFB_FUSION;

    if (ret) {
        D_DERROR( ret, "X11/Image: X11_IMAGE_DESTROY call failed!\n" );
        return ret;
    }

    D_MAGIC_CLEAR( image );

    return DFB_OK;
}
Beispiel #12
0
DFBResult x11ImageInit( DFBX11                *x11,
                        x11Image              *image,
                        int                    width,
                        int                    height,
                        DFBSurfacePixelFormat  format )
{
     int           ret;
     Visual       *visual;
     DFBX11Shared *shared = x11->shared;

     if (!x11->use_shm)
          return DFB_UNSUPPORTED;

     /* Lookup visual. */
     visual = x11->visuals[DFB_PIXELFORMAT_INDEX(format)];
     if (!visual)
          return DFB_UNSUPPORTED;

     /* For probing. */
     if (!image)
          return DFB_OK;

     image->width  = width;
     image->height = height;
     image->format = format;
     image->depth  = DFB_COLOR_BITS_PER_PIXEL( format );

     D_MAGIC_SET( image, x11Image );

     if (fusion_call_execute( &shared->call, FCEF_NONE, X11_IMAGE_INIT, image, &ret )) {
          D_MAGIC_CLEAR( image );
          return DFB_FUSION;
     }

     if (ret) {
          D_DERROR( ret, "X11/Image: X11_IMAGE_INIT call failed!\n" );
          D_MAGIC_CLEAR( image );
          return ret;
     }

     return DFB_OK;
}
Beispiel #13
0
static DFBResult
dfb_x11_update_screen( DFBX11 *x11, const DFBRegion *region, CoreSurfaceBufferLock *lock )
{
     int           ret;
     DFBX11Shared *shared = x11->shared;

     DFB_REGION_ASSERT( region );
     D_ASSERT( lock != NULL );

     /* FIXME: Just a hot fix! */
     while (shared->update.lock)
          usleep( 10000 );

     shared->update.region = *region;
     shared->update.lock   = lock;

     if (fusion_call_execute( &shared->call, FCEF_NONE, X11_UPDATE_SCREEN, &shared->update, &ret ))
          return DFB_FUSION;

     return ret;
}
Beispiel #14
0
DirectResult
fusion_ref_down (FusionRef *ref, bool global)
{
     D_ASSERT( ref != NULL );

     direct_mutex_lock (&ref->single.lock);

     if (!ref->single.refs) {
          D_BUG( "no more references" );
          direct_mutex_unlock (&ref->single.lock);
          return DR_BUG;
     }

     if (ref->single.destroyed) {
          direct_mutex_unlock (&ref->single.lock);
          return DR_DESTROYED;
     }

     if (! --ref->single.refs) {
          if (ref->single.call) {
               FusionCall *call = ref->single.call;

               if (call->handler) {
                    fusion_call_execute( call, FCEF_NODIRECT | FCEF_ONEWAY, ref->single.call_arg, NULL, NULL );

                    direct_mutex_unlock( &ref->single.lock );

                    return DR_OK;
               }
          }
          else
               direct_waitqueue_broadcast (&ref->single.cond);
     }

     direct_mutex_unlock (&ref->single.lock);

     return DR_OK;
}
Beispiel #15
0
int
main( int argc, char *argv[] )
{
     DirectResult         ret;
     FusionWorld         *world;
     FusionCall           call = {0};
     FusionSHMPoolShared *pool;
     void                *buffer;
     int           i, max_busy = 0, active = 1;
     long long     t1 = 0, t2;
     long long     start       = 0;
     long long     bytes       = 0;
     long long     last_bytes  = 0;
     unsigned long blocks      = 0;
     unsigned long last_blocks = 0;
     unsigned long last_busy   = 0;
     u32           checksum    = 0;
     bool          produce     = true;
     int           delay       = 66000;

     if (parse_cmdline( argc, argv ))
          return -1;

     if (bit_rate) {
          int blocks_per_sec = (bit_rate * 1024 / 8) / block_size;

          if (blocks_per_sec < 100)
               delay = 900000 / blocks_per_sec - 2000;
          else
               delay = 300000 * 100 / blocks_per_sec;

          num_blocks = bit_rate * 1024 / 8 / block_size * delay / 900000;

          if (num_blocks > MAX_NUM_BLOCKS)
               num_blocks = MAX_NUM_BLOCKS;

          if (!num_blocks) {
               num_blocks = 1;
               delay = 970 * block_size / (bit_rate * 1024 / 8) * 1000 - 2000;
          }
     }

     sync();

     if (run_busy) {
          pthread_create( &busy_thread, NULL, busy_loop, NULL );

          printf( "Calibrating...\n" );
     
          pthread_mutex_lock( &busy_lock );
     
          for (i=0; i<7; i++) {
               int busy_rate;
     
               busy_count = 0;
     
               t1 = get_millis();
               pthread_mutex_unlock( &busy_lock );
     
               usleep( 300000 );
     
               pthread_mutex_lock( &busy_lock );
               t2 = get_millis();
     
               busy_rate = busy_count * 1000 / (t2 - t1);
     
               if (busy_rate > max_busy)
                    max_busy = busy_rate;
          }
     
          printf( "Calibrating done. (%d busy counts/sec)\n", max_busy );
     }

     ret = fusion_enter( -1, 23, FER_MASTER, &world );
     if (ret)
          return ret;

     ret = fusion_call_init( &call, call_handler, NULL, world );
     if (ret)
          return ret;

     ret = fusion_shm_pool_create( world, "Stream Buffer", block_size + 8192, false, &pool );
     if (ret)
          return ret;

     ret = fusion_shm_pool_allocate( pool, block_size, false, true, &buffer );
     if (ret)
          return ret;



     /*
      * Do the fork() magic!
      */
     if (do_fork) {
          fusion_world_set_fork_action( world, FFA_FORK );

          switch (fork()) {
               case -1:
                    D_PERROR( "fork() failed!\n" );
                    return -1;

               case 0:
                    /* child continues as the producer */
                    run_busy = false;
                    break;

               default:
                    /* parent is the consumer (callback in Fusion Dispatch thread) */
                    produce = false;

                    usleep( 50000 );
          }

          fusion_world_set_fork_action( world, FFA_CLOSE );
     }


     start = t1 = get_millis();

     if (run_busy) {
          busy_count = 0;
          pthread_mutex_unlock( &busy_lock );
     }

#ifdef LINUX_2_4
     delay -= 10000;
#endif

     do {
          if (bit_rate || !produce) {
               if (delay > 10)
                    usleep( delay );
          }

          if (produce) {
               for (i=0; i<num_blocks; i++) {
                    int  n;
                    u32  retsum;
                    u32 *values = buffer;

                    for (n=0; n<block_size/4; n++) {
                         values[n] = n;
                         checksum += n;
                    }

                    bytes += block_size;

                    fusion_call_execute( &call, do_thread ? FCEF_NODIRECT : FCEF_NONE,
                                         0, buffer, (int*) &retsum );

                    if (retsum != checksum)
                         D_ERROR( "Checksum returned by consumer (0x%08x) does not match 0x%08x!\n", retsum, checksum );
               }

               blocks += num_blocks;
          }


          t2 = get_millis();
          if (t2 - t1 > 2000) {
               if (produce) {
                    long long kbits = 0, avgkbits, total_time, diff_time, diff_bytes;

                    printf( "\n\n\n" );

                    total_time = t2 - start;
                    diff_time  = t2 - t1;
                    diff_bytes = bytes - last_bytes;

                    avgkbits   = (long long)bytes * 8LL * 1000LL / (long long)total_time / 1024LL;

                    if (diff_time)
                         kbits = (long long)diff_bytes * 8LL * 1000LL / (long long)diff_time / 1024LL;

                    printf( "Total Time:       %7lld ms\n", total_time );
                    printf( "Stream Size:      %7lld kb\n", bytes / 1024 );
                    printf( "Stream Rate:      %7lld kb/sec -> %lld.%03lld MBit (avg. %lld.%03lld MBit)\n",
                            kbits / 8,
                            (kbits * 1000 / 1024) / 1000, (kbits * 1000 / 1024) % 1000,
                            (avgkbits * 1000 / 1024) / 1000, (avgkbits * 1000 / 1024) % 1000 );
                    printf( "\n" );


                    if (last_bytes && bit_rate) {
                         long long diff_bytes = (bytes - last_bytes) * 1000 / (t2 - t1);
                         long long need_bytes = bit_rate * 1024 / 8;

                         if (diff_bytes) {
                              int new_blocks = (num_blocks * need_bytes + diff_bytes/2) / diff_bytes;

                              num_blocks = (new_blocks + num_blocks + 1) / 2;

                              if (num_blocks > MAX_NUM_BLOCKS)
                                   num_blocks = MAX_NUM_BLOCKS;
                         }
                    }


                    read_stat();

                    if (ftotal != ctotal && dtotal) {
                         int load, aload;

                         load  = 1000 - didle * 1000 / dtotal;
                         aload = 1000 - (cidle - fidle) * 1000 / (ctotal - ftotal);

                         printf( "Overall Stats\n" );
                         printf( "  Total Time:      %7lld ms\n", t2 - start );
                         printf( "  Block Size:      %7ld\n", block_size );
                         printf( "  Blocks/cycle:    %7ld\n", num_blocks );
                         printf( "  Blocks/second:   %7lld\n", (blocks - last_blocks) * 1000 / diff_time );
                         printf( "  Delay:           %7d\n", delay );
                         printf( "  CPU Load:        %5d.%d %% (avg. %d.%d %%)\n",
                                 load / 10, load % 10, aload / 10, aload % 10 );
                    }


                    last_bytes  = bytes;
                    last_blocks = blocks;
               }

               if (run_busy) {
                    pthread_mutex_lock( &busy_lock );

                    if (last_busy) {
                         int busy_diff;
                         int busy_rate, busy_load;
                         int abusy_rate, abusy_load;

                         busy_diff = busy_count - last_busy;
                         busy_rate = max_busy - (busy_diff * 1000 / (t2 - t1));
                         busy_load = busy_rate * 1000 / max_busy;
                         abusy_rate = max_busy - (busy_count * 1000 / (t2 - start));
                         abusy_load = abusy_rate * 1000 / max_busy;

                         printf( "  Real CPU Load:   %5d.%d %% (avg. %d.%d %%)\n",
                                 busy_load / 10, busy_load % 10,
                                 abusy_load / 10, abusy_load % 10 );
                    }

                    last_busy = busy_count;

                    pthread_mutex_unlock( &busy_lock );
               }

               t1 = t2;
          }
     } while (active > 0);


     if (run_busy) {
          busy_alive = 0;

          pthread_join( busy_thread, NULL );
     }

     return -1;
}