UE4:运行时获取UFont相关数据

最近项目中要排查运行时字体的使用和内存占用情况,稍微看了一下相关的东西,简单整理一下,目测没啥用

UFont相关类

去官网查了一些得知,UFont在运行时和非运行时有不同的缓存,运行时缓存包含了一些TTF文件,这些文件组合成了一个复合字体。
然后发现UFont有一个成员函数GetResourceSizeEx,继承自Uobject,大概看一下这个函数:

1
2
3
4
5
6
7
/**
* Get the size of the object/resource for use in memory tools or to display to artists/LDs in the Editor
* This is the extended version which separates up the used memory into different memory regions (the actual definition of which may be platform specific).
*
* @param CumulativeResourceSize Struct used to count up the cumulative size of the resource as to be displayed to artists/LDs in the Editor.
*/
virtual void GetResourceSizeEx(FResourceSizeEx& CumulativeResourceSize);

可以获得对象或者资源的内存使用情况,需要传入一个结构体FResourceSizeEx,那再去看一下这个结构体

就是专门给这个函数使用的用来计算资源内存使用情况的结构体

= =emmm,还得继续看下这个结构体的具体情况,一个一个看

  • ResourceSizeMode,资源占用内存情况的类型
    可以看出这个是枚举,我们去看一下这个枚举EResourceSizeMode,只有两个值
    • Exclusive,只显示这个UObject直接拥有的非UObject类型资源的内存使用情况,通常在runtime用
    • EstimatedTotal,包括本身和所有子UObject的独占资源和UObject序列化内存,但不包括外部引用或仅编辑器成员的内存。通常用在editor模式下。
  • DedicatedSystemMemoryBytes
    字面意思,系统专用内存,从系统专用内存(或者在一些统一内存类型的平台上交首选内存)分配给CPU资源的内存大小,单位是byte
  • SharedSystemMemoryBytes
    共享系统内存,从非系统专用内存(非首选内存)分配给CPU的
  • DedicatedVideoMemoryBytes
    视频专用内存,从专用视频内存(首选内存)分配的GPU资源的内存
  • SharedVideoMemoryBytes
    共享视频内存,非系统专用内存(非首选内存)分配给GPU的
  • UnknownMemoryBytes
    该资源所使用的内存是一个没有特别指定的内存区域

看到这里大概了解了,我们构建一个结构体FResourceSizeEx,第一个参数是内存使用情况模式,会影响到子UObject占用内存是否统计,后面是将具体的内存占用在哪个区域给分开了,分成了五个指定的内存区。

回到GetResourceSizeEx()函数,看一下结构体传进去会干点什么0.0
20220312220207
先判断了一下我们要查看的资源占用情况的类型,只有EstimatedTotal才会继续
= =但是在枚举中建议在运行时用Exclusive,行吧EstimatedTotal也不是不行,先继续看
创建了一个FArchiveCountMem,把自己传进去,通过GetMax方法拿到内存占用,添加到了结构体的系统专用内存的计数上
然后创建了子UObject的数组,获取所有的子UObject,在非编辑器模式下跳过检查分别再去调用他们的GetResourceSizeEx,全部放进传进来的FResourceSizeEx结构体中,这样子最后结构体里面的系统专用内存的值就是这个UObject占用的内存值了

再继续看UFont重载的对应方法
20220312220240
在调用了基类方法之后,注释说嵌套的Texture和FontFace是包含在subobject里的,需要用EstimatedTotal,看来UFont是得这么操作了
接下来判断了了字体缓存的类型,确定是RunTime,然后判断资源占用情况的类型
然后是一个lambda函数GetTypefaceResourceSize,先看一下这个函数的参数和作用。
参数类型是FTypeface,函数内遍历Typeface的Fonts(类型是FTypefaceEntry),获取到每一个Fontface
接下来这个if判断十分迷惑,条件是非FontFace并且加载方式是LazyLoad,那么会去获取Font的文件名,在通过FileManager的FileSize方法去获取一个FileSize,如果大于0加到系统专用内存里。那我要是成功获取了FontFace不是反而不会走进去吗,到时候return出来ResourceSize里面不都是0吗?
对默认的Typeface和子Typeface都做了上述操作。

Font.h中可以看到UFont的成员变量:
20220312220321
看一下FCompositeFont这个结构体有哪些东西,发现在非仅限编辑器模式下有三个变量
20220312220328


UE4:运行时获取UFont相关数据
http://muchenhen.com/posts/26550/
作者
木尘痕
发布于
2022年3月12日
许可协议