1 / 31

Writing Custom GFX Drivers for DirectFB

Writing Custom GFX Drivers for DirectFB. IGEL Co., Ltd / Renesas Solution Corp. Today’s Topics. Objective Give commentary on DirectFB custom driver code Content Detail of custom driver code (gfxdriver) for DirectFB Porting experience on Renesas SH7751 + Silicon Motion SM501. DirectFB.

fiscus
Download Presentation

Writing Custom GFX Drivers for DirectFB

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Writing Custom GFX Drivers for DirectFB IGEL Co., Ltd / Renesas Solution Corp. IGEL Co.,Ltd. / Renesas Solution Corp.

  2. Today’s Topics • Objective • Give commentary on DirectFB custom driver code • Content • Detail of custom driver code (gfxdriver) for DirectFB • Porting experience on Renesas SH7751 + Silicon Motion SM501 IGEL Co.,Ltd. / Renesas Solution Corp.

  3. DirectFB • Provides graphic API set and integrated window system • Works on a frame buffer device(/dev/fb) and provides the mechanism to use the hardware acceleration effectively. • Goals • Small Foot Print • Maximizing the usability of hardware accelerator • Alpha blending • No modification in kernel • Library independent except for libc IGEL Co.,Ltd. / Renesas Solution Corp.

  4. DirectFB API • Graphics • Rectangle Filling/Drawing • Triangle Filling/Drawing • Line Drawing • Blit • Alpha Blending (texture alpha, alpha modulation) • Colorizing • Source Color Keying • Destination Color Keying • Integrated Window System IGEL Co.,Ltd. / Renesas Solution Corp.

  5. Graphics Drivers Matrox Mystique/Millennium, G100, G200, G400/450, G550 Via CLE266 ATI Mach64/Rage Pro series ATI Rage 128 ATI Radeon 3dfx Voodoo3/4/5/Banshee igs CyberPro 5xxx S3 Savage 3/4 series NeoMagic 220/2230/2360/2380 nVidia TNT/GeForce seiries SiS 315 Intel i810 NSC Geode Supported Devices • Input Drivers • Standard Keyboards • Serial and PS/2 mice • joysticks • Linux Input Layer Devices • Infrared Light Remote cont.(lirc) • iPAQ Touch Screen • ucb 1x00 Touch Screen • Microtech Touch Screen • Sony PI Jogdial IGEL Co.,Ltd. / Renesas Solution Corp.

  6. Sztatic Image JPEG (libjpeg) PNG (libpng2) GIF Imlib2 compatible image Moving Image mpeg1/2 (libmpeg3) AVI (avifile) MOV (OpenQuicktime) Macromedia Flash (libflash) video4linux Supported Formats • Font • DirectFB bitmap font • TrueType (FreeType2) IGEL Co.,Ltd. / Renesas Solution Corp.

  7. XDirectFB DirectFBGL GTK+ DFB++ C++ inteface for DirectFB DFBTerm Terminal DFBSee Motion Picture Application DFBPoint Presentation Application Useful Widgets on DirectFB • MythTV • PVR • Qt on DirectFB • SDL (Simple Directmedia Layer) • For Game Developper IGEL Co.,Ltd. / Renesas Solution Corp.

  8. DirectFB Architecture DirectFB Application • DirectFB consists of the followings: • Core API Module • Generic GFX Driver • GFX Drivers for Specific Hardware • To bring out the best performance on a specific graphics hardware GFX Drivers for the hardware should be written. • Generic GFX Driver checks whether the hardware acceleration by a GFX driver is available • If yes, it handovers to the GFX driver • If not it uses software rendering engine User Level DirectFB DirectFB Core API Module Generic GFX Driver GFX drivers(※) Device Drivers Frame Buffer Driver(※) Display Unit 2D Graphics Hardware Hardware ※Modules that needs to be developed IGEL Co.,Ltd. / Renesas Solution Corp.

  9. Why do we need GFX drivers? • Embedded CPU and bus are slow compare to Desktop’s CPU • 200-400MHz CPU • 120MHz 32bit Bus • Therefore, handover the rendering tasks to specialized hardware is crucial! IGEL Co.,Ltd. / Renesas Solution Corp.

  10. Writing GFX Drivers IGEL Co.,Ltd. / Renesas Solution Corp.

  11. How to write GFX Drivers? • Callback routines needs to be written • GFX Graphics Driver Functions • GFX Graphics Device Functions • Important Files • include/directfb.h • src/core/gfxcard.h • gfxdrivers/* • Good starting point is gfxdrivers/i810/*.[ch] IGEL Co.,Ltd. / Renesas Solution Corp.

  12. GFX Graphics Driver Functions From core/gfxcard.h: typedef struct { int (*Probe) (GraphicsDevice *device); void (*GetDriverInfo) (GraphicsDevice *device, GraphicsDriverInfo *driver_info); DFBResult (*InitDriver) (GraphicsDevice *device, GraphicsDeviceFuncs *funcs, void *driver_data, void *device_data); DFBResult (*InitDevice) (GraphicsDevice *device, GraphicsDeviceInfo *device_info, void *driver_data, void *device_data); void (*CloseDevice) (GraphicsDevice *device, void *driver_data, void *device_data); void (*CloseDriver) (GraphicsDevice *device, void *driver_data); } GraphicsDriverFuncs; IGEL Co.,Ltd. / Renesas Solution Corp.

  13. Probe() This should return check result of expected graphics chip is exist or not. GetDriverInfo() Returns driver's information static int driver_probe( GraphicsDevice *device ) { #ifdef FB_ACCEL_I810 switch (dfb_gfxcard_get_accelerator( device )) { case FB_ACCEL_I810: /* Intel 810 */ return 1; } #endif return 0; } static void driver_get_info( GraphicsDevice *device, GraphicsDriverInfo *info ) { /* fill driver info structure */ snprintf( info->name, DFB_GRAPHICS_DRIVER_INFO_NAME_LENGTH, "Intel 810/810E Driver" ); … info->version.major = 0; info->version.minor = 5; info->driver_data_size = sizeof (I810DriverData); info->device_data_size = sizeof (i801DeviceData); } Probe() and GetDriverInfo() IGEL Co.,Ltd. / Renesas Solution Corp.

  14. InitDriver() Initializes hardware and creates callback function table. InitDevice() Fills the device information such as flags of hardware-supported rendering. static DFBResult driver_init_driver( GraphicsDevice *device, GraphicsDeviceFuncs *funcs, void *driver_data, void *device_data ) { I810DriverData *i810drv = (I810DriverData *) driver_data; agp_setup setup; u32 base; i810drv->mmio_base = (volatile __u8*) dfb_gfxcard_map_mmio( device, 0, -1 ); if (!i810drv->mmio_base) return DFB_IO; /* AGP initilization */ i810drv->agpgart = open("/dev/agpgart", O_RDWR); . . . funcs->CheckState = i810CheckState; funcs->SetState = i810SetState; funcs->EngineSync = i810EngineSync; funcs->FlushTextureCache = i810FlushTextureCache; funcs->FillRectangle = i810FillRectangle; funcs->DrawRectangle = i810DrawRectangle; funcs->Blit = i810Blit; funcs->FillTriangle = i810FillTriangle; . . . return DFB_OK; } InitDriver() and InitDevice() static DFBResult driver_init_device( GraphicsDevice *device, GraphicsDeviceInfo *device_info, void *driver_data, void *device_data ) { /* fill device info */ device_info->caps.flags = CCF_CLIPPING; device_info->caps.accel =I810_SUPPORTED_DRAWINGFUNCTIONS | I810_SUPPORTED_BLITTINGFUNCTIONS; device_info->caps.drawing = I810_SUPPORTED_DRAWINGFLAGS; device_info->caps.blitting = I810_SUPPORTED_BLITTINGFLAGS; return DFB_OK; } IGEL Co.,Ltd. / Renesas Solution Corp.

  15. CloseDriver() Releases resource for the driver CloseDevice() Reset the hardware and releases resources for the device. static void driver_close_device( GraphicsDevice *device, void *driver_data, void *device_data ) { I810DeviceData *i810dev = (I810DeviceData *) device_data; I810DriverData *i810drv = (I810DriverData *) driver_data; (void) i810dev; (void) i810drv; } static void driver_close_driver( GraphicsDevice *device, void *driver_data ) { I810DriverData *i810drv = (I810DriverData *) driver_data; i810_wait_for_blit_idle(i810drv, NULL); i810_lring_enable(i810drv, 0); i810_release_resource(i810drv); dfb_gfxcard_unmap_mmio( device, i810drv->mmio_base, -1); } CloseDriver() and CloseDevice() IGEL Co.,Ltd. / Renesas Solution Corp.

  16. From core/gfxcard.h: typedef struct _GraphicsDeviceFuncs { /* * function that is called after variable screeninfo is changed * (used for buggy fbdev drivers, that reinitialize something when * calling FBIO_PUT_VSCREENINFO) */ void (*AfterSetVar)( void *driver_data, void *device_data ); /* * Called after driver->InitDevice() and during dfb_gfxcard_unlock( true ). * The driver should do the one time initialization of the engine, * e.g. writing some registers that are supposed to have a fixed value. * * This happens after mode switching or after returning from * OpenGL state (e.g. DRI driver). */ void (*EngineReset)( void *driver_data, void *device_data ); /* * Makes sure that graphics hardware has finished all operations. * * This method is called before the CPU accesses a surface' buffer * that had been written to by the hardware after this method has been * called the last time. * * It's also called before entering the OpenGL state (e.g. DRI driver). */ void (*EngineSync)( void *driver_data, void *device_data ); /* * after the video memory has been written to by the CPU (e.g. modification * of a texture) make sure the accelerator won't use cached texture data */ void (*FlushTextureCache)( void *driver_data, void *device_data ); /* * Check if the function 'accel' can be accelerated with the 'state'. * If that's true, the function sets the 'accel' bit in 'state->accel'. * Otherwise the function just returns, no need to clear the bit. */ void (*CheckState)( void *driver_data, void *device_data, CardState *state, DFBAccelerationMask accel ); /* * Program card for execution of the function 'accel' with the 'state'. * 'state->modified' contains information about changed entries. * This function has to set at least 'accel' in 'state->set'. * The driver should remember 'state->modified' and clear it. * The driver may modify 'funcs' depending on 'state' settings. */ void (*SetState) ( void *driver_data, void *device_data, struct _GraphicsDeviceFuncs *funcs, CardState *state, DFBAccelerationMask accel ); GFX Graphics Device Functions IGEL Co.,Ltd. / Renesas Solution Corp.

  17. /* * drawing functions */ bool (*FillRectangle) ( void *driver_data, void *device_data, DFBRectangle *rect ); bool (*DrawRectangle) ( void *driver_data, void *device_data, DFBRectangle *rect ); bool (*DrawLine) ( void *driver_data, void *device_data, DFBRegion *line ); bool (*FillTriangle) ( void *driver_data, void *device_data, DFBTriangle *tri ); /* * blitting functions */ bool (*Blit) ( void *driver_data, void *device_data, DFBRectangle *rect, int dx, int dy ); bool (*StretchBlit) ( void *driver_data, void *device_data, DFBRectangle *srect, DFBRectangle *drect ); /* * emit any buffered commands, i.e. trigger processing */ void (*EmitCommands) ( void *driver_data, void *device_data ); } GraphicsDeviceFuncs; GFX Graphics Device Interface(contd.) IGEL Co.,Ltd. / Renesas Solution Corp.

  18. Returns bits which indicate the hardware acceleration capability and supported color format. If you added new hardware drawing API, you need to enable bit in CheckState() and need to maintain function table list. Due to the limitations of graphics controller if some hardware acceleration can not be used, you need to disable corresponded bit in CheckState(). static void i810CheckState(void *drv, void *dev, CardState *state, DFBAccelerationMask accel ) { switch (state->destination->format) { case DSPF_LUT8: case DSPF_ARGB1555: case DSPF_RGB16: case DSPF_RGB24: break; default: return; } if (!(accel & ~I810_SUPPORTED_DRAWINGFUNCTIONS) && !(state->drawingflags & ~I810_SUPPORTED_DRAWINGFLAGS)) state->accel |= I810_SUPPORTED_DRAWINGFUNCTIONS; if (!(accel & ~I810_SUPPORTED_BLITTINGFUNCTIONS) && !(state->blittingflags & ~I810_SUPPORTED_BLITTINGFLAGS)) { if (state->source->format == state->destination->format) state->accel |= I810_SUPPORTED_BLITTINGFUNCTIONS; } } CheckState() IGEL Co.,Ltd. / Renesas Solution Corp.

  19. Rendering Functions • FillRectangle() • DrawRectangle() • DrawLine() • FillTriangle() • Blit() • StretchBlit() • Set_colorkey() • Set_color() • Set_clip() IGEL Co.,Ltd. / Renesas Solution Corp.

  20. EngineSync() is called before the CPU accesses a buffer that had been written to by the hardware. FlushTextureCache() after the video memory has been written to by the CPU, make sure the accelerator won't use cached texture data. Synchronization Functions Applications DirectFB CPU 2DG Video memory IGEL Co.,Ltd. / Renesas Solution Corp.

  21. An Our Experience Renesas SH7751 + Silicon Motion SM501 IGEL Co.,Ltd. / Renesas Solution Corp.

  22. Porting DirectFB on SH7751 + SM501 • GFX Driver for SM501 just set registers to issue rendering commands • Issuing command is done on the fly • Callback functions immediately set registers to render • Rendering comes on screen instantly GFX Driver for SM501 SM501 SM501 Registers IGEL Co.,Ltd. / Renesas Solution Corp.

  23. Color compare regiser is used in SM501 to enable this operation. You can define transparent color to the SM501 color compare register, then SM501 does not transfer this color when doing BLIT operation. So it looks transparent. static inline void sm501_set_colorkey( sm501DriverData *sm501drv, sm501DeviceData *sm501dev, CardState *state) { if (sm501dev->i_colorkey) return; if (state->blittingflags & DSBLIT_SRC_COLORKEY) { sm501drv->colorkey = state->src_colorkey; } else { sm501drv->colorkey = state->dst_colorkey; } regWrite32(DE_COLOR_COMPARE, sm501drv->colorkey); sm501dev->i_colorkey = 1; } Acceleration by SM501: Colorkey IGEL Co.,Ltd. / Renesas Solution Corp.

  24. Set SM501 clipping register as well static inline void sm501_set_clip( sm501DriverData *sm501drv, sm501DeviceData *sm501dev, DFBRegion *clip) { if (sm501dev->i_clip) return; sm501drv->clip_x1 = clip->x1; sm501drv->clip_x2 = clip->x2 + 1; sm501drv->clip_y1 = clip->y1; sm501drv->clip_y2 = clip->y2 + 1; regWrite32(DE_CLIP_TL, (sm501drv->clip_y1 << 16) | (unsigned short)sm501drv->clip_x1); regWrite32(DE_CLIP_BR, (sm501drv->clip_y2 << 16) | (unsigned short)sm501drv->clip_x2); sm501dev->i_clip = 1; } Acceleration by SM501: Clipping IGEL Co.,Ltd. / Renesas Solution Corp.

  25. Use 2D drawing engine static bool sm501FillRectangle(void *driver_data,void *device_data,DFBRectangle *rect) { sm501DriverData *sm501drv = (sm501DriverData *)driver_data; int DeltaX; int DeltaY; . . . sm501drv->x1 = rect->x; sm501drv->y1 = rect->y; sm501drv->x2 = rect->x+rect->w-1; sm501drv->y2 = rect->y+rect->h-1; . . . regWrite32(DE_FOREGROUND, sm501drv->color_value); regWrite32(DE_DESTINATION, (sm501drv->x1 << 16) | (unsigned short)sm501drv->y1); regWrite32(DE_DIMENSION,(DeltaX << 16) | (unsigned short)DeltaY); regWrite32(DE_CONTROL,0x8001800c); return true; } Acceleration by SM501: FillRectangle IGEL Co.,Ltd. / Renesas Solution Corp.

  26. SM501 does not have rectangle drawing capability, so draw four lines to draw rectangle in this driver static bool sm501DrawRectangle(void *driver_data,void *device_data,DFBRectangle *rect) { . . . sm501drv->x1 = rect->x; sm501drv->y1 = rect->y; sm501drv->x2 = rect->x+rect->w-1; sm501drv->y2 = rect->y+rect->h-1; . . . regWrite32(DE_FOREGROUND,drv->color_value); regWrite32(DE_DESTINATION, (drv->x1 << 16) | (unsigned short)drv->y1); regWrite32(DE_DIMENSION,(1 << 16) | (unsigned short)nHeight); regWrite32(DE_CONTROL,0x8506800c); regWrite32(DE_DESTINATION,(drv->x2 << 16) | (unsigned short)drv->y1); regWrite32(DE_CONTROL,0x8506800c); regWrite32(DE_DESTINATION,(drv->x1 << 16) | (unsigned short)drv->y1); regWrite32(DE_DIMENSION,(nWidth << 16) | 1); regWrite32(DE_CONTROL,0x8a06800c); regWrite32(DE_DESTINATION,(drv->x1 << 16) | (unsigned short)drv->y2); regWrite32(DE_CONTROL,0x8a06800c); return true; } Acceleration by SM501: DrawRectangle IGEL Co.,Ltd. / Renesas Solution Corp.

  27. Use shortstroke command for simple vertical / holizontal line,and use line command for other kind of line. static bool sm501DrawLine(void *driver_data,void *device_data,DFBRegion *line) { sm501DriverData *sm501drv = (sm501DriverData *)driver_data; sm501drv->x1 = line->x1; sm501drv->y1 = line->y1; sm501drv->x2 = line->x2; sm501drv->y2 = line->y2; if (drv->x1 == drv->x2) { // Vertical Line . . . } else if(drv->y1 == drv->y2) { // Horizontal line . . . } else { // Generic Line . . . } return true; } Acceleration by SM501: DrawLine IGEL Co.,Ltd. / Renesas Solution Corp.

  28. As SM501 does not have hardware triangle drawing capability, we draw triangle by software. However we can use horizontal line draw capability in SM501, so seems to achieved a little better performance than all software drawing. static bool sm501FillTriangle(void *driver_data,void *device_data,DFBTriangle *tri) { sm501DriverData *sm501drv = (sm501DriverData*)driver_data; bool err = true; dfb_sort_triangle(tri); if (tri->y3 - tri->y1 > 0) { sm501fill_tri(tri, sm501drv); } return err; } Acceleration by SM501: FillTriangle IGEL Co.,Ltd. / Renesas Solution Corp.

  29. Blit: Uses the 2D drawing engine StretchBlit: To avoid SM501 2D engine stretch function limitation, we use CSC (color space conversion) function instead. Acceleration by SM501: Blit and StretchBlit IGEL Co.,Ltd. / Renesas Solution Corp.

  30. Benchmark Results (df_dok) The hardware acceleration shows remarkable results. The performance depends on hardware acceleration engine rather than CPU. IGEL Co.,Ltd. / Renesas Solution Corp.

  31. Conclusion • DirectFB runs on various platforms because of the generic gfxdriver (software rendering engine). • It is easy to implement custom GFX driver for specific hardware. • The SM501 gfxdriver is just 1058 lines! • The GFX driver must improve the performance by the hardware acceleration. • If there are some graphic functions which are NOT supported by the hardware, you should find out an alternative way to implement it (rather than giving up). • DrawRectangle → DrawLine × 4 • FillTriangle → DrawLine × 3 + Software Rendering IGEL Co.,Ltd. / Renesas Solution Corp.

More Related