Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RT-Thread一般讨论
FreeType应用研究小记
发布于 2014-09-15 20:51:20 浏览:5195
订阅该版
RTGUI中已经支持FreeType了,相信有人对TTF等字体比较青睐。实测RTGUI只在PC验证平台上支持了FreeType,在ARM上还不能跑起来.对比之后发现,原来PC平台上使用的标准连接库函数,这是FreeType原生支持的,要想在嵌入式使用,需要作少量修改。 FreeType使用头文件freetype/config/ftstdlib.h实现标准库函数的可移植性支持, 下面这些需要替换: ```c /* file handling */ #include
#define FT_FILE FILE #define ft_fclose fclose #define ft_fopen fopen #define ft_fread fread #define ft_fseek fseek #define ft_ftell ftell #define ft_sprintf sprintf ``` 可以使用rtgui的struct filerw替换: ```c #include
#define FT_FILE rtgui_filerw_t #define ft_fclose rtgui_filerw_close #define ft_fopen rtgui_filerw_create_file #define ft_fread rtgui_filerw_read #define ft_fseek rtgui_filerw_seek #define ft_ftell rtgui_filerw_tell ``` 之后检查函数的形参是否一致,顺序是否正确, 如果开启了宏FT_DEBUG_LEVEL_ERROR和FT_DEBUG_LEVEL_TRACE, 还需要修改ftdebug.c和ftdbgmem.c和其它文件中引用以下函数的地方, vfprintf,vprintf,fprintf, 可以自己修改成与RTT相关的函数,最简单的办法是把它们都指向串口输出rt_kprintf, 最后有一个比较奇怪的地方是FT_Stream_Seek函数: ```c FT_BASE_DEF( FT_Error ) FT_Stream_Seek( FT_Stream stream, FT_ULong pos ) { FT_Error error = FT_Err_Ok; if ( stream->read ) { if ( stream->read( stream, pos, 0, 0 ) ) //此语句在RTT下测试不能通过 { FT_ERROR(( "FT_Stream_Seek:" " invalid i/o; pos = 0x%lx, size = 0x%lx ", pos, stream->size )); error = FT_Err_Invalid_Stream_Operation; } } ``` 上面注释的语句修改成 ```c if ( stream->read ) { stream->read( stream, pos, 0, 0 ); } ``` 只执行,不再对错误处理就行了, 如果没有遗漏的地方,FreeType应该可以成功跑起来了。 想流畅的运行FreeType,建议ARM11以上平台,ARM9以下勉勉强强的
查看更多
11
个回答
默认排序
按发布时间排序
xiao苦
2014-09-17
这家伙很懒,什么也没写!
谢谢。。这篇不错呢 [s:186]
amsl
2014-09-19
这家伙很懒,什么也没写!
xiao苦,你也对FreeType感兴趣吗,希望一起讨论有关问题,也希望更多的人参与进来. 下面说说关于如何优化FreeType的问题,如果优化得当,在嵌入式系统中使用FreeType还是相当有竞争力的.我在度娘看到有篇论文经过优化使用ttf字体时可以把效率提高1倍以上,不知是如何做到的.我尝试了一下,经过一些优化措施,即便开启编译优化-O3,再开启time优化,效率也没有提高到1倍的水平.既然别人能做到,说明还是有优化余地的. 以下是我总结的优化点: 1.只保留一种字体,例如仅开启TrueType字体(我仅保留了TT_CONFIG_CMAP_FORMAT_4,对应windows的ttf字体),此时需要开启的模块有tt_driver,sfnt,smooth,可再多加个autofit,后者可省略处理一些贝塞尔曲线,略微提高生成轮廓的速度?(目前还在摸索中),其它模块关闭之,在ftmodule.h中配置. (后编辑:果断去掉autofit模块,少点代码,都会提高一点效率) 2.关闭FreeType库的ASSERT,FT_UNUSED,在ftoption.h仅保留AF_CONFIG_OPTION_CJK选项(使用东方字体必须的)和一些定义常数的选项,其它选项全关闭,可大幅度减小代码量, 3.RTGUI的draw_point效率问题,这个是硬伤,没太多办法了,当然最好是使用framebuffer_driver,如果是,可以优化宏 ```c #define GET_PIXEL(dst, x, y, type) \ (type *)((rt_uint8_t*)((dst)->framebuffer) + (y) * (dst)->pitch + (x) * _UI_BITBYTES((dst)->bits_per_pixel)) ``` 根据自己的LCD屏的参数,用固定的framebuffer,常数pitch,和常数bits_per_pixel替换对应参数,也就是跳过了访问(dst)的过程,这在频繁的写点操作中是非常有利的. 其它方面,所有dc函数中取消对dc的非空判断,这个工作在dc_begin_drawing之后判断一次之后,其实都是有效的了,所以之后使用dc绘图的函数无需判断.draw_point函数内部展开所有调用的函数(试过该措施改善很显著),如果其他朋友有好办法,请参与进来一起搞它. 4.文件系统,它的瓶颈也是很明显的,获取字体Face的过程就是读取文字信息然后生成轮廓并填充的过程,所以访问文件的时间也会影响到字体生成速度.措施是优化硬件访问接口,其它措施暂无. 5.默认打开FreeType使用的是FT_New_Face取得文字Face,这个函数是根据需要显示的内容随时访问文件;如果内存较充裕,可以使用FT_New_Memory_Face,它以流方式访问字体数据,可以先将字体文件读到一个缓存中,然后用该函数以stream方式访问字体文件,该方式可以适当提升效率,缺点是占有较大内存,刚开始读字体文件时会使用较长时间. 6.不使用GUI,这样画点时就无需判断太多与范围相关的东西,可以得到较高的效率,这或许是在低频MPU上使用FreeType的最佳方案,缺点是在非os下实现文件系统,对有经验的人来说,这似乎不是问题. 7.最麻烦的做法,自己重写一个简洁的矢量字体函数库,FreeType库的特点是使用了对象编程概念,封装了太多层数据,在嵌入式系统上,过多的指令意味着较低的效率 [s:188] .是否值得这么做呢 [s:189] .
bernard
2014-09-19
这家伙很懒,什么也没写!
单独画点必然非常低,而且效果也不会。直接用dc,可以支持抗锯齿 4088上跑确实效率挺低,很多地方需要优化
amsl
2014-09-19
这家伙很懒,什么也没写!
alpha函数的效率低了些,例如Blit565to565PixelAlpha(),功能是实现了,但是从进入函数,到离开函数,执行了太多指令,仅一个像素就消耗这么多,这也是效率低的原因,要想办法控制指令数量.函数调用也是一个开销.是否用宏语句 ---------------------------------------------------------------------------------------------------- 后编辑 刚分析了一下,这些开销是必须的,没办法省略了...
amsl
2014-09-21
这家伙很懒,什么也没写!
```c struct rtgui_rect { //rt_int16_t x1, y1, x2, y2; //原来的类型16位 rt_int32_t x1, y1, x2, y2; //使用32位 } ``` 将rect成员变量类型换成32位,相关函数的参数也改为32位,在ARM上绘图性能可以得到一些提升 测试在不优化的情况下,在2416上`800*480`整屏绘点可以从耗时`>4000ms`,缩短到`<3300ms` 建议RTGUI使用一个选项来切换这个类型 ----------------------------------------------------------- 后编辑 似乎可以借鉴pixman的做法,它就由用户选择是使用16位的还是使用32位的, 16位的版本在在嵌入式没有太大优势,节省的RAM有限.
amsl
2014-09-24
这家伙很懒,什么也没写!
写个总结贴,文中使用了伪代码描述, 移植FreeType成功用了1天,但是为了让它流畅的跑起来,用了10天也没辙,测试平台是S3C2416,开始也担心跑FreeType可能会比较吃力,没想到一语成谶了. 刷新频率设置为60fps,开启了G2D,使用了point,line,alpha, bitblt功能, 测试条件:800x480的fb,24bit模式,刷新整屏,win0未使用双缓冲,原先dc_hw_line用时>120ms,2D画线降到10ms以内,原先dc_hw_point用时>2500ms,2D画点也大于2300ms,基本没有提升,dc_client_point测试结果惨不忍睹,无论开启2D,耗时都在3500ms以上, win0开启双缓冲之后,不用看一个一个字绘制的那种纠结了.可惜绘图速度还是一样的,维护两个buf的一致性也是一大开销. 所以问题点依然是GUI的整体绘图效率,瓶颈是draw_point()接口. 天无绝人之路,尝试过各种办法之后,还是有点效果的,首先用前面3楼的方法进行一些手术, 使用万能的空间换时间大法,将常用的字体进行缓存,需要显示时先从缓存中查找,如果有则从缓冲中提取,否则从文件中读取,并加入缓存, 这个办法可以把效率提高一倍以上,缺点是缓存的大小是无限增长的,不适合显示文字太多的情况.不可控性总让人没底. 还有个有效的优化方法是,减少指针嵌套层数,每增加一级指针,就会多增加2~3条指令,代码中大量应用指针嵌套,必然降低执行效率, 例如a->b->c->d=0;和e->d=0;两种情况效率差很多. 关于dc_client_draw_point,它使用客户型DC,意味着需要绘图的控件被剪切过,所以需要先 用region_container_point(region, px, py, &rect)判断该点是否在控件的有效clip rect list之内,这个过程使得画点的效率降低了约30倍(pc上测试的结果),我想,把它的效率提起来,整体效率自然就提升了,pixman-region使用了二分查找法确定clip rect list中的某个rect,这个值得借鉴.这样改动之后,效率还是没有提起来,每次画点都还要进region_container_point,如果不进它就好了,需要在参数&rect上做文章,以前一直不理解这个参数是干嘛用的,现在我觉得它就是为了解决效率低下的问题而准备的吧. 绘制点的下一个点的坐标很可能就是x+1,或是y+1,总之上一个点和下一个点很可能是在同一个rect之内,这个概率应该大于95%,所以需要在region_container_point成功之后保存参数&rect,给下一次判断提供捷径.这个命题目前还在摸索中,希望伙伴们能一起来完善这个思路. 关于alpha blending,像_dc_get_bits_per_pixel(),_dc_get_pitch(),是否可以用dc的成员来代替, 这个话题可以延伸到整个GUI的实现,像bpp,pitch,colordepth这样的参数,GUI中很多引用都是实时计算出来的,这无疑增加了代码量,一个平台所用的屏幕参数是已知且固定的,那么对于GUI来说也是可以获取到固定参数的,类似环境变量的概念,比如,可以根据color depth定义rgui_color_t,从而得到固定的bytes_per_pixel,固定的bits_per_pixel和固定的pitch,如果不确定,可以在创建dc时确定下来,引用时可以直接访问到.这样GUI的整体效率也会得到提升.在低速MCU上这些措施比较有效. 这个帖子就到这里了,因使用freetype而引出的绘图效率问题,可以告一段落了,它让我对GUI又有了一次全面认识,加深了理解,也有一些意外收获,很充实,
bernard
2014-09-24
这家伙很懒,什么也没写!
为什么你那边会大量的进入client_draw_point(),不是应该是hw_draw_point()?
amsl
2014-09-24
这家伙很懒,什么也没写!
大量进入dc_client,是因为想实现一块画面上,悬浮着一些按钮的效果,这种画面很酷
bernard
2014-09-25
这家伙很懒,什么也没写!
如果是这样,我觉得有必要专门进行优化的,肯定得考虑跳过draw_point或以其他的方式进行绘图
amsl
2014-09-25
这家伙很懒,什么也没写!
熊哥你的意思是避开DC,使用一种新的模式?
撰写答案
登录
注册新账号
关注者
0
被浏览
5.2k
关于作者
amsl
这家伙很懒,什么也没写!
提问
12
回答
137
被采纳
0
关注TA
发私信
相关问题
1
有关动态模块加载的一篇论文
2
最近的调程序总结
3
晕掉了,这么久都不见layer2的踪影啊
4
继续K9ii的历程
5
[GUI相关] FreeType 2
6
[GUI相关]嵌入式系统中文输入法的设计
7
20081101 RT-Thread开发者聚会总结
8
嵌入式系统基础
9
linux2.4.19在at91rm9200 上的寄存器设置
10
[转]基于嵌入式Linux的通用触摸屏校准程序
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
【NXP-MCXA153】 定时器驱动移植
2
GD32F450 看门狗驱动适配
3
【NXP-MCXA153】看门狗驱动移植
4
RT-Thread Studio V2.2.9 Release Note
5
CherryUSB的bootuf2配置
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
PWM
freemodbus
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
编译报错
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
踩姑娘的小蘑菇
7
个答案
2
次被采纳
a1012112796
15
个答案
1
次被采纳
Ryan_CW
5
个答案
1
次被采纳
红枫
4
个答案
1
次被采纳
张世争
4
个答案
1
次被采纳
本月文章贡献
YZRD
3
篇文章
6
次点赞
catcatbing
3
篇文章
6
次点赞
lizimu
2
篇文章
8
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部