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

Reply via email to