最近用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
阅读(2651) | 评论(0) | 转发(0) |