DirectFB Issues for CE

Download Report

Transcript DirectFB Issues for CE

Writing Custom GFX Drivers for
DirectFB
IGEL Co., Ltd / Renesas Solution Corp.
2005/6/13
IGEL Co.,Ltd. / Renesas Solution Corp.
1
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
2005/6/13
IGEL Co.,Ltd. / Renesas Solution Corp.
2
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
2005/6/13
IGEL Co.,Ltd. / Renesas Solution Corp.
3
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
2005/6/13
IGEL Co.,Ltd. / Renesas Solution Corp.
4
Supported Devices
 Graphics Drivers
 Input 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
2005/6/13
–
–
–
–
–
–
–
–
–
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.
5
Supported Formats
 Sztatic Image
–
–
–
–
 Font
JPEG (libjpeg)
PNG (libpng2)
GIF
Imlib2 compatible image
– DirectFB bitmap font
– TrueType (FreeType2)
 Moving Image
–
–
–
–
–
mpeg1/2 (libmpeg3)
AVI (avifile)
MOV (OpenQuicktime)
Macromedia Flash (libflash)
video4linux
2005/6/13
IGEL Co.,Ltd. / Renesas Solution Corp.
6
Useful Widgets on DirectFB
 XDirectFB
 MythTV
–
PVR
 DirectFBGL
 Qt on DirectFB
 GTK+
 SDL (Simple Directmedia Layer)
–
For Game Developper
 DFB++
–
C++ inteface for DirectFB
 DFBTerm
–
Terminal
 DFBSee
–
Motion Picture Application
 DFBPoint
–
Presentation Application
2005/6/13
IGEL Co.,Ltd. / Renesas Solution Corp.
7
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.
–
•
•
2005/6/13
If yes, it handovers to the GFX driver
If not it uses software rendering
engine
DirectFB
DirectFB Core API Module
Generic
GFX Driver
Device Drivers Hardware
Generic GFX Driver checks whether
the hardware acceleration by a GFX
driver is available
User Level
–
–
–
GFX drivers(※)
Frame Buffer
Driver(※)
Display Unit
2D Graphics
Hardware
※Modules that needs to be developed
IGEL Co.,Ltd. / Renesas Solution Corp.
8
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!
2005/6/13
IGEL Co.,Ltd. / Renesas Solution Corp.
9
Writing GFX Drivers
2005/6/13
IGEL Co.,Ltd. / Renesas Solution Corp.
10
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]
2005/6/13
IGEL Co.,Ltd. / Renesas Solution Corp.
11
GFX Graphics Driver Functions
From core/gfxcard.h:
typedef struct {
int
(*Probe)
void
(*GetDriverInfo)
(GraphicsDevice
(GraphicsDevice
GraphicsDriverInfo
*device);
*device,
*driver_info);
DFBResult (*InitDriver)
(GraphicsDevice
GraphicsDeviceFuncs
void
void
*device,
*funcs,
*driver_data,
*device_data);
DFBResult (*InitDevice)
(GraphicsDevice
GraphicsDeviceInfo
void
void
*device,
*device_info,
*driver_data,
*device_data);
void
(*CloseDevice)
void
(*CloseDriver)
(GraphicsDevice
void
void
(GraphicsDevice
void
*device,
*driver_data,
*device_data);
*device,
*driver_data);
} GraphicsDriverFuncs;
2005/6/13
IGEL Co.,Ltd. / Renesas Solution Corp.
12
Probe() and GetDriverInfo()
 Probe()
– This should return check
result of expected graphics
chip is exist or not.
 GetDriverInfo()
– Returns driver's information
2005/6/13
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);
}
IGEL Co.,Ltd. / Renesas Solution Corp.
13
InitDriver() and InitDevice()
 InitDriver()
– Initializes hardware and
creates callback function
table.
 InitDevice()
