Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

疑似绘图效率偏低 #381

Closed
chnykn opened this issue Dec 14, 2024 · 11 comments
Closed

疑似绘图效率偏低 #381

chnykn opened this issue Dec 14, 2024 · 11 comments
Assignees

Comments

@chnykn
Copy link

chnykn commented Dec 14, 2024

src.zip

修改了Hello2D的代码进行FPS的测试,代码详见上述src.zip附件。

TGFX版本: 1.2.1
操作系统:Windows11 Home,23H2

上述代码测试500个Rect进行不间断移动,FPS只有30多。
类似的代码,使用Skia可以进行8000(甚至更多)Rect的测试,FPS可以达到100左右。

以上两者测试,都使用clang v19.1.3进行编译,均为Release设置;
TGFX的渲染效率与MSVC进行编译 没有差别,Skia用MSVC编译效率会显著降低。


水平有限,以及TGFX不够熟悉,不排除我的测试代码有问题,

@domchen
Copy link
Collaborator

domchen commented Dec 15, 2024

看了一下代码,初步的判断的原因是构造的用例比较特殊,你可以把Paint里的描边参数都去掉,改成填充Rect的方式再和Skia进行对比一下看看,应该会看到性能出现非常明显的变化。

解释一下原因:TGFX 本身也还在快速迭代开发中,很多的优化都是已知的但是需要有个优先级,我们的策略是优先优化更加接近实际业务场景下会普遍出现的调用方式。目前上层的业务场景要么是大规模简单图形的填充,要么是涉及描边的图形都会合并成一个Path并进行缓存,比较少遇到大规模简单图形的随机描边,这种还是偏向在测试场景下刻意去构造才会遇到,相比其他场景优先级就没那么高。所以目前简单图形的描边这块优化还没启动。目前描边都是直接转发给了复杂Path的绘制分支,这样也会导致无法进行draw call的合并。但这并不是最终的性能表现,后续如果加上简单图形描边的直绘能力,性能表现会和现在的简单图形填充接近,理论上像素更少可能还会更好一些。我们会在后续的排期里补上描边的优化。目前建议暂时可以先用简单图形的填充和Skia进行性能对比,这块的参考意义更大一些。如果填充这块还有差距我们会继续分析原因,至少优化到比Skia更好为止。

另外注意检查一下构造的Skia的用例是否是基于ANGLE运行的。TGFX目前在win平台是只能跑在ANGLE模拟的OpenGL上,也把Skia配置为使用ANGLE渲染对比就能确保是相同的测试条件了。 因为我们支持的平台特别的多,Windows平台优先级相比其他平台一直也偏低,最近已经排期开始会补上Windows平台原生的WGL后端支持。

@domchen
Copy link
Collaborator

domchen commented Dec 15, 2024

目前main分支的编译问题已经解决,建议还是使用最新的main分支进行测试。另外关于MSVC的问题,tgfx在Windows上只有用MSVC编译,并没有提供clang编译选项,第三方库编译也是只有msvc。这块不太一样的地方是tgfx设计为了纯GPU渲染架构,并没有Skia的CPU渲染模块,所以理论上用哪个编译器对tgfx的性能影响也并不明显。

@chnykn
Copy link
Author

chnykn commented Dec 15, 2024

您提到 “目前建议暂时可以先用简单图形的填充和Skia进行性能对比”,看来你认为代码中
paint1.setStyle(tgfx::PaintStyle::Stroke);
也是描边不是填充,实际编译出的效果的确就是填充,而不是边框,这可能也是一个Bug了。

另外,您提到的Clang的编译,那是因为Skia针对Clang有特殊的优化;TGFX因为不清楚是否也有,所以也进行Clang的编译测试的。

最后,Skia的测试,我也有编译为WASM、采用WebGL的方式,10000个Rect动态刷新也能达到80FPS。
根据我可能不太正确的感觉,WebGL应该与ANGLE 性能可能大致相当。

@domchen
Copy link
Collaborator

domchen commented Dec 15, 2024

