管理设备资源
更新:2007 年 11 月
在托管 Mobile Direct3D 编程中有两种基本类型的资源:设备重置时需重新创建的资源和不需重新创建的资源。在设备重置后,有多种对象类型可能会被数据填充,也有多种类型不会被数据填充。与桌面计算机应用程序中的 Direct3D 不同,用于创建资源的内存池不是决定某种资源是否在设备重置后必须进行重新创建的因素。
内存池
托管移动 Direct3D 编程中有三种可用的内存池:
系统
在移动设备上的常规系统内存中分配,通常比使用视频内存慢。
视频
分配主要供移动设备上的视频硬件使用的内存区域。在有些设备上,视频内存可能是高度受约束的资源。
托管内存
分配视频内存作为系统内存的缓存。驱动程序可以使用多种算法来实现缓存方案,包括 LRU(最近最少使用的)替换算法。
在托管池中创建纹理或其他资源时,系统内存池中将为该纹理分配空间。使用 SetTexture 方法将该纹理分配到纹理贴图层后,该纹理将被上载到视频内存池并保存到池中,直至其变为最少使用的项并最终退出池以便为其他资源腾出空间为止。当需要在视频内存中腾出空间以加载托管图面,并且没有任何项满足 LRU 定义时,驱动程序应该使用 Priority 属性确定要从视频内存剔除什么托管内存资源。
可以在托管池中创建 VertexBuffer、IndexBuffer 和 Texture 资源,但是不能创建前置和后置缓冲区、深度缓冲区和图像图面。
可以使用 SurfaceCaps 结构的实例确定在创建资源时哪些内存池是可访问的。
移动设备能够支持不同类型的资源的不同内存池。显示驱动程序使用 SurfaceCaps 的 SupportsManagedPool 属性来指示其对托管资源池的支持。如果此属性为 true,则该设备支持 VertexBuffer、IndexBuffer 和 Texture 资源的托管池。如果驱动程序不支持托管池,则应用程序不能从托管池创建图面。如果设备同时支持将系统和视频内存池用于纹理,则应用程序可以使用 UpdateTexture 方法实现自己的内存缓存方案。
该应用程序还可以使用 Resource 的 PreLoad 方法将图面强制预加载到视频内存中。此方法导致立即丢弃必需字节并加载图面。
最后,该应用程序还可以使用 Device 的 ResourceManagerDiscardBytes 方法强制托管的资源丢弃给定的字节数。此方法将需要丢弃的字节数视为一个参数。如果应用程序传递 0,则将丢弃视频内存中的所有托管字节。
所有控制资源管理器的方法都会立即执行,它们不会缓冲到命令缓冲区中。如果设备不支持托管池,这些方法就会失败。
对象实例和生存期
当管理设备进行重置并且在使用索引缓冲区或顶点缓冲区时,您必须使用适当的构造函数,以便创建具有适当的生存期的对象。
Windows Mobile Direct3D 在 Smartphone 或 Pocket PC 上一次只支持一个 Device 实例。您可以使用 Manager 的 ReleaseD3DMobile 静态方法移除所有 Direct3D 设备资源,以便可以在相同的 Pocket PC 或 Smartphone 上启动另一个 Windows Mobile Direct3D 应用程序。
重置 Device 后必须重新创建以下对象。可以在 DeviceReset 事件的事件处理程序中进行重新创建。
Texture 对象。
Mesh 对象。
Surface 对象。
使用 VertexBuffer(Device, Int32, Usage, VertexFormats, Pool) 构造函数创建的 VertexBuffer 对象。
使用 IndexBuffer(Device, Int32, Usage, Pool, Boolean) 构造函数创建的 IndexBuffer 对象。
重置 Device 后无需重新创建以下对象:
Font 对象。
Sprite 对象。
使用 VertexBuffer(Type, Int32, Device, Usage, VertexFormats, Pool) 构造函数创建的 VertexBuffer 对象。
使用 IndexBuffer(Type, Int32, Device, Usage, Pool) 构造函数创建的 IndexBuffer 对象。
Font 和 Sprite 对象会自动执行所有必要的操作来响应设备重置。
IndexBuffer 和 VertexBuffer 对象会在设备重置后自动重新创建其自身,但它们将不包含数据。您可以定义 IndexBuffer.Created 事件或 VertexBuffer.Created 事件的事件处理程序,以便在设备重置之后向索引缓冲区或顶点缓冲区填充数据。