我们用下面的log来跟踪DFB Core的创建过程:(蓝色为解释,黑色为打印的log)
=======================| DirectFB 1.1.1 |=======================
(c) 2001-2007 The DirectFB Organization (directfb.org)
(c) 2000-2004 Convergence (integrated media) GmbH
------------------------------------------------------------
//
指示当前DFB图形库为支持多进程共享方式,且通过dfb_system_lookup在/usr/local/lib/directfb-1.1.1/system中遍历加载图形接口库,找到配置文件中指定的system
(*) DirectFB/Core: Multi Application Core. (2008-02-28 06:31) [ DEBUG ][ TRACE ]
//dfb_core_create>>>fusion_enter>>>
//fusion_enter
解释为
Enters a fusion world by joining or creating it.
,说明每当一个进程调用
DFB
图形库都会获取一个
world index
,打开对性的
Fusion Kernel Device
“
/dev/fusion(0~8)
”
,且同时支持的最大数量为
FUSION_MAX_WORLDS=8
//
提示目前内核版本存在
MADV_REMOVE
漏洞
(*) Fusion/SHM: NOT using MADV_REMOVE (2.6.10.0 < 2.6.19.2)! [0x02060a00]
//dfb_core_create>>>fusion_enter>>>/* Start the dispatcher thread. */
direct_thread_create( DTT_MESSAGING,fusion_dispatch_loop,world, "Fusion Dispatch" );
启动消息接收处理线程,负责接收来自其他进程的消息
(*) Direct/Thread: Running 'Fusion Dispatch' (MESSAGING, 1297)...
//dfb_core_create>>>dfb_system_thread_init>>>system_funcs->ThreadInit()(fbdev.c-system_initialize)>>>dfb_vt_initialize>>>vt_init_switching
(*) Direct/Thread: Running 'VT Switcher' (CRITICAL, 1307)...
//下面以加载鼠标为例说明驱动Probe过程,Keyboard ,显卡MMX 过程都类同
//在循环打开动态库的同时完成下面过程DFB_INPUT_DRIVER( ps2mouse )>>>driver_open_device>>>
/* start input thread */ data->thread = direct_thread_create( DTT_INPUT, linux_input_EventThread, data, "Linux Input" );
(*) Direct/Thread: Running 'PS/2 Input' (INPUT, 1321)...
(*) DirectFB/Input: IMPS/2 Mouse 1.0 (directfb.org)
(*) Direct/Thread: Running 'Keyboard Input' (INPUT, 1322)...
(*) DirectFB/Input: Keyboard 0.9 (directfb.org)
//
Generic 软件渲染
(*) DirectFB/Graphics: Generic Software Rasterizer 0.6 (directfb.org)
//
创建窗口管理器
(*) DirectFB/Core/WM: Default 0.3 (directfb.org)
//以devfb为例说明分辨率、像素格式的检测过程
1.注册devfb region测试函数:
fbdev.c system_initialize
>>>/* Register primary layer functions */
dfb_layers_register( screen, NULL, &primaryLayerFuncs );
2.完成测试过程:
DirectFBCreate>>>IDirectFB_Construct>>>
if (dfb_core_is_master( core )) {
ret = InitLayers( thiz, data );
>>>dfb_layer_context_test_configuration
>>> funcs = layer->funcs;
/* Test the region configuration. */
if (region_config.buffermode == DLBM_WINDOWS) {}
else{ /* Let the driver examine the modified configuration. */
ret = funcs->TestRegion( layer, layer->driver_data, layer->layer_data,
®ion_config, &failed );
}
(*) FBDev/Mode: Testing 720x576 RGB16
(*) FBDev/Mode: Preparing switch to 720x576 RGB16
(*) FBDev/Mode: Testing 720x576 RGB16
(*) FBDev/Mode: Preparing switch to 720x576 RGB16
(*) FBDev/Mode: Testing 720x576 RGB16
(*) FBDev/Mode: Preparing switch to 720x576 RGB16
(*) FBDev/Mode: Testing 720x576 RGB16
(*) FBDev/Mode: Preparing switch to 720x576 RGB16
(*) FBDev/Mode: Testing 720x576 RGB16
(*) FBDev/Mode: Preparing switch to 720x576 RGB16
(*) FBDev/Surface: Allocated 720x576 16bit RGB16 buffer at offset 0 and pitch 1440.
(*) FBDev/Mode: (Post)Setting 720x576 RGB16
(*) FBDev/Mode: Switched to 720x576 (720x576) at 16 bit RGB16 (wanted RGB16).
(*) FBDev/Mode: Testing 720x576 RGB16
(*) FBDev/Mode: Preparing switch to 720x576 RGB16
(*) FBDev/Mode: (Post)Setting 720x576 RGB16
-------------------------woods---------df_fire---DirectFBCreate success
4.DFB画图流程
4.1在分析画图流程前先罗列一下DFB中关于图形相关名词
Blitting
Blitting
是只图像数据的拷贝过程。举一个最简单的例子就是当两个
Surface有相同的大小,颜色深度和像素格式时,
Blitting
其中一个
Surface 到另一个Surface。在这个过程中内存只被复制而没有被处理(就像复制其他任何类型的数据一样)。除此之外还有更高级的带alpha通道的blitting或者带不同像素格转换功能的blitting。许多图形显卡是由硬件
Blitting
来完成多种格式数据的传输和操作。一般来讲在完成Blitting操作后,我们即可在显示设备上看到要显示的内容。
Surface
Surface 是图像以一种具体的像素格式被保存的一块内存区域。一个Surface 可以位于显存或系统内存中。可以在一个Surface上进行画图操作或者把一个Surface
Blitting
到另一个上。
在全屏模式下时,屏幕中的可视区称为
”
主
Surface”
,所以可以直接在屏幕的可
视区完成图形操作。
为了避免闪烁问题,每个
Surface 都可以选择双缓冲,图形操作将首先在辅助缓冲区中执行然后采用Flip操作将其显示到可视区域。
SubSurface
SubSurface
使用和
Surface相同的接口。它代表父类Surface的一个区域并且没有
为自己分配任何系统或显存空间。
Layer
针对不同的显卡而言可能存在有一个或者多个显示层。一个标准的
PC
显卡只有一个层,但是对于嵌入式设备而言可能不只一个,比如TI Davinci平台的Video Processing Back End就包含4个硬件Layer,每个Layer都有独立的显存和显示控制特性。常用的硬件
alpha blend也多半都是基于这些硬件Layer完成的。其中真对STB应用,有一个比较特殊的Layer即Video层,一般情况下Video层都是位于底层且不支持透明,有的还支持硬件缩放,YUV、RGB颜色空间转换功能。真对硬件Layer的特点, DFB相应的实现了一些型号的显卡驱动。
Window / Windowstack
为了达到多显示对象的独立控制,DFB设计了一个Window管理器对某一个Layer上显示内容进行管理。每 个Window有独立的Surface进行画图操作,Window之间可以有重叠、聚焦、透明处理、获取事件等操作,增加了应用程序显示的多样性和灵活 性。多个Window组成了一个WindowStack。
4.2下图所示为DFB类间简单逻辑关系
1 个screenàN个 Layer (Davinci上为2个Video Layer 2个OSD Layer)
1个 Layer à N个 Window
1 个Window à N 个 Region
以上的N都是有最大值的,这里只代表多个的意思。
4.2以在Davinci平台的OSD Layer上的显示为例,分析DFB的画图流程:
情况1:如果我们不基于Window管理器,直接在OSD Layer上画图的流程
dfb->CreateSurface( dfb, &desc, &primary ); >>>获取OSD Layer的primary Surface
primary->SetColor(primary,0x55,0x55,0x00,0xff);
primary->FillRectangle(primary,0,0,80,80);>>> 填充一个长宽都为80的矩形区域
IDirectFBSurface_FillRectangle>>>surface矩形填充接口
dfb_gfxcard_fillrectangles>>>抽象出来的显卡矩形填充接口
dfb_gfxcard_state_check>>>检测是否存在显卡的硬件加速渲染接口 card->funcs.FillRectangle>>>通过函数指针调用显卡驱动
gFillRectangle>>>如果不存在则使用软件渲染函数,即直接对显存进行内存拷贝操作
primary->Flip( primary, NULL, 0 );
dfb_surface_flip( data->surface, false );>>> 改变surface buffer index
dfb_surface_notify( surface, CSNF_FLIP );>>>
dfb_surface_dispatch( surface, ¬ification, dfb_surface_globals );>>> 通过fusion通知进行surface_listener flip操作
fusion_reactor_dispatch>> ioctl (FUSION_REACTOR_DISPATCH)把消息丢给内核模块。
IDirectFBSurface_Flip>>> surface_listener收到消息后调用
dfb_back_to_front_copy >>>显示缓冲区之间的交换
情况2:基于Window管理器的画矩形框流程
dfb->GetDisplayLayer( dfb, DLID_PRIMARY, &layer )>>>获取Layer对象
layer->CreateWindow( layer, &desc, &window2 );>>>在创建Window对象,并将其加入Window Stack
window2->GetSurface( window2, &window_surface2 );>>>获取Window的Surface
window2->SetOpacity( window2, 0xFF );>>>设置Window为不透明
window2->CreateEventBuffer( window2, &buffer );>>>创建Window事件缓冲区
window_surface2->SetColor( window_surface2,0x00, 0x30, 0x10, 0xc0 );>>>设置Surface上画笔的颜色
window_surface2->DrawRectangle( window_surface2, 0, 0, desc.width, desc.height );>>>在Window2上的Surface画出矩形框
window_surface2->Flip( window_surface2, NULL, 0 );>>>显示Surface2上的图像缓存
=============需要进一步补充