你说的那个还是显示为填充的是个Bug,用main分支最新的代码进行测试就行,2.1版本是有这个问题。
不同平台性能差距会非常大,比如Web有没开启多线程,能使用的GL版本都会很大影响性能,要尽可能保证测试平台和环境是一致的对比才有意义。根据你的描述Skia的Web版本比它原生的性能还高,这个是非常违反常识的,无论哪个引擎Wasm版本性能一般只会大幅落后原生。

所以建议你把skia的具体测试项目也上传上来吧。我们分析一下你对Skia具体是怎么构造测试的。可能还是两边demo有部分测试条件没有完全对齐,这个要一起发出来才好对比。

@chnykn
Copy link
Author

chnykn commented Dec 16, 2024

"根据你的描述Skia的Web版本比它原生的性能还高,这个是非常违反常识的" 。其实,我针对Skia的测试,两者几乎是一样的。
因为,我没有直接在网页中,使用CanvasKit进行绘制(这种情况,性能的确降低30%左右,但FPS不稳定);

而是直接把原生(桌面版)的代码,直接编译进入了CanvasKit中。这种情况下,Skia的Web版(CanvasKit)与原生的几乎是一样的,都是10000个Rect接近80FPS,8000个Rect接近100PFS。

demo.zip
桌面端(原生)测试代码如上;定制的CanvasKit就不上传了,涉及改动太多。

原生Skia的编译参数如下:
bin/gn gen out/release --ide=vs --args='cc=\"clang\" cxx=\"clang++\" extra_cflags=[\"/MD\"] is_official_build=true is_debug=false skia_enable_tools=false skia_enable_android_utils=false skia_use_system_expat=false skia_use_system_harfbuzz=false skia_use_system_icu=false skia_use_system_libjpeg_turbo=false skia_use_system_libpng=false skia_use_system_libwebp=false skia_use_system_zlib=false skia_use_xps=false skia_enable_pdf=false'

Skia版本:m132
Clang 版本:18.1.8 (备注:不是昨天的 v19.1.3 了,因为更早编译的)
WinSDK版本:10.0.26100.0
开发工具:Visual Studio 2022 社区版(Version 17.12.3)
操作系统: Windows11 Home 23H2

@domchen
Copy link
Collaborator

domchen commented Dec 16, 2024

收到,我们分析一下看看

@domchen
Copy link
Collaborator

domchen commented Dec 16, 2024

你的这个 Skia demo 好像没有处理窗口的 pixelRatio,就是 main.cpp 里的 DPIAware() 相关设置,开启这个会适配窗口按照屏幕的高分辨率模式渲染。不确定你测试的设备屏幕缩放系数是多少,我本地的Windows设备这个系数是 2.5,也就说适配之后渲染的像素面积是原来的 6.25 倍,压力也是原来的 6 倍多。你可以检查一下两边 demo 测试的实际渲染分辨率是否一致,断点看一下最终传入给CreateWindow 那边的像素宽高具体是多少。这块要确保测试的时候渲染分辨率完全一致,以及测试用的矩形也不能是完全随机的尺寸,或者要随机到一致的结果。 我们已经把你最初的代码修改了一下适配了 main 分支最新的代码。可以直接检出tests/draw_rects分支的代码跑win目录下的工程进行测试。你也可以把 tgfx 里 main.cpp 的 DPIWare() 调用注释掉关闭高分辨率适配进行测试。

另外还有一个不同点,你给的这个Skia的测试demo跑的就是WGL的后端,而不是ANGLE。这里可能也会有明显的性能差别。我们正在构造一个mac平台下的tgfx和skia的相同对比测试,确保这些测试条件都是完全一致的,有结轮会同步出来,到时候把构建的测试代码也发出来。

@domchen
Copy link
Collaborator

domchen commented Dec 17, 2024

我们在 Mac 平台构造的测试 demo 和结果已经出来了,TGFX 和 Skia 两个 demo 都是根据你原版的测试用例还原的,并确保了OpenGL 后端和分辨率都完全一致(每次运行的矩形尺寸还是有一定随机性,但在量级非常大从概率分布来说基本可以忽略了),这次的测试结果参考性会比较准确了。源代码在这里:tests.zip

运行截图

