用户的host端场景数据,在渲染的资源准备(上传到device)完成后,如果没有从host端使用的需求,那么就应该在host端释放。用户的场景数据中,贴图和mesh是主要的内存消耗,其中贴图基本上是没有任何host使用需求的,mesh如果采用gpu pick的技术,也亦没有host端pick的使用需求。释放这些资源是非常基本的优化。
host的渲染数据释放,并不是简单的在gpu数据生成之后释放这么简单。实现完备的渲染器,特别是需要支持web平台的渲染器,需要考虑device重建的问题。device需要重建意味着gpu数据需要重新生成,意味着host数据在重新生成时处于available的状态,意味着host数据本身也需要支持重建。
从这个角度出发,可以认为用户需要表达的场景数据,并不应该是简单的host数据,而是应该支持「重建」的host数据,或者说是数据的访问的接口,而不是数据本身。因为全量数据没有高度可压缩的假设,所以优化host的内存的方式,一般只能是存储在网络或者磁盘上,所以这样的数据重建接口是异步的。它返回一个获取全量数据的Future
考虑到数据重建接口的异步特征,可以进一步的统一认为:数据的初次访问也具备异步特征。所以渲染器的gpu数据本身天然就应该实现为异步的流式的。必需的结构性质的数据同步加载,实际的内容数据异步载入,并实现业务上的降级表现。
用户的场景数据有可能是直接生成的,而不属于任意一种「异步可重建」的数据形态。基础实现应该提供必要的基础设施,以让用户能够将任何数据转化为异步可重建的数据。这样的工具函数需要让用户提供必要的序列化和反序列化细节(其中包括压缩和校对的细节),同时需要保证经过这样的转化之后,在首次使用不会导致额外的成本(因为数据原本就是可用的)
我们可以简单的认为url或者path就是异步可重建的数据。所以假设我们要优化texture的场景api,使其具备host数据释放能力。我们应该提供一种新的texture api,让用户提供texture资源的url或者磁盘路径。
gpu系统维护一个pool,并发的请求和加载texture数据到gpu。全程没有持久化的host texture数据。
用户生成的texture数据,可以让用户使用createObjectURL createObjectPersistPath的方式转化为保证在程序后续运行阶段在磁盘或者网络上持久化的的数据源头。用户采用当成生成的url填写场景信息。实现层面作出优化使得新创建的url并不会立刻删除内存来保证首次使用不会导致额外的成本。