static DirectResult fusion_hash_create_internal (bool local,FusionSHMPoolShared *pool, FusionHashType key_type, FusionHashType value_type, int size, FusionHash **ret_hash ) { FusionHash *hash; if (!ret_hash) return DFB_BUG; if (!local && !pool) return DFB_BUG; if (size < FUSION_HASH_MIN_SIZE) size = FUSION_HASH_MIN_SIZE; if (local) hash = D_CALLOC(1, sizeof (FusionHash) ); else hash = SHCALLOC(pool, 1, sizeof (FusionHash) ); if (!hash) return local ?DFB_NOSYSTEMMEMORY:DFB_NOSHAREDMEMORY; hash->local = local; hash->pool = pool; hash->key_type = key_type; hash->value_type = value_type; hash->size = size; hash->nnodes = 0; if (local) hash->nodes = D_CALLOC(size,sizeof (FusionHashNode*) ); else hash->nodes = SHCALLOC(pool, size, sizeof(FusionHashNode*) ); if (!hash->nodes) { if (local) D_FREE(hash ); else SHFREE(pool, hash ); return local?DFB_NOSYSTEMMEMORY:DFB_NOSHAREDMEMORY; } D_MAGIC_SET(hash, FusionHash ); *ret_hash = hash; return DFB_OK; }
DFBResult dfb_palette_create( CoreDFB *core, unsigned int size, CorePalette **ret_palette ) { CorePalette *palette; D_DEBUG_AT( Core_Palette, "%s( %d )\n", __FUNCTION__, size ); D_ASSERT( ret_palette ); palette = dfb_core_create_palette( core ); if (!palette) return DFB_FUSION; palette->shmpool = dfb_core_shmpool( core ); if (size) { palette->entries = SHCALLOC( palette->shmpool, size, sizeof(DFBColor) ); if (!palette->entries) { fusion_object_destroy( &palette->object ); return D_OOSHM(); } palette->entries_yuv = SHCALLOC( palette->shmpool, size, sizeof(DFBColorYUV) ); if (!palette->entries_yuv) { SHFREE( palette->shmpool, palette->entries ); fusion_object_destroy( &palette->object ); return D_OOSHM(); } } palette->num_entries = size; /* reset cache */ palette->search_cache.index = -1; D_MAGIC_SET( palette, CorePalette ); /* activate object */ fusion_object_activate( &palette->object ); /* return the new palette */ *ret_palette = palette; D_DEBUG_AT( Core_Palette, " -> %p\n", palette ); return DFB_OK; }
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; }
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; }
void dfb_colorhash_attach( DFBColorHashCore *core, CorePalette *palette ) { DFBColorHashCoreShared *shared; D_ASSUME( core != NULL ); if (core) { D_MAGIC_ASSERT( core, DFBColorHashCore ); D_MAGIC_ASSERT( core->shared, DFBColorHashCoreShared ); } else core = core_colorhash; shared = core->shared; fusion_skirmish_prevail( &shared->hash_lock ); if (!shared->hash) { D_ASSERT( shared->hash_users == 0 ); shared->hash = SHCALLOC( shared->shmpool, HASH_SIZE, sizeof (Colorhash) ); } shared->hash_users++; fusion_skirmish_dismiss( &shared->hash_lock ); }
/** * fusion_hash_insert: * @hash: a #FusionHash. * @key: a key to insert. * @value: the value to associate with the key. * * Inserts a new key and value into a #FusionHash. * If the key already exists in the #FusionHash DFB_BUG is returned * If you think a key may exist you should call fusion_hash_replace * Generally this is only used on a new FusionHash **/ DirectResult fusion_hash_insert( FusionHash *hash, void *key, void *value ) { FusionHashNode **node; D_MAGIC_ASSERT( hash, FusionHash ); node = fusion_hash_lookup_node (hash, key); if (*node) { D_BUG( "key already exists" ); return DFB_BUG; } else { if (hash->local) (*node) = D_CALLOC(1,sizeof(FusionHashNode)); else (*node) = SHCALLOC(hash->pool, 1, sizeof(FusionHashNode)); if ( !(*node) ) return hash->local?DFB_NOSYSTEMMEMORY:DFB_NOSHAREDMEMORY; (*node)->key = key; (*node)->value = value; hash->nnodes++; if ( fusion_hash_should_resize(hash) ) fusion_hash_resize(hash); } return DFB_OK; }
static Chunk* split_chunk( Chunk *c, int length ) { Chunk *newchunk; D_MAGIC_ASSERT( c, _Chunk_ ); if (c->length == length) /* does not need be splitted */ return c; newchunk = (Chunk*) SHCALLOC( 1, sizeof(Chunk) ); /* calculate offsets and lengths of resulting chunks */ newchunk->offset = c->offset + c->length - length; newchunk->length = length; c->length -= newchunk->length; /* insert newchunk after chunk c */ newchunk->prev = c; newchunk->next = c->next; if (c->next) c->next->prev = newchunk; c->next = newchunk; D_MAGIC_SET( newchunk, _Chunk_ ); return newchunk; }
static DFBResult init_bridge( CoreDFB *core, CoreSurfacePoolBridge *bridge, const SurfacePoolBridgeFuncs *funcs, void *context ) { DFBResult ret; D_MAGIC_ASSERT( bridge, CoreSurfacePoolBridge ); D_ASSERT( funcs != NULL ); D_ASSERT( funcs->InitPoolBridge != NULL ); D_DEBUG_AT( Core_SurfPoolBridge, "%s( %p, %p )\n", __FUNCTION__, bridge, funcs ); if (funcs->PoolBridgeDataSize) bridge->bridge_data_size = funcs->PoolBridgeDataSize(); if (funcs->PoolBridgeLocalDataSize) bridge->bridge_local_data_size = funcs->PoolBridgeLocalDataSize(); if (funcs->PoolTransferDataSize) bridge->transfer_data_size = funcs->PoolTransferDataSize(); /* Allocate shared bridge data. */ if (bridge->bridge_data_size) { bridge->data = SHCALLOC( bridge->shmpool, 1, bridge->bridge_data_size ); if (!bridge->data) return D_OOSHM(); } /* Allocate local bridge data. */ if (bridge->bridge_local_data_size && !(bridge_locals[bridge->bridge_id] = D_CALLOC( 1, bridge->bridge_local_data_size ))) { SHFREE( bridge->shmpool, bridge->data ); return D_OOM(); } ret = funcs->InitPoolBridge( core, bridge, bridge->data, get_local(bridge), context, &bridge->desc ); if (ret) { D_DERROR( ret, "Core/SurfacePoolBridge: Initializing '%s' failed!\n", bridge->desc.name ); if (bridge_locals[bridge->bridge_id]) { D_FREE( bridge_locals[bridge->bridge_id] ); bridge_locals[bridge->bridge_id] = NULL; } if (bridge->data) { SHFREE( bridge->shmpool, bridge->data ); bridge->data = NULL; } return ret; } fusion_skirmish_init2( &bridge->lock, bridge->desc.name, dfb_core_world(core), fusion_config->secure_fusion ); return DFB_OK; }
static DFBResult system_initialize( CoreDFB *core, void **ret_data ) { DFBResult ret; MesaData *mesa; MesaDataShared *shared; FusionSHMPoolShared *pool; D_ASSERT( m_data == NULL ); mesa = D_CALLOC( 1, sizeof(MesaData) ); if (!mesa) return D_OOM(); mesa->core = core; pool = dfb_core_shmpool( core ); shared = SHCALLOC( pool, 1, sizeof(MesaDataShared) ); if (!shared) { D_FREE( mesa ); return D_OOSHM(); } shared->shmpool = pool; mesa->shared = shared; m_data = mesa; if (dfb_config->vt) { ret = dfb_vt_initialize(); if (ret) return DFB_INIT; } ret = InitLocal( mesa ); if (ret) { if (dfb_config->vt) dfb_vt_shutdown( false ); return ret; } *ret_data = m_data; dfb_surface_pool_initialize( core, &mesaSurfacePoolFuncs, &shared->pool ); mesa->screen = dfb_screens_register( NULL, mesa, mesaScreenFuncs ); mesa->layer = dfb_layers_register( mesa->screen, mesa, mesaLayerFuncs ); core_arena_add_shared_field( core, "mesa", shared ); return DFB_OK; }
static DFBResult system_initialize( CoreDFB *core, void **ret_data ) { DFBResult ret; DevMemData *data; DevMemDataShared *shared; FusionSHMPoolShared *pool; D_ASSERT( m_data == NULL ); if (!dfb_config->video_phys || !dfb_config->video_length) { D_ERROR( "System/DevMem: Please supply 'video-phys = 0xXXXXXXXX' and 'video-length = XXXX' options!\n" ); return DFB_INVARG; } if (dfb_config->mmio_phys && !dfb_config->mmio_length) { D_ERROR( "System/DevMem: Please supply both 'mmio-phys = 0xXXXXXXXX' and 'mmio-length = XXXX' options or none!\n" ); return DFB_INVARG; } data = D_CALLOC( 1, sizeof(DevMemData) ); if (!data) return D_OOM(); pool = dfb_core_shmpool( core ); shared = SHCALLOC( pool, 1, sizeof(DevMemDataShared) ); if (!shared) { D_FREE( data ); return D_OOSHM(); } shared->shmpool = pool; data->shared = shared; ret = MapMemAndReg( data, dfb_config->video_phys, dfb_config->video_length, dfb_config->mmio_phys, dfb_config->mmio_length ); if (ret) { SHFREE( pool, shared ); D_FREE( data ); return ret; } *ret_data = m_data = data; dfb_surface_pool_initialize( core, &devmemSurfacePoolFuncs, &shared->pool ); fusion_arena_add_shared_field( dfb_core_arena( core ), "devmem", shared ); return DFB_OK; }
static DFBResult system_initialize( CoreDFB *core, void **ret_data ) { DFBResult ret; PVR2DData *data; PVR2DDataShared *shared; FusionSHMPoolShared *pool; D_ASSERT( m_data == NULL ); data = D_CALLOC( 1, sizeof(PVR2DData) ); if (!data) return D_OOM(); data->core = core; pool = dfb_core_shmpool( core ); shared = SHCALLOC( pool, 1, sizeof(PVR2DDataShared) ); if (!shared) { D_FREE( data ); return D_OOSHM(); } shared->shmpool = pool; data->shared = shared; ret = InitPVR2D( data ); if (ret) { SHFREE( pool, shared ); D_FREE( data ); return ret; } ret = InitEGL( data ); if (ret) { SHFREE( pool, shared ); D_FREE( data ); return ret; } *ret_data = m_data = data; data->screen = dfb_screens_register( NULL, data, pvr2dPrimaryScreenFuncs ); data->layer = dfb_layers_register( data->screen, data, pvr2dPrimaryLayerFuncs ); dfb_surface_pool_initialize( core, pvr2dSurfacePoolFuncs, &shared->pool ); fusion_arena_add_shared_field( dfb_core_arena( core ), "pvr2d", shared ); return DFB_OK; }
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; }
DFBResult dfb_core_part_initialize( CoreDFB *core, CorePart *core_part ) { DFBResult ret; void *local = NULL; void *shared = NULL; FusionSHMPoolShared *pool; pool = dfb_core_shmpool( core ); if (core_part->initialized) { D_BUG( "%s already initialized", core_part->name ); return DFB_BUG; } D_DEBUG_AT( Core_Parts, "Going to initialize '%s' core...\n", core_part->name ); if (core_part->size_local) local = D_CALLOC( 1, core_part->size_local ); if (core_part->size_shared) shared = SHCALLOC( pool, 1, core_part->size_shared ); D_INFO("Going to initialize '%s' core...\n", core_part->name ); ret = core_part->Initialize( core, local, shared ); D_INFO("Core '%s' initialized ...\n", core_part->name ); if (ret) { D_ERROR( "DirectFB/Core: Could not initialize '%s' core!\n" " --> %s\n", core_part->name, DirectFBErrorString( ret ) ); if (shared) SHFREE( pool, shared ); if (local) D_FREE( local ); return ret; } if (shared) fusion_arena_add_shared_field( dfb_core_arena( core ), core_part->name, shared ); core_part->data_local = local; core_part->data_shared = shared; core_part->initialized = true; return DFB_OK; }
/** * hash_replace: * @hash: a #FusionHash. * @key: a key to insert. * @value: the value to associate with the key. * * Inserts a new key and value into a #FusionHash similar to * hash_insert(). The difference is that if the key already exists * in the #FusionHash, it gets replaced by the new key. * If you supplied a oldkey pointer or oldkey value they are returned * otherwise free is called the key if table type is not type HASH_INT * and free is called on the old value if not supplied **/ DirectResult fusion_hash_replace (FusionHash *hash, void * key, void * value, void **old_key, void **old_value) { FusionHashNode **node; D_MAGIC_ASSERT( hash, FusionHash ); node = fusion_hash_lookup_node (hash, key); if (*node) { if ( old_key) *old_key = (*node)->key; else if ( hash->key_type != HASH_INT ) { if (hash->free_keys) { if (hash->local) D_FREE((*node)->key); else SHFREE(hash->pool, (*node)->key ); } } if ( old_value) *old_value = (*node)->value; else if ( hash->value_type != HASH_INT ) { if (hash->free_values) { if (hash->local) D_FREE((*node)->value); else SHFREE(hash->pool, (*node)->value ); } } } else { if (hash->local) *node = D_CALLOC(1, sizeof(FusionHashNode)); else *node = SHCALLOC(hash->pool, 1, sizeof(FusionHashNode)); if ( !(*node) ) return hash->local?DFB_NOSYSTEMMEMORY:DFB_NOSHAREDMEMORY; hash->nnodes++; } (*node)->key = (void*)key; (*node)->value = (void*)value; return DFB_OK; }
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; }
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; }
/* Hash Functions * Resize the hash to minumim for this number of entries */ DirectResult fusion_hash_resize (FusionHash *hash) { FusionHashNode **new_nodes; FusionHashNode *node; FusionHashNode *next; unsigned int hash_val; int new_size; int i; D_MAGIC_ASSERT( hash, FusionHash ); new_size = spaced_primes_closest (hash->nnodes); if (new_size > FUSION_HASH_MAX_SIZE ) new_size = FUSION_HASH_MAX_SIZE; if (new_size < FUSION_HASH_MIN_SIZE) new_size = FUSION_HASH_MIN_SIZE; if (hash->local) new_nodes = D_CALLOC (new_size, sizeof(FusionHashNode*)); else new_nodes = SHCALLOC (hash->pool, new_size, sizeof(FusionHashNode*)); if (!new_nodes) return hash->local?DFB_NOSYSTEMMEMORY:DFB_NOSHAREDMEMORY; for (i = 0; i < hash->size; i++) for (node = hash->nodes[i]; node; node = next) { next = node->next; /*TODO We could also optimize pointer hashing*/ if (hash->key_type == HASH_STRING ) { unsigned int h; const signed char *p = node->key; HASH_STR(h, p) hash_val = h % new_size; } else hash_val = ((unsigned long)node->key) % new_size; node->next = new_nodes[hash_val]; new_nodes[hash_val] = node; } if (hash->local) D_FREE(hash->nodes); else SHFREE(hash->pool, hash->nodes); hash->nodes = new_nodes; hash->size = new_size; return true; }
static DFBResult system_initialize( CoreDFB *core, void **ret_data ) { DFBResult ret; AndroidData *android; AndroidDataShared *shared; FusionSHMPoolShared *pool; D_ASSERT( m_data == NULL ); android = D_CALLOC( 1, sizeof(AndroidData) ); if (!android) return D_OOM(); android->core = core; pool = dfb_core_shmpool( core ); shared = SHCALLOC( pool, 1, sizeof(AndroidDataShared) ); if (!shared) { D_FREE( android ); return D_OOSHM(); } shared->shmpool = pool; android->shared = shared; m_data = android; ret = InitLocal( android ); if (ret) return ret; *ret_data = m_data; dfb_surface_pool_initialize( core, &androidSurfacePoolFuncs, &shared->pool ); android->screen = dfb_screens_register( NULL, android, androidScreenFuncs ); android->layer = dfb_layers_register( android->screen, android, androidLayerFuncs ); android->java_vm = native_data.app->activity->vm; android->app_path = D_STRDUP( native_data.app->activity->internalDataPath) ; core_arena_add_shared_field( core, "android", shared ); return DFB_OK; }
static DFBResult x11Lock( CoreSurfacePool *pool, void *pool_data, void *pool_local, CoreSurfaceAllocation *allocation, void *alloc_data, CoreSurfaceBufferLock *lock ) { DFBResult ret; x11PoolLocalData *local = pool_local; x11AllocationData *alloc = alloc_data; DFBX11 *x11 = local->x11; DFBX11Shared *shared = x11->shared; CoreSurfaceBuffer *buffer; CoreSurface *surface; D_DEBUG_AT( X11_Surfaces, "%s( %p )\n", __FUNCTION__, allocation ); D_MAGIC_ASSERT( pool, CoreSurfacePool ); D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation ); D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock ); buffer = allocation->buffer; D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer ); surface = buffer->surface; D_MAGIC_ASSERT( surface, CoreSurface ); D_ASSERT( local->hash != NULL ); pthread_mutex_lock( &local->lock ); if (!alloc->ptr) { alloc->ptr = SHCALLOC( shared->data_shmpool, 1, allocation->size ); if (!alloc->ptr) return D_OOSHM(); } lock->addr = alloc->ptr; lock->pitch = alloc->pitch; pthread_mutex_unlock( &local->lock ); return DFB_OK; }
static DFBResult allocate_transfer( CoreSurfacePoolBridge *bridge, CoreSurfaceBuffer *buffer, CoreSurfaceAllocation *from, CoreSurfaceAllocation *to, const DFBRectangle *rects, unsigned int num_rects, CoreSurfacePoolTransfer **ret_transfer ) { CoreSurfacePoolTransfer *transfer; unsigned int alloc_size; D_MAGIC_ASSERT( bridge, CoreSurfacePoolBridge ); D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer ); CORE_SURFACE_ALLOCATION_ASSERT( from ); CORE_SURFACE_ALLOCATION_ASSERT( to ); D_ASSERT( rects != NULL ); D_ASSERT( num_rects > 0 ); D_ASSERT( ret_transfer != NULL ); alloc_size = sizeof(CoreSurfacePoolTransfer) + num_rects * sizeof(DFBRectangle) + bridge->transfer_data_size; transfer = SHCALLOC( bridge->shmpool, 1, alloc_size ); if (!transfer) return D_OOSHM(); transfer->bridge = bridge; transfer->buffer = buffer; transfer->from = from; transfer->to = to; transfer->rects = (DFBRectangle*)(transfer + 1); if (bridge->transfer_data_size) transfer->data = transfer->rects + num_rects; transfer->num_rects = num_rects; direct_memcpy( transfer->rects, rects, num_rects * sizeof(DFBRectangle) ); D_MAGIC_SET( transfer, CoreSurfacePoolTransfer ); *ret_transfer = transfer; return DFB_OK; }
DFBResult dfb_surface_pool_bridge_initialize( CoreDFB *core, const SurfacePoolBridgeFuncs *funcs, void *context, CoreSurfacePoolBridge **ret_bridge ) { DFBResult ret; CoreSurfacePoolBridge *bridge; FusionSHMPoolShared *shmpool; D_DEBUG_AT( Core_SurfPoolBridge, "%s( %p, %p )\n", __FUNCTION__, funcs, context ); D_ASSERT( core != NULL ); D_ASSERT( funcs != NULL ); D_ASSERT( ret_bridge != NULL ); /* Check against bridge limit. */ if (bridge_count == MAX_SURFACE_POOL_BRIDGES) { D_ERROR( "Core/SurfacePoolBridge: Maximum number of bridges (%d) reached!\n", MAX_SURFACE_POOL_BRIDGES ); return DFB_LIMITEXCEEDED; } D_ASSERT( bridge_funcs[bridge_count] == NULL ); shmpool = dfb_core_shmpool( core ); /* Allocate bridge structure. */ bridge = SHCALLOC( shmpool, 1, sizeof(CoreSurfacePoolBridge) ); if (!bridge) return D_OOSHM(); /* Assign a bridge ID. */ bridge->bridge_id = bridge_count++; /* Remember shared memory pool. */ bridge->shmpool = shmpool; /* Set function table of the bridge. */ bridge_funcs[bridge->bridge_id] = funcs; /* Add to global bridge list. */ bridge_array[bridge->bridge_id] = bridge; D_MAGIC_SET( bridge, CoreSurfacePoolBridge ); ret = init_bridge( core, bridge, funcs, context ); if (ret) { bridge_funcs[bridge->bridge_id] = NULL; bridge_array[bridge->bridge_id] = NULL; bridge_count--; D_MAGIC_CLEAR( bridge ); SHFREE( shmpool, bridge ); return ret; } /* Insert new bridge into priority order */ insert_bridge_local( bridge ); /* Return the new bridge. */ *ret_bridge = bridge; return DFB_OK; }
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; }
static DFBResult x11Lock( CoreSurfacePool *pool, void *pool_data, void *pool_local, CoreSurfaceAllocation *allocation, void *alloc_data, CoreSurfaceBufferLock *lock ) { DFBResult ret; x11PoolLocalData *local = pool_local; x11AllocationData *alloc = alloc_data; DFBX11 *x11 = local->x11; DFBX11Shared *shared = x11->shared; D_DEBUG_AT( X11_Surfaces, "%s( %p )\n", __FUNCTION__, allocation ); D_MAGIC_ASSERT( pool, CoreSurfacePool ); D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation ); D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock ); D_ASSERT( local->hash != NULL ); pthread_mutex_lock( &local->lock ); if (alloc->real) { void *addr = direct_hash_lookup( local->hash, alloc->image.seginfo.shmid ); if (!addr) { ret = x11ImageAttach( &alloc->image, &addr ); if (ret) { D_DERROR( ret, "X11/Surfaces: x11ImageAttach() failed!\n" ); pthread_mutex_unlock( &local->lock ); return ret; } direct_hash_insert( local->hash, alloc->image.seginfo.shmid, addr ); /* FIXME: When to remove/detach? */ } lock->addr = addr; lock->handle = &alloc->image; } else { if (!alloc->ptr) { D_DEBUG_AT( X11_Surfaces, " -> allocating memory in data_shmpool (%d bytes)\n", allocation->size ); alloc->ptr = SHCALLOC( shared->data_shmpool, 1, allocation->size ); if (!alloc->ptr) { pthread_mutex_unlock( &local->lock ); return D_OOSHM(); } } lock->addr = alloc->ptr; } lock->pitch = alloc->pitch; pthread_mutex_unlock( &local->lock ); return DFB_OK; }
/* * parses video modes in /etc/fb.modes and stores them in dfb_fbdev->shared->modes * (to be replaced by DirectFB's own config system */ static DFBResult dfb_fbdev_read_modes( void ) { FILE *fp; char line[80],label[32],value[16]; int geometry=0, timings=0; int dummy; VideoMode temp_mode; VideoMode *m = dfb_sdl->modes; if (!(fp = fopen("/etc/fb.modes","r"))) return errno2result( errno ); while (fgets(line,79,fp)) { if (sscanf(line, "mode \"%31[^\"]\"",label) == 1) { memset( &temp_mode, 0, sizeof(VideoMode) ); geometry = 0; timings = 0; while (fgets(line,79,fp) && !(strstr(line,"endmode"))) { if (5 == sscanf(line," geometry %d %d %d %d %d", &temp_mode.xres, &temp_mode.yres, &dummy, &dummy, &temp_mode.bpp)) { geometry = 1; } else if (7 == sscanf(line," timings %d %d %d %d %d %d %d", &temp_mode.pixclock, &temp_mode.left_margin, &temp_mode.right_margin, &temp_mode.upper_margin, &temp_mode.lower_margin, &temp_mode.hsync_len, &temp_mode.vsync_len)) { timings = 1; } else if (1 == sscanf(line, " hsync %15s",value) && 0 == strcasecmp(value,"high")) { temp_mode.hsync_high = 1; } else if (1 == sscanf(line, " vsync %15s",value) && 0 == strcasecmp(value,"high")) { temp_mode.vsync_high = 1; } else if (1 == sscanf(line, " csync %15s",value) && 0 == strcasecmp(value,"high")) { temp_mode.csync_high = 1; } else if (1 == sscanf(line, " laced %15s",value) && 0 == strcasecmp(value,"true")) { temp_mode.laced = 1; } else if (1 == sscanf(line, " double %15s",value) && 0 == strcasecmp(value,"true")) { temp_mode.doubled = 1; } else if (1 == sscanf(line, " gsync %15s",value) && 0 == strcasecmp(value,"true")) { temp_mode.sync_on_green = 1; } else if (1 == sscanf(line, " extsync %15s",value) && 0 == strcasecmp(value,"true")) { temp_mode.external_sync = 1; } else if (1 == sscanf(line, " bcast %15s",value) && 0 == strcasecmp(value,"true")) { temp_mode.broadcast = 1; } } if (geometry && timings) { if (!m) { dfb_sdl->modes = SHCALLOC( dfb_core_shmpool(dfb_sdl_core), 1, sizeof(VideoMode) ); m = dfb_sdl->modes; } else { m->next = SHCALLOC( dfb_core_shmpool(dfb_sdl_core), 1, sizeof(VideoMode) ); m = m->next; } direct_memcpy (m, &temp_mode, sizeof(VideoMode)); D_DEBUG( "DirectFB/FBDev: %20s %4dx%4d %s%s\n", label, temp_mode.xres, temp_mode.yres, temp_mode.laced ? "interlaced " : "", temp_mode.doubled ? "doublescan" : "" ); } } } fclose (fp); return DFB_OK; }
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, data_size; 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; surface->data = NULL; 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 ); if (config->caps & DSCAPS_ROTATED) D_UNIMPLEMENTED(); surface->config.caps = config->caps & ~DSCAPS_ROTATED; } 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) ); surface->config.preallocated_pool_id = config->preallocated_pool_id; 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->config.caps &= ~DSCAPS_ROTATED; } 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_init2( &surface->lock, buf, dfb_core_world(core), fusion_config->secure_fusion ); // fusion_skirmish_add_permissions( &surface->lock, 0, FUSION_SKIRMISH_PERMIT_PREVAIL | FUSION_SKIRMISH_PERMIT_DISMISS ); 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 system driver specific surface data information */ data_size = dfb_system_surface_data_size(); if (data_size) { surface->data = SHCALLOC( surface->shmpool, 1, data_size ); if (!surface->data) { ret = D_OOSHM(); goto error; } } dfb_system_surface_data_init(surface,surface->data); dfb_surface_lock( surface ); /* Create the Surface Buffers. */ for (i=0; i<buffers; i++) { ret = dfb_surface_buffer_create( core, surface, CSBF_NONE, &surface->buffers[i] ); if (ret) { D_DERROR( ret, "Core/Surface: Error creating surface buffer!\n" ); goto error; } surface->num_buffers++; dfb_surface_buffer_globalize( surface->buffers[i] ); 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; } } dfb_surface_unlock( surface ); CoreSurface_Init_Dispatch( core, surface, &surface->call ); fusion_object_activate( &surface->object ); *ret_surface = surface; return DFB_OK; error: for (i=0; i<MAX_SURFACE_BUFFERS; i++) { if (surface->buffers[i]) dfb_surface_buffer_decouple( surface->buffers[i] ); } /* release the system driver specific surface data */ if (surface->data) { dfb_system_surface_data_destroy( surface, surface->data ); SHFREE( surface->shmpool, surface->data ); surface->data = NULL; } fusion_skirmish_destroy( &surface->lock ); direct_serial_deinit( &surface->serial ); D_MAGIC_CLEAR( surface ); fusion_object_destroy( &surface->object ); return ret; }
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; }
static DFBResult realize_region( CoreLayerRegion *region ) { DFBResult ret; CoreLayer *layer; CoreLayerShared *shared; DisplayLayerFuncs *funcs; D_ASSERT( region != NULL ); D_ASSERT( region->context != NULL ); D_ASSERT( D_FLAGS_IS_SET( region->state, CLRSF_CONFIGURED ) ); D_ASSERT( ! D_FLAGS_IS_SET( region->state, CLRSF_REALIZED ) ); layer = dfb_layer_at( region->context->layer_id ); D_ASSERT( layer != NULL ); D_ASSERT( layer->shared != NULL ); D_ASSERT( layer->funcs != NULL ); shared = layer->shared; funcs = layer->funcs; D_ASSERT( ! fusion_vector_contains( &shared->added_regions, region ) ); /* Allocate the driver's region data. */ if (funcs->RegionDataSize) { int size = funcs->RegionDataSize(); if (size > 0) { region->region_data = SHCALLOC( 1, size ); if (!region->region_data) return D_OOSHM(); } } D_DEBUG_AT( Core_Layers, "Adding region (%d, %d - %dx%d) to '%s'.\n", DFB_RECTANGLE_VALS( ®ion->config.dest ), shared->description.name ); /* Add the region to the driver. */ if (funcs->AddRegion) { ret = funcs->AddRegion( layer, layer->driver_data, layer->layer_data, region->region_data, ®ion->config ); if (ret) { D_DERROR( ret, "Core/Layers: Could not add region!\n" ); if (region->region_data) { SHFREE( region->region_data ); region->region_data = NULL; } return ret; } } /* Add the region to the 'added' list. */ fusion_vector_add( &shared->added_regions, region ); /* Update the region's state. */ D_FLAGS_SET( region->state, CLRSF_REALIZED ); /* Initially setup hardware. */ ret = set_region( region, ®ion->config, CLRCF_ALL, region->surface ); if (ret) { unrealize_region( region ); return ret; } return DFB_OK; }