TGFX Skia
tgfx_20k_60fps skia_2k_50fps
TGFX 渲染 20000 个矩形仍然可以保持 60 fps Skia 渲染 2000 个矩形已经开始掉到 50 fps

测试环境

测试机器:Macbook Pro 16寸(M2 Pro / 32GB)
操作系统:macOS 15.1.1
编译环境: XCode 16.1(Release)
窗口尺寸:2048*1440(width: 1024, height: 720, pixelRatio:2.0)
TGFX 版本:main 分支最新(ef445edee3335b3ee30bd79afea76c0419947401)
Skia 版本:chrome/m121 (chrome/m132的性能更差一些,相对于chrome/m121性能下降1%-3%)

Fill 模式

矩形个数 TGFX-FPS Skia-FPS
800 120 120
1750 120 60
2000 120 50
3500 120 30
5000 120 22
10000 120 12
20000 60 5.3
30000 30 4.7
50000 30 2.9
80000 20 2.1

Stroke 模式

矩形个数 TGFX-FPS Skia-FPS
500 120 120
1000 60 60
1500 30 45
2000 30 35
3000 20 23
5000 12 14.4
8000 7 9.1
10000 5.5 7.5
20000 3 4.0

测试结论

  • 填充模式下,TGFX 的渲染性能大幅领先于 Skia,Skia 在 60 fps 情况下只能渲染 1750 个矩形,而TGFX 可以渲染到 20000 多个,有超过 10 倍的显著优势。这个优势的核心来源前面也提到过,主要来自 TGFX 相比 Skia 做了更多的并发优化,目前 Skia 对所有矢量图形的栅格化都是在一个线程里串行阻塞完成的,而 TGFX 花了很长时间重构,将所有耗时操作都进行延迟化处理,因为延迟之后就可以极限利用多线程并发计算。这个架构优化不止会体现在绘制简单矩形上,复杂 Path 和文本的栅格化也会极限并发,甚至连 PathOp 相关操作在 TGFX 里也能实现并发。
  • 描边模式下,目前 TGFX 相比 Skia 接近但还略有差距。这个原因在前面解释过,因为上层业务很少大规模这么调用描边,优先级原因描边的优化还没启动,目前是直接转发到了复杂 Path 的绘制路径,并且也没有开启 Draw Call 合并。但是改成和填充一样的绘制方式后会和填充模式有比较一致的性能表现,预期也会大幅领先于 Skia。所以目前可以先参考矩形填充的性能表现即可。

后续优化

我们近期会排期加上对简单图形描边的优化,采用跟填充一样的绘制方式实现,并开始在 Windows 平台适配原生的 WGL 的渲染后端。之所以前面在 Windows 平台测试的结论和 Mac 平台有出入,主要的原因可能是测试条件不一致,TGFX 是跑在了模拟 OpenGL 的 ANGLE 后端上,而 Skia 采用了原生的 WGL,加上两个测试的渲染分辨率可能也不一致。这块可以等我们适配完 WGL 之后重新对 Windows 平台进行测试。目前 Mac 平台没有这些问题,两个引擎都是在最佳性能状态下进行的测试,结果是比较能准确反应两个引擎的渲染效率的。

另外我们也会开启构建一个开源的 benchmark 项目,专注用于对比 TGFX 和 Skia 在各个性能维度和其他接口的全面对性能对比,每个用例都会同时提供 TGFX 和 Skia 的等价版本方便大家自己进行测试。这个 benchmark 项目后面也会作为 TGFX 优化性能的基准线。也欢迎大家能贡献更多接近真实使用场景的性能测试案例给我们。

@domchen domchen closed this as completed Dec 17, 2024
@chnykn
Copy link
Author

chnykn commented Dec 17, 2024

感谢大佬的解惑,之前的确没注意分辨率、屏幕缩放方面。WGL与ANGEL对比,的确也有差异。

@chnykn
Copy link
Author

chnykn commented Dec 17, 2024

又看了一遍您的留言,晚点我再测一下。
祝大佬工作顺利,万事如意!

@domchen
Copy link
Collaborator

domchen commented Dec 17, 2024

也感谢你构造的测试用例,我们会收录到之后的benchmark项目里去。后续还有好的建议或优化欢迎反馈。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants