Chinaunix首页 | 论坛 | 博客
  • 博客访问: 723851
  • 博文数量: 104
  • 博客积分: 4320
  • 博客等级: 上校
  • 技术积分: 1948
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-30 14:42
文章分类

全部博文(104)

文章存档

2012年(4)

2011年(65)

2010年(35)

分类: LINUX

2011-11-07 20:33:36

本文根据 IGEL 公司和 Renesas 公司的工程师做的 presentation 整理而成,介绍了他们使用 DirectFB 开发嵌入式应用程序的经验,内容包括 DirectFB 的体系结构、硬件加速带来的性能提升、GFX graphics 驱动开发方法、DirectFB 缺少的 features 等内容。本文图文并茂,对使用者较深入的理解 DirectFB 有很大帮助。
体系结构体系结构如下图所示:

  • works on a frame buffer device(/dev/fb) and provides the mechanism to use the hardware acceleration effectively.
  • consists of the followings:
    1. Core API Module;
    2. Generic GFX Driver;
    3. 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:
    1. If yes, it handovers to the GFX driver;
    2. If not, it uses software rendering engine.

Why do we need GFX driver
  • Embedded CPU and bus are slow compare to Desktop’s CPU;
    1. 200-400MHz CPU;
    2. 120MHz 32bit Bus.
  • Therefore, handover the rendering tasks to specialized hardware is crucial.
Effects of Hardware Acceleration
  • The hardware acceleration shows remarkable results.
  • The performance depends on hardware acceleration engine rather than CPU.
How to write GFX Driver

Callback routines needs to be written

  1. GFX Driver Functions;
  2. GFX Device Functions.

Good starting point is gfxdrivers/i810/*.[ch]

GFX Driver Function:

  1. From core/gfxcard.h:

  2. typedef struct {
  3.      int (*Probe) (GraphicsDevice *device);
  4.      void (*GetDriverInfo) (GraphicsDevice *device,
  5.                                   GraphicsDriverInfo *driver_info);

  6.      DFBResult (*InitDriver) (GraphicsDevice *device,
  7.                                   GraphicsDeviceFuncs *funcs,
  8.                                   void *driver_data,
  9.                                   void *device_data);

  10.      DFBResult (*InitDevice) (GraphicsDevice *device,
  11.                                   GraphicsDeviceInfo *device_info,
  12.                                   void *driver_data,
  13.                                   void *device_data);

  14.      void (*CloseDevice) (GraphicsDevice *device,
  15.                                   void *driver_data,
  16.                                   void *device_data);
  17.      void (*CloseDriver) (GraphicsDevice *device,
  18.                                   void *driver_data);
  19. } GraphicsDriverFuncs;
GFX Device Functions:
  1. From core/gfxcard.h:
  2. typedef struct _GraphicsDeviceFuncs {
  3.      /*
  4.       * function that is called after variable screeninfo is changed
  5.       * (used for buggy fbdev drivers, that reinitialize something when
  6.       * calling FBIO_PUT_VSCREENINFO)
  7.       */
  8.      void (*AfterSetVar)( void *driver_data, void *device_data );

  9.      /*
  10.       * Called after driver->InitDevice() and during dfb_gfxcard_unlock( true ).
  11.       * The driver should do the one time initialization of the engine,
  12.       * e.g. writing some registers that are supposed to have a fixed value.
  13.       *
  14.       * This happens after mode switching or after returning from
  15.       * OpenGL state (e.g. DRI driver).
  16.       */
  17.      void (*EngineReset)( void *driver_data, void *device_data );

  18.      /*
  19.       * Makes sure that graphics hardware has finished all operations.
  20.       *
  21.       * This method is called before the CPU accesses a surface' buffer
  22.       * that had been written to by the hardware after this method has been
  23.       * called the last time.
  24.       *
  25.       * It's also called before entering the OpenGL state (e.g. DRI driver).
  26.       */
  27.      void (*EngineSync)( void *driver_data, void *device_data );

  28.      /*
  29.       * after the video memory has been written to by the CPU (e.g. modification
  30.       * of a texture) make sure the accelerator won't use cached texture data
  31.       */
  32.      void (*FlushTextureCache)( void *driver_data, void *device_data );

  33.      /*
  34.       * Check if the function 'accel' can be accelerated with the 'state'.
  35.       * If that's true, the function sets the 'accel' bit in 'state->accel'.
  36.       * Otherwise the function just returns, no need to clear the bit.
  37.       */
  38.      void (*CheckState)( void *driver_data, void *device_data,
  39.                      CardState *state, DFBAccelerationMask accel );

  40.      /*
  41.       * Program card for execution of the function 'accel' with the 'state'.
  42.       * 'state->modified' contains information about changed entries.
  43.       * This function has to set at least 'accel' in 'state->set'.
  44.       * The driver should remember 'state->modified' and clear it.
  45.       * The driver may modify 'funcs' depending on 'state' settings.
  46.       */
  47.      void (*SetState) ( void *driver_data, void *device_data,
  48.                      struct _GraphicsDeviceFuncs *funcs,
  49.                      CardState *state, DFBAccelerationMask accel );
  50.      /*
  51.       * drawing functions
  52.       */
  53.      bool (*FillRectangle) ( void *driver_data, void *device_data,
  54.                              DFBRectangle *rect );

  55.      bool (*DrawRectangle) ( void *driver_data, void *device_data,
  56.                              DFBRectangle *rect );

  57.      bool (*DrawLine) ( void *driver_data, void *device_data,
  58.                              DFBRegion *line );

  59.      bool (*FillTriangle) ( void *driver_data, void *device_data,
  60.                              DFBTriangle *tri );

  61.      /*
  62.       * blitting functions
  63.       */
  64.      bool (*Blit) ( void *driver_data, void *device_data,
  65.                              DFBRectangle *rect, int dx, int dy );

  66.      bool (*StretchBlit) ( void *driver_data, void *device_data,
  67.                              DFBRectangle *srect, DFBRectangle *drect );

  68.      /*
  69.       * emit any buffered commands, i.e. trigger processing
  70.       */
  71.      void (*EmitCommands) ( void *driver_data, void *device_data );
  72. } GraphicsDeviceFuncs;

