合成图面
注意
对于 Windows 10 上的应用,我们建议使用 Windows.UI.Composition API 而不是 DirectComposition。 有关详细信息,请参阅 使用视觉层现代化桌面应用。
本主题介绍 directComposition 支持Microsoft的图面类型。
DirectComposition 逻辑图面
DirectComposition 公开 IDCompositionSurface 对象来表示逻辑组合图面。 DirectComposition 公开可用于创建、更新和删除这些逻辑图面的 API。 每个图面都可以与一个或多个视觉对象相关联。 应用程序负责管理逻辑图面的生存期。
更新逻辑图面
应用程序可以通过调用 BeginDraw 并在应用要更新的逻辑图面上指定矩形的大小和偏移量来更新逻辑图面。 DirectComposition 分配指定大小的矩形,然后返回应用程序绘制或更新所需的图面和相应偏移量。 更新矩形的限制受图面大小的约束。 例如,40 到 100 像素图面的更新矩形最多可以 (0,0,40,100)。 此外,可更新区域由防护矩形强制实施。 由于一次只能有一个防护矩形,因此一次只能更新一个逻辑图面。 如果 EndDraw 或 SuspendDraw 之前 调用 beginDraw后,BeginDraw 将返回错误代码。 应用程序可以将提交调用添加到批处理 BeginDraw,但在调用和提交 EndDraw 之前,它才会生效。
暂停对逻辑图面的更新
需要更新不同图面的应用程序可以在当前更新上调用 suspendDraw,然后调用 BeginDraw 开始新的更新。 Microsoft DirectComposition 允许多个更新,但一次只能有一个更新处于活动状态。 这意味着,需要在一个图面上调用 suspendDraw 或 EndDraw,然后再对下一个图面调用 BeginDraw。 与 EndDraw不同,提交的批处理可以包含处于 SuspendDraw 状态的图面,但在调用 EndDraw 之前,不会在屏幕上显示此类更新。
恢复逻辑图面的更新
应用程序可以通过调用 ResumeDraw来恢复对处于 SuspendDraw 状态的图面的更新。 此方法只能在挂起的图面上调用。
结束对逻辑图面的更新
调用 EndDraw 和 提交 是在屏幕上查看位图更新更改的唯一方法。 每次调用 EndDraw 都必须有相应的调用来 BeginDraw 才能删除防护矩形。 逻辑图面将保留所有更新,直到调用 提交。 还可以在处于 suspendDraw状态的图面上调用 EndDraw,因为 EndDraw 是隐式恢复/结束。 调用 EndDraw后,更新的内容会显示到屏幕并丢弃,以便更新的内存可以重复使用以供以后更新使用。
使用逻辑图面的示例
以下示例介绍应用程序在创建由两个视觉对象组成的可视化树时需要执行的步骤,然后需要更新与视觉对象关联的两个逻辑图面的特定区域:
- 创建 DirectComposition 设备。
- 创建由根节点和视觉对象 1 和 2 组成的可视化树。
- 创建逻辑图面 1 和 2。
- 调用 SetContent,将逻辑图面与视觉对象 1 和 2 相关联。
- 在逻辑图面 1 的子矩形上调用 BeginDraw。
- 在 DirectComposition 返回的偏移量处更新图面。
- 可选步骤:
- 在逻辑图面 1 上调用 SuspendDraw。
- 在逻辑图面 2 的子分区上调用 BeginDraw。
- 在 DirectComposition 返回的偏移量处更新图面。
- 在逻辑图面 2 上调用 EndDraw。
- 在逻辑图面 1 上调用 ResumeDraw。
- 在 DirectComposition 返回的偏移量处更新图面。
- 在逻辑图面 1 上调用 EndDraw。
- 调用 提交。
DirectComposition 虚拟图面
DirectComposition 公开 IDCompositionVirtualSurface 接口来表示虚拟图面,它是在固定网格中排列的逻辑图面(磁贴)集合,其磁贴大小固定。 应用程序指定创建时虚拟纹理的大小。 大小为虚拟图面建立边界。 图面可以与一个或多个视觉对象相关联。
初始化虚拟图面时,它不受实际分配的支持。 换句话说,它不保留任何位。 DirectComposition 在应用程序开始更新图面后分配磁贴(即合成图面对象)。 应用程序通过调用 BeginDraw 并指定虚拟图面坐标感兴趣的区域来更新虚拟图面。 然后,DirectComposition 分配必要的磁贴来保存更新,并返回要更新的合成图面和偏移量。
与逻辑图面一样,可以在虚拟图面上调用 BeginDraw、SuspendDraw、ResumeDraw 和 EndDraw。 此外,DirectComposition 还公开了可用于调整和剪裁现有虚拟图面的方法。
调整虚拟图面的大小
Resize 方法更改虚拟图面的边界,这意味着任何新的更新或分配都必须属于由新大小设置的边界。 应用程序使用 调整大小 告知 DirectComposition 不再需要虚拟图面的特定区域,并且可以回收。 如果 调整大小 缩小虚拟图面,应用程序将无法再更新新边界之外的区域。
下图显示了调整为 2 到 2 的 3 个虚拟图面。 红色区域表示作为调整大小作的一部分丢弃的磁贴,并且由 DirectComposition 回收内存。 重设大小后,应用程序无法更新红色区域,而无需重新调整虚拟图面的大小。
调整大小作将立即生效。 DirectComposition 不会等待应用程序调用 提交 进行调整大小更新。 例如,假设应用程序发出以下调用序列。
pVirtualSurface->Resize(0, 0);
pVirtualSurface->Resize(INT_MAX, INT_MAX);
pDevice->Commit();
在此示例中,应用程序在第一次调整大小时会丢失所有内容。 即使 提交之前调用了第二个大小,第二个调整大小也不起作用。 在这种情况下,屏幕上不显示任何内容。
剪裁虚拟图面
Trim 方法标识应用程序所需的虚拟图面区域。 它不会调整虚拟图面的边界大小,但会告知 DirectComposition 当前需要分配哪些逻辑图面。
在下图中,绿色方块是应用程序的视区。 应用程序最初呈现到视区中虚拟表面的前六个磁贴(蓝色)。 当虚拟图面所表示的页面滚动时,应用程序需要呈现最后六个磁贴。 应用程序调用 Trim,以指示最后六个磁贴定义的区域是内容所在的位置,而目前不需要其余部分。 然后,DirectComposition 可以选择回收最初表示前六个磁贴(深灰色)的逻辑图面。
相关主题