关于原生Label优化代码的若干问题

一个Label就发现这么多问题,值得深思、值得深思、值得深思!!!!!!

1赞

有理有据…官方接锅…顺便膜拜大佬…

就喜欢这种有理有据的喷 膜拜大佬

感谢各位大佬的督促. Label 原生的代码是我提交的, 抱歉给各位大佬带来困惑.

首先是更新说明我没说清楚.
之前原生 Label 有一个比较明显的问题: 通过平台的接口获取 TTF 字体的纹理. 在 Android 就意味着从 JS -> C++ -> Java(JNI) 这样的巨大调用代价. 改动后, Android 性能的提升主要是优化调用路径获得的, 而 iOS 平台的提升是通过 C++ 替换无 JIT 的 JS 代码实现的.

文本越大提升越明显. 如果文本比较少的话, 本身系统调用就少, 所以提升就不明显. 所以准确点的更新说明应该是

原生平台上使用 FreeType CHAR 模式渲染大段文本的 Label: 提升 Label 初始化速度,Android 提升 5 倍左右,iOS 提升 3 倍

更多的讨论参照 https://github.com/cocos-creator/cocos2d-x-lite/issues/2068

可以对比 examplecases 里的测试例 LargetSystemFontTextLargetTTFText, 感受到性能的提升.

大佬提到的其他问题:

说好的 提升5倍 呢?实际结果却比None还要差。例子都是很简单的,不会有使用姿势不对的问题。

这里提升 提升5倍 是相对于改动前的 CHAR 模式(大文本的情况下), 不是和 None 对比. 二者目标场景不同.

我使用附件工程测试在windows上测试, 新的实现 和 旧的实现 运行时间差异不大, ±5ms/310ms. 这应该是各个 Label 文本较少的缘故.

  • 问题1:类名拼写错误
  • 问题2:TTFLabelAtals重复调用init函数。
  • 问题3:LabelRenderer重复调用genStringLayout

确实存在冗余的调用, 修复后在win32上 提升 +30ms/310ms. :+1:

  • 问题3:CC_TTF_LABELATLAS_ENABLE_GC
  • 问题4:TTFLabelAtals_ttfFont的问题

这个两个问题的核心是字体纹理缓存的管理是交给 GC 还是交由开发者. 如果由开发者管理, 就需要提供额外的接口, 也只有开发者清楚什么时候释放字体纹理. 这会增加开发者的负担. 目前考虑是交给GC.
多数情况下, 字体纹理是能得到复用不会立即被释放的 (GC不总是立即的). 如果有开发者有明确的需求, 未来可以增加接口或者临时禁用这个宏 CC_TTF_LABELATLAS_ENABLE_GC.

不过 FT_Face 的缓存应该是可行的, 字体文件不像 Label, 数目相对有限, 可以考虑不释放. 导致的问题就是内存占用增加.

  • 问题5:LabelRenderergetString getFontPath

再退一步,因为某些原因不能做缓存,那么从getFontPath取出来值之后,应该通过函数传参的方式传递,而不应该每个函数重新调用getFontPath等。具体的函数是:render, renderIfChange, genStringLayout。

目前的 Label 已经在 JS 层和 原生层 都做了 flags 管理. 只有在文本/样式等方式变化时才会调用原生 render 的接口, 次数不多. 再多一层缓存的提升有限.

虽然上面这些问题没法解释为何性能没超过None模式,但举一反三,仔细检查FontAtlas等类,一定能找出问题所在。

CHAR 模式在文本较少的情况下 不优于 NONE.
CHAR 模式优势在, 没有最大字符/纹理的限制, 能够复用单字符的纹理.

说好了要受喷,其实我还是很温柔的,希望写C++层的代码要多多斟酌,毕竟要驾驭好C++,写出真正性能高超的代码并不是那么容易的

欢迎各位大佬多多指出问题, 这样引擎才能更快完善:+1:

总(自)结(责)一下

原生Label 中

  • 冗余调用
  • typo
  • 更新说明表述不够明确, 误导各位开发大佬

修复在 https://github.com/cocos-creator/cocos2d-x-lite/pull/2874

@colinsusie

5赞

好的我看看修改

另外没有带TTF的Char模式和None模式的显示效果不一样,Char模式显示出来是糊的,这个也检查一下吧

这个只有在真机上才能看出来,看找时间看看吧。

TTFLabelAtals 名字错误不改了吗,看着怪怪的。

官网的 2.4.0 更新说明,已依据上面的表述进行调整,谢谢大家反馈~

改改改改了

1赞

高手在民间

mark。。

mark flag

mark… 真机上char模式下文字大小不一的问题能看下不

apk版本 label自动换行英文单词会被截断! to被拆开了, 在H5中正常

真机字体会糊的问题,到现在还没解决。
目前采用的是 放大字号,然后缩小scale
。。。可是这种方法并不适用于分辨率低的手机上

字体糊的问题,确实引擎组一直没有解决。对于眼睛不敏感的人来说,感觉没问题,而我自己就是一个很敏感的人。在2.1.2中,自己修改引擎解决了这个问题,原理就是把字体纹理缩放(*设备物理分辨率/设计分辨率),保证纹理像素点和当前设备能够做到物理点对点,边缘处不能有拉伸,这样文字就清晰锐利,不会有边缘发虚的感觉。

受教了~谢谢大佬!我尝试一下!

准确的说,是底层写字的时候,对字体大小进行缩放。

大佬,能否给个修改的代码片段呢?

这个咋解决,char模式下有的字带描边,有的不带。导致一行字里面看起来粗细不一样

1赞