– Fills the device information
such as flags of hardwaresupported rendering.
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;
}
2005/6/13
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
funcs->SetState
funcs->EngineSync
funcs->FlushTextureCache
i810FlushTextureCache;
funcs->FillRectangle
funcs->DrawRectangle
funcs->Blit
funcs->FillTriangle
. . .
return DFB_OK;
= i810CheckState;
= i810SetState;
= i810EngineSync;
=
=
=
=
=
i810FillRectangle;
i810DrawRectangle;
i810Blit;
i810FillTriangle;
}
IGEL Co.,Ltd. / Renesas Solution Corp.
14
CloseDriver() and CloseDevice()
 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);
}
2005/6/13
IGEL Co.,Ltd. / Renesas Solution Corp.
15
GFX Graphics Device Functions
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 );
2005/6/13
/*
* 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 );
IGEL Co.,Ltd. / Renesas Solution Corp.
16
GFX Graphics Device Interface
(contd.)
/*
* 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;
2005/6/13
IGEL Co.,Ltd. / Renesas Solution Corp.
17
CheckState()
 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().
2005/6/13
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;
}
}
IGEL Co.,Ltd. / Renesas Solution Corp.
18
Rendering Functions




FillRectangle()
DrawRectangle()
DrawLine()
FillTriangle()
 Blit()
 StretchBlit()
 Set_colorkey()
 Set_color()
 Set_clip()
2005/6/13
IGEL Co.,Ltd. / Renesas Solution Corp.
19
Synchronization Functions
 EngineSync()
Applications
– 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.
2005/6/13
DirectFB
CPU
2DG
Video memory
IGEL Co.,Ltd. / Renesas Solution Corp.
20
An Our Experience
Renesas SH7751 + Silicon Motion SM501
2005/6/13
IGEL Co.,Ltd. / Renesas Solution Corp.
21
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
2005/6/13
GFX Driver for SM501
SM501 Registers
IGEL Co.,Ltd. / Renesas Solution Corp.
SM501
22
Acceleration by SM501: Colorkey
 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;
}
2005/6/13
IGEL Co.,Ltd. / Renesas Solution Corp.
23
Acceleration by SM501: Clipping
 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;
}
2005/6/13
IGEL Co.,Ltd. / Renesas Solution Corp.
24
Acceleration by SM501:
FillRectangle
 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
sm501drv->y1
sm501drv->x2
sm501drv->y2
. . .
=
=
=
=
rect->x;
rect->y;
rect->x+rect->w-1;
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;
}
2005/6/13
IGEL Co.,Ltd. / Renesas Solution Corp.
25
Acceleration by SM501:
DrawRectangle
 SM501 does not have
rectangle drawing capability,
so draw four lines to draw
rectangle in this driver
2005/6/13
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;
}
IGEL Co.,Ltd. / Renesas Solution Corp.
26
Acceleration by SM501: DrawLine
 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
sm501drv->y1
sm501drv->x2
sm501drv->y2
=
=
=
=
line->x1;
line->y1;
line->x2;
line->y2;
if (drv->x1 == drv->x2) {
// Vertical Line
. . .
} else if(drv->y1 == drv->y2) {
// Horizontal line
. . .
} else {
// Generic Line
. . .
}
return true;
}
2005/6/13
IGEL Co.,Ltd. / Renesas Solution Corp.
27
Acceleration by SM501:
FillTriangle
 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;
}
2005/6/13
IGEL Co.,Ltd. / Renesas Solution Corp.
28
Acceleration by SM501: Blit and
StretchBlit
 Blit: Uses the 2D drawing
engine
 StretchBlit: To avoid SM501
2D engine stretch function
limitation, we use CSC (color
space conversion) function
instead.
2005/6/13
IGEL Co.,Ltd. / Renesas Solution Corp.
29
Benchmark Results (df_dok)
CPU
Bus
RAM
2D
Kernel
H/W Accel
A
SH7751 240MHz
SH-Bus
64MB
SMI SM501
2.4.19
Off
B
SH7751 240MHz
SH-Bus
64MB
SMI SM501
2.4.20
On
C
SH7751 240MHz
PCI
64MB
Matrox Millennium
2.4.20
On
D
Celeron 450MHz
PCI
128MB
Matrox Millennium
2.4.20
On
A
Fill Rectangles [MPixel/sec]
Fill RectanglesThe
(blend)
[MPixel/sec]
hardware
Fill Triangles
[MPixel/sec]
acceleration
shows
Fill Triangles
(blend) [MPixel/sec]
remarkable
results.
Draw Rectangles [KRects/sec]
Draw Rectangles (blend) [KRects/sec]
Draw Lines [KLines/sec]
Draw Lines (blend) [KLines/sec]
Blit [MPixel/sec]
Blit with format conversion [MPixel/sec]
2005/6/13
B
C
D
14.07
217.66
63.63
53.25
1.64
1.66
1.2
3.26
12.25
93.69
62.26
50.51
1.63
1.63
1.17
3.17
1.81
15.45
10.67
8.57
0.43
0.84
61.33
48.84
1.94
3.7
38.68
32.56
3.59
17.79
The performance
0.52
0.56
depends on7.1hardware67.09
acceleration
engine 2.43
2.33
rather than
CPU. 102.47
8.12
4.04
4.12
IGEL Co.,Ltd. / Renesas Solution Corp.
30
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
2005/6/13
IGEL Co.,Ltd. / Renesas Solution Corp.
31