Chinaunix首页 | 论坛 | 博客
  • 博客访问: 271808
  • 博文数量: 95
  • 博客积分: 2047
  • 博客等级: 大尉
  • 技术积分: 1022
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-14 16:18
文章分类

全部博文(95)

文章存档

2013年(1)

2011年(94)

我的朋友

分类: 嵌入式

2011-08-30 23:08:54



最近用0xbench测试软件对2D进行测试,用Qualcomm的cortex A8跑0xbench所有的canvas 测试都有60FPS左右。但是一些低端设备,如S3C6410、TCC8900等ARM11产品,很多项目的分数都不尽如意,甚至只有个位数帧数,而且开不开2D3D加速都差不多。究其原因,Android 2D加速的面临一个问题,只能加速Opengl的接口,无法针对Skia库进行加速。
今天终于获取到运行0xbench的oprofile数据,基于TCC8900,以下列举占CPU1%以上的函数调用,可见skia库的函数占多数,这些函数均无法被GPU加速!
CPU: ARM V6 PMU, speed 0 MHz (estimated)
Counted CPU_CYCLES events (clock cycles counter) with a unit mask of 0x00 (No unit mask) count 150000
samples  %        app name                 symbol name
242313   13.0803  no-vmlinux               /no-vmlinux
173182    9.3486  libskia.so               SkRGB16_Blitter::blitRect(int, int, int, int)
171502    9.2579  libskia.so               blit_less_than_16_left
146735    7.9209  libskia.so               S32_Opaque_D32_nofilter_DX_gether
81697     4.4101  libc.so                  congruent_aligned32
77210     4.1679  libskia.so               SkRGB16_Blitter::blitH(int, int, int)
69659     3.7603  libskia.so               SkRGB16_Blitter::blitAntiH(int, int, unsigned char const*, short const*)
56494     3.0496  libcutils.so             android_memset32
52445     2.8310  libdvm.so                dalvik_inst
38848     2.0971  libdvm.so                common_invokeMethodNoRange
34478     1.8612  libskia.so               decal_nofilter_scale(unsigned int*, int, int, int)
25674     1.3859  libMali.so               /system/lib/libMali.so
23712     1.2800  libdvm.so                common_returnFromMethod
22207     1.1988  libskia.so               sk_fill_path(SkPath const&, SkIRect const*, SkBlitter*, int, int, SkRegion const&)
20735     1.1193  libGLESv1_CM_mali.so     /system/lib/egl/libGLESv1_CM_mali.so

来看
SkRGB16_Blitter::blitRect(int, int, int, int)
该函数主要调用
blend32_16_row(SkPMColor src, uint16_t dst[], int count)
通过固定的RGBA数据和RGB565的dst做混合,从函数中可见所有的计算都是通过CPU进行的。

static inline void blend32_16_row(SkPMColor src, uint16_t dst[], int count) {
    SkASSERT(count > 0);
    uint32_t src_expand = pmcolor_to_expand16(src);
    unsigned scale = SkAlpha255To256(0xFF - SkGetPackedA32(src)) >> 3;
    do {
        uint32_t dst_expand = SkExpand_rgb_16(*dst) * scale;
        *dst = SkCompact_rgb_16((src_expand + dst_expand) >> 5);
        dst += 1;
    } while (--count != 0);
}

想了一晚上应该如何针对这个函数优化:
没有给GPU留介入的接口,GPU用不起来(如果大改Skia框架应该也可以做到,不过看maillist中google也没做)
写了个汇编替换该函数,结果分数比原来还低
最终决定用牺牲效果的方法,将32位数据downscale为16bit数据计算,减少了几个32to16过程。

static inline void blend32_16_row(SkPMColor src, uint16_t dst[], int count) {
    SkASSERT(count > 0);
    unsigned r = SkGetPackedR32(src)>>3;
    unsigned g = SkGetPackedG32(src)>>2;
    unsigned b = SkGetPackedB32(src)>>3;
    uint32_t src_expand = (r << 11) | (g << 5) | (b) ;
    unsigned scale = (0x100 - SkGetPackedA32(src)) ;
    do {
        uint32_t dst_expand = (*dst * scale)>>8;
        *dst = uint16_t((src_expand + dst_expand) );
        dst += 1;
    } while (--count != 0);
}

竟然还有点效果
Draw Rect
FPS 10.33提升至13.33 30%提升
Draw Arc
FPS 18.0提升至20.0 10%提升

继续研究,有汇编参考,争取写个高效的汇编出来,可惜我的平台是ARM11,没有Neon,很多优化都不能用ToT。

Rockie Cheng
阅读(2616) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~