Porting on SH7751 + SM501

需要开发为 SM501 开发 GFX Driver。

基本思路如下图所示:


GFX Driver for SM501 just set registers to issue rendering commands:

  1. Issuing command is done on the fly;
  2. Callback functions immediately set registers to render;
  3. Rendering comes on screen instantly.

Porting on SH7770

SH7770 的驱动比上面的 SM501 更复杂一些。


GFX Driver for SH7770 creates list of rendering commands, so called Display List.The list is double buffered.

The driver fills the list until they’re full, and then pass them to the 2D engine.

  1. While the driver is filling one list, the 2D engine reads commands from another list;
  2. Once the 2D engine is done with the list, it sends an interrupt,and get the next list;
  3. Rendering doesn’t come on screen instantly.

Sync mechanism is required to sync with software rendering done by generic GFX driver

Missing Pieces in
  • Access multiple layered frame buffer from a process.Recent graphics hardware has multiple frame buffers;
  • Using ‘scroll’ function on hardware. New feature not covered by API;
  • Synchronous rendering and display with VSYNC (QoS, delay handling).Real-time motion graphics (e.g. game), car navigation, etc;
  • Synchronize 2D Engine and 3D Engine.
    1. Render with 2D and 3D Engine in a single layer;
    2. Synchronous display even 2D and 3D are on different layers.
Access Multiple Layered Frame Buffer from a Process

Recent graphics hardware has multiple layered frame buffer.

To coordinate layers efficiently, an application process wants to issue rendering commands and switch on / off display of each layer.

Using "Scroll" Function on Hardware

Use Case: car navigation system, web browser.

The 'Scroll' function reduces re-rendering cost.

Synchronous Rendering and Display with VSYNC (QoS)

In real-time motion graphics applications, the screen must be updated in sync with the VSYNC signal.

Under the standard (fairly) task scheduling in Linux, rendering might miss display timing (VSYNC) because of signal interrupts or other heavy tasks.

Real-time motion graphics applications could be optimized for screen rendering, especially for delay handling.

Application needs VSYNC signal timing to notice the delay.

Delay Handling by Application:

  1. Skipping the next frame rendering.When an application noticed that display has been delayed, it could skip the next frame and start rendering the frame after the next.
  2. Updating screen even if the rendering is not finished.Additionally, application could give priority to rendering operations in case of incomplete frame displaying.
Synchronize 2D Engine and 3D Engine

Many 3D graphics applications combine 3D graphics and 2D graphics.

These 2D graphics must be synchronized with 3D graphics.

Some 3D acceleration hardware (nVIDIA, ATI, for example) are separated from 2D hardware.

Synchronization mechanism between 2D and 3D graphics (hardware) is needed.

Situation 1: Rendering 2D graphics and 3D graphics into a single layer simultaneously

  1. 2D engine and 3D engine tries to draw into a frame without any synchronization. They should be serialized.
  2. Issued rendering commands might be performed asynchronously.
来自资料1

Situation 2: Displaying a 2D graphics layer and a 3D graphics layer synchronously.

  1. 2D/3D engines can draw into each independent layer asynchronously if the multiple layered frame buffer is available.
  2. Synchronous display function is still needed.
来自参考资料1
阅读(3075) | 评论(0) | 转发(0) |
0

上一篇:DirectFB分析

下一篇:I9001 刷机

给主人留下些什么吧!~~