I recently had a need for directfb without any display so I've patched up the devmem system to work with allocated memory.
So far it works ok for my usage. Patch attached. Some notes their seems to some assumptions about the amount of memory available for surfaces and layers. Sample config that worked export DFBARGS="system=devmem,video-allocate=0x0,video-allocate-length=614400,mode=320x240"
diff --git a/src/misc/conf.c b/src/misc/conf.c index e220836..9add322 100644 --- a/src/misc/conf.c +++ b/src/misc/conf.c @@ -149,6 +149,8 @@ static const char *config_usage = " mmio-phys=<hexaddress> Physical start of MMIO area (devmem system)\n" " mmio-length=<bytes> Length of MMIO area (devmem system)\n" " accelerator=<id> Accelerator ID selecting graphics driver (devmem system)\n" + " video-allocate=<hexaddress> Start of virtual video memory (devmem system)\n" + " video-allocate-length=<byyes> Length of virtual video memory (devmem system)\n" "\n" " [no-]matrox-sgram Use Matrox SGRAM features\n" " [no-]matrox-crtc2 Experimental Matrox CRTC2 support\n" @@ -1541,6 +1543,44 @@ DFBResult dfb_config_set( const char *name, const char *value ) return DFB_INVARG; } } else + if (strcmp (name, "video-allocate" ) == 0) { + if (value) { + char *error; + ulong allocate; + + allocate = strtoul( value, &error, 16 ); + + if (*error) { + D_ERROR( "DirectFB/Config '%s': Error in hex value '%s'!\n", name, error ); + return DFB_INVARG; + } + + dfb_config->video_allocate = allocate; + } + else { + D_ERROR( "DirectFB/Config '%s': No value specified!\n", name ); + return DFB_INVARG; + } + } else + if (strcmp (name, "video-allocate-length" ) == 0) { + if (value) { + char *error; + ulong length; + + length = strtoul( value, &error, 10 ); + + if (*error) { + D_ERROR( "DirectFB/Config '%s': Error in value '%s'!\n", name, error ); + return DFB_INVARG; + } + + dfb_config->video_allocate_length = length; + } + else { + D_ERROR( "DirectFB/Config '%s': No value specified!\n", name ); + return DFB_INVARG; + } + } else if (strcmp (name, "matrox-tv-standard" ) == 0) { if (value) { if (strcmp( value, "pal-60" ) == 0) { diff --git a/src/misc/conf.h b/src/misc/conf.h index 430e2e4..a9f9ec8 100644 --- a/src/misc/conf.h +++ b/src/misc/conf.h @@ -196,6 +196,8 @@ typedef struct unsigned long mmio_phys; /* Physical base address of MMIO area */ unsigned int mmio_length; /* Size of MMIO area */ int accelerator; /* Accelerator ID */ + unsigned long video_allocate; /* virtual base address of video memory */ + unsigned int video_allocate_length; /* Size of virtual video memory */ bool font_premult; /* Use premultiplied data in case of ARGB glyph images */ diff --git a/systems/devmem/devmem.c b/systems/devmem/devmem.c index 2a30a0b..c26e7e8 100644 --- a/systems/devmem/devmem.c +++ b/systems/devmem/devmem.c @@ -40,6 +40,9 @@ #include <core/core.h> #include <core/surface_pool.h> +#include <core/layers.h> +#include <core/screens.h> +#include <gfx/convert.h> #include <misc/conf.h> @@ -51,6 +54,209 @@ DFB_CORE_SYSTEM( devmem ) +static DFBResult +primaryInitScreen( CoreScreen *screen, + CoreGraphicsDevice *device, + void *driver_data, + void *screen_data, + DFBScreenDescription *description ) +{ + /* Set the screen capabilities. */ + description->caps = DSCCAPS_NONE; + + /* Set the screen name. */ + snprintf( description->name, + DFB_SCREEN_DESC_NAME_LENGTH, "Allocated Primary Screen" ); + + return DFB_OK; +} + +static DFBResult +primaryGetScreenSize( CoreScreen *screen, + void *driver_data, + void *screen_data, + int *ret_width, + int *ret_height ) +{ + + if (dfb_config->mode.width) + *ret_width = dfb_config->mode.width; + else + *ret_width = dfb_config->video_allocate_length/2; + + if (dfb_config->mode.height) + *ret_height = dfb_config->mode.height; + else + *ret_height = dfb_config->video_allocate_length/2; + return DFB_OK; +} + +ScreenFuncs allocatePrimaryScreenFuncs = { + InitScreen: primaryInitScreen, + GetScreenSize: primaryGetScreenSize +}; + +/******************************************************************************/ + +static int +primaryLayerDataSize() +{ + return 0; +} + +static int +primaryRegionDataSize() +{ + return 0; +} + +static DFBResult +primaryInitLayer( CoreLayer *layer, + void *driver_data, + void *layer_data, + DFBDisplayLayerDescription *description, + DFBDisplayLayerConfig *config, + DFBColorAdjustment *adjustment ) +{ + /* set capabilities and type */ + description->caps = DLCAPS_SURFACE; + description->type = DLTF_GRAPHICS; + + /* set name */ + snprintf( description->name, + DFB_DISPLAY_LAYER_DESC_NAME_LENGTH, "X11 Primary Layer" ); + + /* fill out the default configuration */ + config->flags = DLCONF_WIDTH | DLCONF_HEIGHT | + DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE; + config->buffermode = DLBM_FRONTONLY; + + if (dfb_config->mode.width) + config->width = dfb_config->mode.width; + else + config->width = dfb_config->video_allocate_length/2; + + if (dfb_config->mode.height) + config->height = dfb_config->mode.height; + else + config->height = dfb_config->video_allocate_length/2; + + if (dfb_config->mode.format != DSPF_UNKNOWN) + config->pixelformat = dfb_config->mode.format; + else if (dfb_config->mode.depth > 0) + config->pixelformat = dfb_pixelformat_for_depth( dfb_config->mode.depth ); + else { + config->pixelformat = DSPF_RGB32; + } + + return DFB_OK; +} + +static DFBResult +primaryTestRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + CoreLayerRegionConfig *config, + CoreLayerRegionConfigFlags *failed ) +{ + CoreLayerRegionConfigFlags fail = 0; + + switch (config->buffermode) { + case DLBM_FRONTONLY: + case DLBM_BACKSYSTEM: + case DLBM_BACKVIDEO: + case DLBM_TRIPLE: + break; + + default: + fail |= CLRCF_BUFFERMODE; + break; + } + + if (config->options) + fail |= CLRCF_OPTIONS; + + if (failed) + *failed = fail; + + if (fail) + return DFB_UNSUPPORTED; + + return DFB_OK; +} + +static DFBResult +primaryAddRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreLayerRegionConfig *config ) +{ + return DFB_OK; +} + +static DFBResult +primarySetRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreLayerRegionConfig *config, + CoreLayerRegionConfigFlags updated, + CoreSurface *surface, + CorePalette *palette, + CoreSurfaceBufferLock *lock ) +{ + return DFB_OK; +} + +static DFBResult +primaryRemoveRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data ) +{ + return DFB_OK; +} + +static DFBResult +primaryFlipRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreSurface *surface, + DFBSurfaceFlipFlags flags, + CoreSurfaceBufferLock *lock ) +{ + return DFB_OK; +} + +static DFBResult +primaryUpdateRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreSurface *surface, + const DFBRegion *update, + CoreSurfaceBufferLock *lock ) +{ + return DFB_OK; +} + + +DisplayLayerFuncs allocatePrimaryLayerFuncs = { + LayerDataSize: primaryLayerDataSize, + RegionDataSize: primaryRegionDataSize, + InitLayer: primaryInitLayer, + + TestRegion: primaryTestRegion, + AddRegion: primaryAddRegion, + SetRegion: primarySetRegion, + RemoveRegion: primaryRemoveRegion, + FlipRegion: primaryFlipRegion, + UpdateRegion: primaryUpdateRegion, +}; + + /**********************************************************************************************************************/ static DevMemData *m_data; /* FIXME: Fix Core System API to pass data in all functions. */ @@ -98,7 +304,8 @@ UnmapMemAndReg( DevMemData *data, unsigned int mem_length, unsigned int reg_length ) { - munmap( data->mem, mem_length ); + if(!dfb_config->video_length) + munmap( data->mem, mem_length ); if (reg_length) munmap( (void*) data->reg, reg_length ); @@ -124,15 +331,16 @@ system_initialize( CoreDFB *core, void **ret_data ) FusionSHMPoolShared *pool; D_ASSERT( m_data == NULL ); + if (!dfb_config->video_allocate_length) { + 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->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" ); + 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) ); @@ -151,7 +359,27 @@ system_initialize( CoreDFB *core, void **ret_data ) data->shared = shared; - ret = MapMemAndReg( data, + if (dfb_config->video_allocate_length) { + CoreScreen *screen; + ret = DFB_OK; + if(dfb_config->video_allocate) { + data->mem = (void*)dfb_config->video_allocate; + D_INFO("System/DevMem: Memory Preallocated at %p %d bytes\n", dfb_config->video_allocate,dfb_config->video_allocate_length, "MAP_SHARED|MAP_ANONYMOUS" ); + } + else { + data->mem = mmap(NULL,dfb_config->video_allocate_length, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, 0, 0); + if (data->mem == MAP_FAILED) { + fprintf(stderr,"------------------HERE--------\n"); + D_PERROR( "System/DevMem: Mapping %d bytes via '%s' failed!\n", dfb_config->video_allocate_length, "MAP_SHARED|MAP_ANONYMOUS" ); + ret = DFB_INIT; + } + D_INFO("System/DevMem: Mapping %d bytes via '%s' \n", dfb_config->video_allocate_length, "MAP_SHARED|MAP_ANONYMOUS" ); + } + screen = dfb_screens_register( NULL, NULL, &allocatePrimaryScreenFuncs ); + dfb_layers_register( screen, NULL, &allocatePrimaryLayerFuncs ); + + } else + ret = MapMemAndReg( data, dfb_config->video_phys, dfb_config->video_length, dfb_config->mmio_phys, dfb_config->mmio_length ); if (ret) { @@ -228,8 +456,11 @@ system_shutdown( bool emergency ) D_ASSERT( shared != NULL ); dfb_surface_pool_destroy( shared->pool ); - - UnmapMemAndReg( m_data, dfb_config->video_length, dfb_config->mmio_length ); + if(dfb_config->video_allocate_length) { + if(!dfb_config->video_allocate) + munmap( m_data->mem, dfb_config->video_allocate_length); + }else + UnmapMemAndReg( m_data, dfb_config->video_length, dfb_config->mmio_length ); SHFREE( shared->shmpool, shared ); @@ -338,6 +569,8 @@ system_video_memory_virtual( unsigned int offset ) static unsigned int system_videoram_length() { + if( dfb_config->video_allocate_length) + return dfb_config->video_allocate_length; return dfb_config->video_length; }
_______________________________________________ directfb-dev mailing list directfb-dev@directfb.org http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev