微软在 Windows 10中 面向通用 Windows 应用 (Universal Windows Apps, UWA) 新引入了一套用于用户界面合成的 API: Composition API 。Composition API 将使开发者使用更少量的代码在通用 Windows 应用实现更为炫丽的界面效果。本系列文章会对该套 API 的由来、用途以及使用方法进行介绍。
简单来说,Composition API 就是一套在桌面窗口管理器(Desktop Window Manager,下文简称 DWM)之上新引入的,面向通用 Windows 应用的用户界面合成 API。DWM 是一个利用硬件加速特性进行图形用户界面合成以及渲染的组件,最早在 Windows Vista 中引入。DWM 诞生的目的旨在提供更高性能的界面渲染以及更丰富的界面效果。需要指出的是,可能很多用户对 DWM 的印象就停留在 Windows Aero 视觉风格中的磨砂玻璃特效,但事实上 DWM 的能力远不止如此。
自 DWM 引入以来,用户在屏幕上实际看到的用户界面实际上是由 DWM 对来自不同应用程序的缓冲区数据进行合成生产的图像。DWM 基于 DirectX 利用显卡显存和 GPU 提供相比老式 GDI 渲染更好的性能来完成界面图形的和成和渲染。对于采用老式 GDI 方法进行呈现的应用,DWM 也会对其绘图方法进行映射。在 DWM 的渲染过程中,桌面实际上是一个全屏大小的 Direct3D 表面,桌面中的窗口则是由两个三角形构成的网格经变换成 2D 矩形。UI 框架作为纹理映射到这些矩形上。窗口过渡等各种效果则是通过 shader 处理、变换等过程实现的。
在 DWM 处理中,每个应用程序都有各自的缓冲区,应用将自身的界面图形数据写入自己的缓冲区,DWM 读取每个应用各自的缓冲区数据进行合成。DWM 使用非托管的媒体整合层(Media Integration Layer, MIL)将窗口描述为合成树 (composition tree) 中的合成节点 (composition nodes) 进行渲染。合成树表示了桌面以及其容纳的窗口,MIL 依照合成树按照从后往前的顺序对整个用户界面的内容进行渲染。有了 MIL 这种依靠合成树的保留模式 1 图形机制,应用就从刷新重绘这些工作中解放了出来。而自 Windows Vista 开始提供的诸如模糊、Flip 3D、实时缩略图等功能,都是依靠即时缓冲区、shader 等特性实现的。简言之,DWM 是由 DirectX 驱动的高性能新一代界面引擎。
在 Windows 8 中,微软引入了 DirectComposition API 。DirectComposition 组件使开发者能够进行高性能的位图合成,并附加变换、特效以及动画等各种效果,以此打造出更为复杂、生动、流畅的用户界面。DirectComposition 利用图形硬件的加速特性可以进行与 UI 线程无关的渲染处理,支持 2D 仿射变换、3D 透视变换等多种变换,以及剪切、不透明等基本特效。正如其名,DirectComposition 的设计受 DirectX 启发,但提供更为友好的方式供开发者使用,也让开发者更清晰地认识到 DWM 这一强大的合成引擎所能实现的效果。
不过,DirectComposition 是面向组建对象模型 (Component Object Model, COM) 构建的一套 API ,并不适合通常使用托管语言进行应用开发的开发者。实际上在 DirectComposition 的 MSDN 文档里明确写道:
The DirectComposition API is intended for experienced and highly-capable graphics developers who know C/C++, have a solid understanding of the Component Object Model (COM), and are familiar with Windows programming concepts.
即,DirectComposition API 适用于熟悉 C/C++、COM的图形处理开发者。
现在,随着 Windows 10 的到来,开发者有了新的选择: Composition API。Composition API 基于 Windows 运行时 (Windows Runtime, WinRT) 构建,在整合 Direct2D 和 Direct3D 的立即模式 2 图形能力的同时,提供了保留模式的视觉树机制,实现了效果丰富、支持动画的高性能界面合成渲染。Composition API 面向 通用 Windows 应用,通过 Windows.UI.Composition 命名空间提供。这意味着,开发者可以使用任何一种通用 Windows 平台 (Universal Windows Platform, UWP) 语言(C#, JavaScript, C++/CX 或 Modern C++ 等)在 UWA 应用中使用,并在所有 UWP 平台设备(PC、平板、手机)上(几乎)无差别运行。
Windows.UI.Composition
是声明式、保留模式的 API。它不仅可以与如今广泛使用的 XAML 结合使用,也可以脱离 XAML 独立使用。这意味着开发者如今可以以更为灵活的方式,使用自己最熟悉的语言,整合 XAML、DirectX 的各种特性打造现代 UI。下图展示了通用 Windows 应用使用 XAML、Composition API 以及 DirectX 进行渲染的层次结构:
借助 Composition API,开发者可以在基于 XAML 的应用中随时从框架层深入至视觉层应用更为复杂的图形效果。
Composition API 除了提供一套视觉树机制外,还提供了以下特性,这些特性将在后文逐一做详细介绍:
Composition API 支持实时特效,特效可以动画化、自定义、链接。特效效果包括 2D 仿射变换 (2D affine transforms)、算数合成(arithmetic composites)、混合 (blends)、色源生成 (color source)、二图合成 (composite)、对比度调整 (contrast)、曝光 (exposure)、灰阶 (grayscale)、伽马转移(gamma transfer)、色调旋转 (hue rotate)、反相 (invert)、饱和度调整 (saturate)、褐色化 (sepia)、色温调整 (temperature)以及着色 (tint)。
Composition API 包含了一套表达式化、框架不可知的动画系统。该系统支持两类动画:关键帧动画以及表达式动画。动画可以用来移动视觉元素,将变换、剪切或特效等动画化。该动画系统直接运行于合成器进程,从而确保了动画的平滑和伸缩性,使大量不同动画的并发成为可能。
点击上图可查看大图
如图所示, CompositionObject 是 Composition API 的核心基类。它实现 ICompositionObject
接口,表示视觉树中的一个节点。
由 CompositionObject
类派生出了以下主要类型:
ContainerVisual
派生出 SpriteVisual 。后文详述。 Windows.UI.Composition
包含一个实现 ICompositor
接口的合成器类 Compositor ,该类扮演创建合成对象的工厂角色,负责创建视觉树种几乎所有操作对象,MSDN 文档对其描述为“管理应用与系统合成器之间的会话。”
保留模式:图形 API 可以分为保留模式和立即模式两类。保留模式 API 是声明式的,应用从形状、线条等图形基元构建场景,将场景抽象成一个图或树的模型保存在内存中。当要绘制一帧画面时,图形处理将场景变换为一组绘图命令。在帧间,图形处理库回将场景保留在内存中。要渲染更新的内容,应用会发送更新场景的命令——例如添加或删除一个形状。之后图形处理库负责重绘场景。保留模式更为直观,更容易操作,因为诸如初始化、状态管理、资源清理等很多底层工作都由 API 负责实行了。但保留模式 API 缺乏灵活性,因为它是用自己的场景模型,很多特性可能并未公开。另外,因为其提供了通用的场景模型,保留模式 API 可能会有更多的内存占用。↩
立即模式:图形 API 可以分为保留模式和立即模式两类。立即模式 API 是过程式的。每次有新帧进行绘制,应哟个都会直接发送绘图命令。图形处理库并不会储存场景模型,而是由应用自行管理场景。相比保留模式,立即模式 API 因为能够进行针对性优化,因而在性能上可以实现更好的表现。↩
某些术语如 "Sprite",有部分资料翻译为精灵,个人以为不如保留原文不翻译,翻译后可能会造成误解,故本系列涉及到的概念、术语视上下文酌情翻译或不译。一般指某一类型、接口时直接使用类名、接口名原文,否则酌情翻译为泛指的中文,比如 "Visual" 特指类型时使用 Visual
,一般叙述翻译为视觉元素。