GDI/GDI+/D2D/D3D

Windows7通过Direct2D等新技术提升了2D图形处理性能,并改进了GDI的硬件加速支持,使得日常应用更加流畅。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文链接 : 2D Drawing APIs in Windows

    在 Windows 7 操作系统中,微软花费了很大的力气构建了一套新的 2D 绘图 API。我们称之为 Direct2D ,隶属于 DirectX 家族。这个 API 的开发填补了 Windows 图形平台的一些缺陷。其中非常重要的一点就是普通的 2D 程序渲染不再缺乏硬件加速。而在 Windows Vista 中,我们知道 GDI 是无法进行硬件加速的。微软寄望于开发的这个 API 具备很多现代特性。比如支持抗锯齿和 Alpha Blend 的 2D 渲染,和其它现代图形 API 交互,服务器端渲染,诸如此类。

    为了方便理解微软为何开发 Direct2D ,我们先来回顾一下当初开发 Windows 时的历史。最初的渲染系统叫做 GDI (图形设备接口),今天仍然存在。它最初为 16 位 Windows 写就,随后升级到 32 位 Windows (Windows 95 和 Windows NT)。因为 GDI 是为很久以前那些计算能力低下的计算机而开发的,所以它并没有诸如抗锯齿之类的特性,大多数 API 亦不支持 Alpha 通道。

    在 Windows 95 期间,DirectX 发布了第一版。DirectDraw 是其中最早的组件之一。当初的本意是在硬件加速启用的情况下,开发人员可以绕过 WinG 允许,直接访问硬件。这样的一个协议堆栈既可以和 GDI 协作,但是又真正处在同一地位。

    随着图形硬件(显卡)演进,GDI 通过 DDI (设备驱动接口) 获得了硬件加速的能力。很多视频卡实现了这些 DDI ,而通过购买一块视频卡来改善你的 Windows 性能亦成为平常之事。接下来,Direct3D 进驻到 DirectX 2 中,当然它也创建了自己的 DDI 集。随之,视频卡开始投入越来越多的精力来使得 3D 图形越来越快,以便维持游戏市场巨大的需求。最后导致诞生了两个不同的领域 : 硬件加速和图形编程。前者围绕于 Direct3D 构建,后者则围绕于 GDI 。

    Direct3D 和 GDI 构建于不同目标,不同位置的事实意味着它们并不能像人们期望的那样能够良好的工作在一起。虽然实现了不少像 GetDC 这样的帮助桥接特性,但是在大量交叉渲染的场景下它们总是存在着或这或那的一些问题。尽管如此,微软并没有移除这些待解决的场景需求。

    到了世纪之交,GDI 的限制越来越显现。微软针对这些功能缺陷做了一个 GDI 扩展,即 GDI+ 。这些扩展提供了诸如位图操作,画笔,抗锯齿和越来越复杂的 Primitive 渲染中不同像素深度格式,Alpha Blend 的支持。同时,GDI+ 亦包括了诸如打开 Png 和 Jpg 格式文件的图像操作支持。然而,GDI+ 新增的全部操作都没有硬件加速支持。

    GDI+ 在托管世界中非常流行,这主要得力于它是 System.Windows.Drawing 命名空间的主力。每一个客户自定义渲染的非常漂亮的 Windows Form 程序都使用 GDI+ 来当此大任。但是,构建于 GDI 之上的 GDI+ 同样继承了与 Direct3D 交互的所有问题。事实上,因为它总是软渲染,在某些场景下,它会变得更糟。

    当时间走到计划研发 Windows 7 时,很明显,微软需要解决很多互操作性的不足,以及不平衡的硬件加速能力。保留现有的 API 且要达到上述目的是相当困难的事情。GDI 有很长的历史,这需要应付海量的应用程序兼容性问题。如果要把 Alpha Blend 支持(举例) 弄进 GDI 核心 API 集合,而且还不得罪现有的客户无异于天方夜谭。因为 GDI+ 构建于 GDI 之上,旧有的陋习同样让它获得硬件加速能力变得难以实现(文中说的GDI没有实现硬件加速是指在Win7之前,Win7已经实现。)。

    解决方案就是创建新的 API 来囊括我们想要的功能和处理互操作性问题。MIL 代码(WPF 处理渲染的原生组件)是一个很方便的起点。它有着我们想要的渲染特性,而且同时提供了软件渲染和硬件加速。

    首先需要做的事情是使渲染代码基于 D3D 10.1 ,而不是 D3D 9 。之所以这样决定是因为有一些构建于这个运行时版本的其它技术把 D3D 10.1 作为基础(10Level9,WARP,D3D Primitive Remoting)。而且我们还可以看到未来的硬件同样构建于这个架构之上。这样就能允许我们来设计 D3D 10.1 互操作性。因此就能允许与其它技术交互,比如 Direct2D 。

    另外一个互操作性工作就是利用窗口管理器和 DXGI ,以确保 Direct2D 和 GDI 能够共同工作。你可以使用 Direct2D 绘图到 GDI 目标,同理,反之亦可。 但是,从性能的角度来看,这些特性并非免费。它只是让那些构建在这两种混合 API 上的应用程序能够平滑过渡到新世界。

    前面所作的工作中很重要的一块就是尽量使得此 API 在性能方面富于表现力。对于开发人员来说,WPF 的好处在于它做了很重要的资源管理工作,但却使得直接控制硬件变得困难起来。这听起来貌似很简单,但是这背后有着大量的设计决定以确保 GPU 内存没有分配给不需要之人,且仍然能够允许人们构造他们之所想。因此遵循了这样一个原则的 Direct2D 设计和资源/线程模型就能够允许服务器端渲染进行合适的伸缩。GDI 却不能。

    此外,对于处理文本和图像可以分别采用 DirectWrite 和 WIC 。这表明了微软 DirectX 家族正更加组件化。Direct2D 以一种互补的方式对 DirectWrite 文本和 WIC 位图操作提供硬件加速支持。

    最后想说的是,我们构建了一个支持硬件加速的 2D 渲染 API (带有软渲染)。它有着现代渲染原语集合,能和以前的 API 进行交互。我们认为它完全可以取代作为大多数应用程序开发场景所使用的 GDI/GDI+ API ,而且也可以作为某些游戏开发场景中 D3D 10.1 的补充。微软构建的这么一套组件化的技术集合完全允许开发人员混合搭配以构造以前难以构造的事物。比如把已定位的文本像素直接渲染到 Direct3D 纹理当中,而不需要任何字体的支持。

二:

深度解读 - Windows 7核心图形架构细致分析

编辑:马志文

时间: 2009-12-29

连接:http://technet.microsoft.com/zh-cn/library/ee921514.aspx

如现在大家所想的那样, Windows7 其实是 Windows Vista 的改进版。 Windows 7 在 Windows Vista 的基础上进行了大量的完善工作,也加入了不少新特性。 Vista 与其上一代 XP 相比,提供了非常大的改进,然而一方面这些改进过于巨大,用户乃至相应软件厂商(如, DirectX 10 应用开发商)一时无法完全接受,另一方面,由于特性的不完全具备, Vista 的表现没有想象之中的那么好。到了 Windows 7 ,包括操作系统本身、软件厂商和用户都已经做好了准备,因此反响比 Vista 更好也就不难理解了。

图形界面一直是 Windows 系统的核心,而从 Windows Vista 开始, Windows 就开始将提供一个富图形化的桌面图形界面作为要目,不仅仅是因为 Vista 和 7 的桌面本身就是一个 3D 应用程序,而是因为 Vista 和 7 可以更好地发挥图形加速硬件的作用。从 Windows Vista 到 Windows7 ,操作系统与 GPU 的结合越来越紧密。

 

虽然人们经常可以听到 Windows7 的大更新在于一个 DirectX 11.0 API ,然而对于 Windows 系统的图形架构来说,虽然 DirectX 也很重要,不过这还不是全部。一个图形架构包括了如何利用 GPU 加速各种各样的图形应用( 2D 、 3D 、打印等)、如何显示到最终显示设备上,以及包括设备检测、控制。 Window 7 在图形架构方面的更新主要有如下方面:

WDDM 1.1 :新的驱动模型
DirectX 11 :更新的 Direct3D 11 ,以及相关的新 Direct2D API
DXVA-HD :高清视频回放加速
显示设备连接和配置
色彩管理
高 DPI 输出和可读性
多 GPU 系统
联合显示适配器(又叫联合渲染)

下面,会就这些改进进行简单的介绍。


Windows 7 核心图形架构

Windows 应用程序使用各种如 GDI ( Graphics DeviceInterface , 2D 时代系统的主要图形接口)、 Direct3D 、 OpenGL 这样的 API 和系统图形组件通信,而系统组件通过 WDDM ( Windows DisplayDriver Model ,又名 Longhorn Display Driver Model )与硬件交互,从 Vista 起, Windows 就采用了和 XP 使用的 XPDM 不同的新的驱动模型: WDDM ,使用的驱动模型在很大程度上决定了一个系统的图形特性。 Vista 使用的 WDDM 版本为 1.0 ,而 Windows7 使用的改进版本为 WDDM 1.1 。

 

WDDM 1.1 带来的改动挺多的,下面我们先来看看 WDDM 1.0 相对 XPDM 的改动,也就是 Vista 相对 XP 的改动

  
XPDM :非合成模型

 
WDDM :合成模型

  在垂直同步之谜 XP/Vista 与 3D 性能测试中,笔者解释过 XP/Vista 的模型的不同之处,在 WDDM 模型下,所有的应用程序生成的显示画面最后会在 DWM ( Desktop WindowsManager ,桌面窗口管理器)内进行合成为单一的最后输出画面,因此获得了更好的显示效果(天生的所有程序垂直同步)、额外效果(缩略图、缩放)以及可以支持更大的左面,不过,原始的 WDDM 1.0 只是实现了这个大架构上的转换,细节上仍未够完美:

  

在 Vista 下, GDI (绘制通常的 2D 窗口的 API ,此外还有很多其他图形操作使用 GDI )和 DirectX ( 3D 应用 API )具有着不同的处理方法: Direct3D 是硬件加速的,而 GDI 则不是( GDI 在 XPDM 时是硬件加速的),因此 Vista 用户在一些图形程序上会感到比 XP 慢;而且 GDI 应用程序先经过 CPU 软件处理到系统内存上,再传输到显卡驱动分配的 GDI 显存区域上(也在系统内存当中),再由 DWM 负责将画面合成输出到显示器

Windows 7 当中, GDI 获得了硬件加速(这个见下面) —— 不过在混合使用 GDI 和 Direct3D API 的时候, GDI 仍然无法硬件加速,不过, GDI 直接输出到驱动的 GDI 显存区域,减少了一个步骤,同时降低了内存消耗(同时对混用的 Direct3D API 也有效);显然,混合食用 API 来进行图形编程并不是一个好主意(当然,同时使用 GDI 和 Direct3D 意味着这个是一个老的、窗口模式的 3D 应用程序,如 Windows 模式的老 3D 游戏)

老的 WDDM 1.0 处理 GDI 应用程序就如前面说过的一样

 

而在 Windows 7 WDDM 1.1 模型当中,单独的 GDI 将会通过 WDDM 与 GPU 进行硬件加速,同时经过 GDI 显存区域输出到 DWM ,表现在实际操作上,就是大部分窗口操作都变得比 Vista 更流畅,日常工作更快捷(大部分 2D 应用程序都使用了 GDI API ,因为 GDI 包括的内容太多,因此必须对其保持兼容;关于 GDI ,后面还有相关内容)


Windows XP 的Direct3D/GDI驱动架构


Windows Vista 核心图形架构,比起 XP 来要丰富了很多

Windows 7 核心图形架构,老的 GDI/GDI+ 仍被单独支持,不过, Windows 7 提供了它们对应功能的新的实现方法相比 Vista 带的 DirectX 10 , Windows 7 自带了 DirectX 11 ,和 WDDM 1.0 到 1.1 的变化不同, DirectX 11 的版本号表示其变化更大一些。 Windows 7 DirectX11 改变了以往的工作模式,将 Direct3D 10.1 升级到 Direct3D 11 ,同时将以前 Vista 无法硬件加速的 GDI/GDI+ 的工作重新划分、引入新的 Direct2D 和 DirectWrite API 来完成:

以前的图形操作大部分由 Diredt3D 和 GDI/GDI+ 完成(此外还有一个 WIC——Windows Image Component ,管理扫描、打印和图形解码等工作),而在 Vista 当中, GDI 是无法硬件加速的 —— 因此 Vista 显得很慢,在 Windows 7 中, GDI 的工作除了通过 WDDM 模型的改变获得硬件加速之外,它们还按照面向的应用重新划分为 Direct2D ( 2D 加速)、 DirectWrite (文本处理)和 DXGI 1.1 (设备控制),这些新的 API 或者新分配到的 API 具有着硬件加速,例如, Direct2D 就实际上是通过 Direct3D 10 来完成加速:

Direct2D :
硬件加速的即时模式 2 维图形 API ,它在 2 维几何图形、位图和文本方面有着较高的性能和质量。 Direct2D API 是设计与 GDI 、 GDI+ 和 Direct3D 之间进行互操作的。

DirectWrite :
DirectWrite 提供高质量的文本呈现、具有独立分辨率的轮廓字体、完整的 Unicode 文本以及布局支持。在使用 Direct2D 的时候, DirectWrite 是硬件加速的。

当系统不支持 Direct3D 10 的时候, Windows 7 会通过一个额外的 10Level9 软件层使用 D3D9 来完成工作,显然,为了最好的效率,你需要使用 Direct3D10 的显卡,因为 Windows 7 的 DWM 基于 Direct3D 10


字体抗锯齿: DirectWrite 效果


Direct3D 11

Windows 7 带的 Direct3D 11 是 D3D10 的超集,它的特点是可以同时支持运行在 Direct3D9 和 Direct3D10.1 硬件上,实际上, DirectX 11 会提供 Vista 的支持,而不是像 Direct 10 出来时那样,只支持 Vista 而无法兼容上一代系统,这导致了软件开发厂商们向 DirectX 10 转移的缓慢。 DirectX 11 支持多个硬件平台和多种操作系统的特性让其更容易被接受。同时 Direc3D 11 本身也具有这不少的改进,这一点会有专文讨论(计划中),这里先谈论 Windows 7 对整个图形操作的改进,通过更多地将 GDI/GDI+ 纳入 DirectX 体系获得硬件加速,图形界面的性能会越来越好(当然,这需要软件厂商们使用新的 Direct2D/DirectWrite 进行编写)。微软希望将所有的图形操作都构建在 DirectX 之上。

通过 Vista 中缺失的 GDI 硬件加速纳入到 DirectX 体系中重新获得硬件加速,并且性能要更快;未来显卡厂商们将不再需要提供 GDI 加速

显示技术  

Windows 7 支持一系列的显示技术,包括将数字输出作为原生输出(支持 HDMI 和 DisplayPort ,而老的 VGA 模拟输出被建议弃用), Windows 7 还原生支持更多的内容来源,如 Blu-Ray 、 JPEG-XR 、 HDR 图片等。

Windows 7 使用默认的 sRGB 色彩空间作为所有设备都统一的工作流,但是精度提升到 30 位 —— 每一个色彩通道都增加了两位; Windows 7 最高支持 48 位的 scRGB 模式,高精度+扩展范围+高动态

  
WDDM 1.1 要求驱动支持 BGRA , BGRA 是最快的色彩格式

显示设备连接和配置  


在 Windows 7 中,所有的应用程序都在一个统一的虚拟桌面中显示,这个虚拟桌面分辨率为 64Kx64K ( 65536x65536 )

虚拟桌面按照显示器分为不同的视图,每一个视图对应一个适配器;一个适配器并不意味着一块显卡,一块显卡连接多个显示器的时候,它就含有多个适配器,类似地, SLI 或者 CrossFireX 连接的单显示器就意味着其是一个单一的适配器(从 Vista 开始加入,叫做 Linked-Adapter 特性)


不过,在 Vista 下,无法使用多块不同 GPU 厂商的显卡,而 Windows 7 则可以  

在 LDA 配置下,程序界面在不同的输出中漫游基本上是透明的,叫做 Dynamic adapterswitching 动态适配器切换

在多显示器下, Windows 7 提供了一个新的全局快捷键功能: Win + P ,可以快速设置多显示器工作状态,这个快捷键本来是特地为了投影仪应用而设计

总的来说, Windows 7 的图形架构比起 Vista 来更加完善,应用也更加方便。最明显的就是 GDI API 的变迁了,现在 GDI 应用程序也获得了硬件加速,就如同 XP 下一样,比其 Vista 下只能处理器来进行处理,因此用户们可以感觉到日常应用会更加流畅。



#ifndef _RENDER_DEVICE_H_ #define _RENDER_DEVICE_H_ #ifdef _WIN32 #include "SystemDetector.h" //Win7 SP1必须安装补丁:KB2670838 才支持 D2D+D3D混合渲染 /*本模块渲染模式: *Win7 : 使用D2D + WIC + D3D10 + SwapChain混合渲染,交换链呈现内容 *Win8 : 使用D2D + D3D11 + SwapChain混合渲染,交换链呈现内容, 能兼容DComposition视觉树 *Win8.1 : 使用D2D + D3D11 + DirectComposition混合渲染,DComposition视觉树呈现内容 : 目前最强模式 *Win10 : 同8.1模式 * Win8兼容DComposition视觉树意义: 虽然最终呈现是SwapChanin的工作, 但DComposition提供了管理视觉树的功能 * 你可以将 DirectComposition(DComposition)的视觉树管理 粗略地类比为 Windows 7 中按 Win + Tab 显示的窗口切换器(任务视图),但它的功能和应用场景更加广泛和灵活。 * 进入了视觉树,说明你能很轻松就把动画效果做出来 */ /*Win7 性能瓶颈警告 * Win7 只支持D2D1.0版本,导致了无法与D3D共享显存,导致D2D+D3D混合渲染性能下降,但依然是win7最高性能,Win7如果想做D2D+D3D+SwapChain混合,必须经过CPU拷贝,但也比GDI+快 * Win7 如果放弃D2D+D3D混合渲染,则只能使用纯D2D绘制+虽然绘图过程可以使用D2D的功能,但最终渲染还是给CPU工作的。Win7下纯D2D绘图需要BindDC * 可以参考微软官网理论: https://learn.microsoft.com/zh-cn/windows/win32/direct2d/comparing-direct2d-and-gdi * win7 想做D2D+D3D+SwapChain混合,必须经过CPU拷贝,但也比GDI+快得多 * win7的绘图方案如下: * 方案 是否支持 GPU 加速 图像质量 开发难度 性能 适用场景 性能排名 GDI ❌ 低 低 低 老系统维护、简单控件 4 GDI+ ❌ 中等 低 中等 快速开发、非高性能需求 3 D2D + BindDC ✅(受限) 高 高 中等 少量高质量图形、混合 D3D 2 D2D + WIC + D3D10 + SwapChain ✅ 高 高 高 高性能 UI、混合 2D/3D 1 特别注意: D2D + WIC + D3D10 + SwapChain模式, D2D的上下文对象是不公开的,并且只有唯一一个,所以不能多线程竞争:BeginDraw() / EndDraw(); 绘图操作要自己进行同步 特别建议: 避免在 Win7 上使用多线程绘制 D2D 渲染目标,即使每个控件有独立的 CreateWicBitmapRenderTarget 哪怕你硬是成功获取了IDXGIFactory2对象,当你创建交换链时,会报错: XGI ERROR: IDXGIFactory::CreateSwapChainForComposition: Composition SwapChains are not supported on Windows 7.[ MISCELLANEOUS ERROR #137: ] 所以只能老实使用D2D + WIC + D3D10 + SwapChain模式 */ //注意性能: 高版本只是增加了特性功能API, 基础核心功能永远都在基础版本ID3D11Device中.性能差异:系统更新, 硬件支持,SDK 和运行时版本, API 调用方式, 多线程支持 #include <d3d11.h> //注意: 所有高版本并没有集成在 d3d11.h 中 /* 各版本的d3d11.h文件对应的系统版本:越高版本越多新特性,但我们的绘图需求不需要那么高版本,低版本能兼容更多系统 * d3d11.h = win7; * d3d11_1.h = win8; * d3d11_2.h = win8.1; * d3d11_3.h = win10(1507) * d3d11_4.h = win10(1709) * 微软已停止更新 D3D11:自 Windows 11 发布后,微软将图形开发重点转向 D3D12,不再为 D3D11 提供新特性。最高文件d3d11_4.h * 接口版本与对应的 DirectX 版本及 SDK 接口名称 对应的 DirectX 版本 引入的 Windows SDK 版本 引入的操作系统版本 ID3D11Device DirectX 11.0 Windows SDK v7.0 Windows 7 SP1 ID3D11Device1 DirectX 11.1 Windows SDK v8.0 (Win8 SDK) Windows 8 ID3D11Device2 DirectX 11.2 Windows SDK v8.1 (Win8.1 SDK) Windows 8.1 ID3D11Device3 DirectX 11.3 Windows SDK v10.0.10240.0 Windows 10 TH1 (1507) ID3D11Device4 DirectX 11.4 Windows SDK v10.0.10586.0 Windows 10 TH2 (1511) ID3D11Device5 DirectX 11.4 Windows SDK v10.0.14393.0 Windows 10 RS1 (1607) */ //注意性能: 高版本只是增加了特性功能API, 基础核心功能永远都在基础版本ID2D1Factory中.性能差异:系统更新, 硬件支持,SDK 和运行时版本, API 调用方式, 多线程支持 #include <d2d1.h> //注意: 所有高版本声明都集成在 d2d1.h 中 /* 各版本的d2d1.h文件对应的系统版本:越高版本越多新特性,但我们的绘图需求不需要那么多特性,低版本能兼容更多系统 * d2d1.h = win7 / vista; * d2d1_1.h = win8; * d2d1_2.h = win8.1; * d2d1_3.h = win10(1507) * * 虽然更新了新版本,但微软不再递增文件号了,所以最高文件为d2d1_3.h * d2d1_4.h = win10(1607) * d2d1_5.h = win10(1703) * d2d1_6.h = win10(19041) * ID2D1Factory 系列版本与对应系统/SDK 接口名称 对应版本号 引入操作系统 对应 SDK 版本 主要功能增强 ID2D1Factory v1.1 Windows 7 SP1 Windows SDK v7.1+ 基础 2D 图形渲染支持 实际使用win7是支持1.1版本 ID2D1Factory1 v1.1 Windows 8 Windows SDK v8.0+ 设备上下文、多线程支持 ID2D1Factory2 v1.2 Windows 8.1 Windows SDK v8.1+ 支持图像效果(Image Effects) ID2D1Factory3 v1.3 Windows 10 Windows 10 SDK v10.0.10240+ 性能优化、GPU 加速改进 ID2D1Factory4 v1.4 Windows 10 1607 Windows 10 SDK v10.0.14393+ 更多 GPU 渲染特性 ID2D1Factory5 v1.5 Windows 10 1803 Windows 10 SDK v10.0.17134+ 新增 D2D 与 D3D 的交互能力 ID2D1Factory6 v1.6 Windows 10 1903 Windows 10 SDK v10.0.18362+ 改进资源管理、图形性能优化 ID2D1Factory7 v1.7 Windows 10 20H2 Windows 10 SDK v10.0.19041+ 支持更复杂的 GPU 渲染流程 ID2D1Factory8 v1.8 Windows 11/Windows 10 21H2+ Windows 10 SDK v10.0.22621+ 与 D3D12 更好的集成、新增高级图像处理功能 注意:每个新版本的接口都继承自前一版本,因此高版本接口通常可以替代低版本使用,但需确保目标平台支持该版本。 接口版本与对应的 Direct2D 版本、SDK 及操作系统 接口名称 对应的 Direct2D 版本 引入的 Windows SDK 版本 引入的操作系统版本 ID2D1Device Direct2D 1.0 Windows SDK v7.1 (Win7 SDK) Windows 7 ID2D1Device Direct2D 1.1 Windows SDK v8.0 (Win8 SDK) Windows 8 ID2D1Device1 Direct2D 1.2 Windows SDK v8.1 (Win8.1 SDK) Windows 8.1 ID2D1Device2 Direct2D 1.3 Windows SDK v10.0.10240.0 Windows 10 TH1 (1507) ID2D1Device3 Direct2D 1.4 Windows SDK v10.0.14393.0 Windows 10 RS1 (1607) ID2D1DeviceContext 版本对应表 接口名称 引入的 SDK 版本 对应操作系统版本 主要新增功能 / 改进 ID2D1DeviceContext Windows SDK v7.0A Windows 8 RTM (6.2) 基础设备上下文接口,支持 Direct2D 设备模型 ID2D1DeviceContext1 Windows SDK v8.0A Windows 8.1 (6.3) 添加对位图格式扩展、纹理采样器状态等的支持 ID2D1DeviceContext2 Windows SDK v10.0.10240.0 Windows 10 TH1 (1507) 支持混合模式渲染、GPU 状态控制、多线程绘制优化 ID2D1DeviceContext3 Windows SDK v10.0.10586.0 Windows 10 TH2 (1511) 增加对 D3D11.3 的支持,例如支持更多着色器资源视图 ID2D1DeviceContext4 Windows SDK v10.0.14393.0 Windows 10 RS1 (1607) 支持更高效的图像处理、硬件加速的模糊效果 ID2D1DeviceContext5 Windows SDK v10.0.15063.0 Windows 10 RS2 (1703) 支持 GPU 后期合成(GPU compositing),提升性能与帧率 ID2D1DeviceContext6 Windows SDK v10.0.17134.0 Windows 10 RS4 (1803) 支持更复杂的 GPU 渲染管线,例如支持 DX12 相关功能(通过兼容层) ID2D1DeviceContext7 Windows SDK v10.0.19041.0 Windows 10 20H2 (2020) 支持 Direct2D 在现代 UI 框架(如 WinUI 3)中的集成,改进跨平台一致性 */ //注意性能: 高版本只是增加了特性功能API, 基础核心功能永远都在基础版本IDXGIDevice中.性能差异:系统更新, 硬件支持,SDK 和运行时版本, API 调用方式, 多线程支持 #include <dxgi.h>//注意: 所有高版本都集成在dxgi.h中 /* DXGI版本 头文件 支持的操作系统 DXGI 1.0 dxgi.h Windows Vista (带更新), Windows 7 DXGI 1.1 dxgi1_2.h Windows Vista SP2 (带更新), Windows 7, 和版本2集成在同一个文件中 DXGI 1.2 dxgi1_2.h Windows 7 (带KB2670838), Windows 8, 和版本1集成在同一个文件中 DXGI 1.3 dxgi1_3.h Windows 8.1, Windows Server 2012 R2 DXGI 1.4 dxgi1_4.h Windows 10 (初始版本) DXGI 1.5 dxgi1_5.h Windows 10 版本1607 (周年更新) 及以上 DXGI 1.6 dxgi1_6.h Windows 10 版本1803 及以上 * 接口版本与对应的 DXGI 版本、SDK 及操作系统 接口名称 对应的 DXGI 版本 引入的 Windows SDK 版本 引入的操作系统版本 IDXGIDevice DXGI 1.0 Windows SDK v7.0 Windows 7 SP1 IDXGIDevice1 DXGI 1.2 Windows SDK v8.0 (Win8 SDK) Windows 8 IDXGIDevice2 DXGI 1.3 Windows SDK v8.1 (Win8.1 SDK) Windows 8.1 IDXGIDevice3 DXGI 1.4 Windows SDK v10.0.10240.0 Windows 10 TH1 (1507) IDXGIDevice4 DXGI 1.5 Windows SDK v10.0.14393.0 Windows 10 RS1 (1607) */ #include <dcomp.h>//dcomp.h 首次出现在 Windows 8 SDK 中 /* 接口名称 引入版本 主要功能 IDCompositionDevice Windows 8 基础合成对象创建 IDCompositionDevice2 Windows 8.1 动画系统增强 IDCompositionDevice3 Windows 10 1511 图像处理和动画扩展 IDCompositionDevice4 Windows 10 1709 高级图像特效支持 IDCompositionDevice5 Windows 10 1809 新增图像处理特效和优化 */ #include <mutex>//设备是共享的,所以需要互斥锁 namespace D2DRENDER { class CRenderDevice { public: CRenderDevice(); ~CRenderDevice(); private: /***************************************开始准备D3D******************************************************************/ void CreateD3DDevice();//创建D3D设备 void GetDXGIDevice();//查询 DXGI 设备需要CreateDevice3D()支持 /***************************************开始准备D2D******************************************************************/ void CreateD2DFactory(); void CreateD2DDevice(); /***************************************开始准备DirectComposition****************************************************/ void CreateDcompDevice(); private: ID3D11Device* m_pD3DDevice; // Direct3D设备,使用交换链过程: 创建D3D设备->取出DXGI设备->桥接:使用DXGI创建D2D设备 IDXGIFactory* m_pDXGIFactory; // DXGI工厂,用于创建交换链 IDXGIDevice* m_pDXGIDevice; // DXGI设备: D3D桥接D2D的桥梁 ID2D1Factory1* m_pD2DFactory1; // Direct2D工厂 ID2D1Device* m_pD2DDevice; // Direct2D设备 // DirectComposition = win8 开始才引入 IDCompositionDevice* m_pDcompDevice; //DirectComposition设备 std::mutex m_mutex; // 用于保护内部资源访问 }; } #endif // _WIN32 #endif // !_RENDER_DEVICE_H_ #include "DcompFactory.h" #include "SystemDetector.h" using namespace D2DRENDER; // 匹配 dcomp.h 中的 DCompositionCreateDevice 函数原型 typedef HRESULT(WINAPI* fDCompositionCreateDevice)( IUnknown* dxgiDevice, REFIID riid, void** ppv ); // 匹配 dcomp.h 中的 DCompositionCreateDevice2 函数原型 typedef HRESULT(WINAPI* fDCompositionCreateDevice2)( IUnknown* renderingDevice, REFIID riid, void** ppv ); // COM最优解, 接口聚全(Interface Aggregation) -> 即最新版本的接口聚合到旧版本接口中 class CDcompFactoryImpl : public IDcompFactory1 { public: CDcompFactoryImpl(); // 构造函数 ~CDcompFactoryImpl(); // 析构函数 STDMETHOD_(HRESULT, QueryInterface)(REFIID riid, void** ppvObject); // COM接口查询 STDMETHOD_(ULONG, AddRef)(); // COM接口引用计数 STDMETHOD_(ULONG, Release)(); // COM接口释放计数 STDMETHOD_(INT32, GetDcompVersion)()CONST; STDMETHOD(DCompositionCreateDevice)(IUnknown* dxgiDevice, REFIID riid, void** ppv); // 创建DComposition设备 STDMETHOD(DCompositionCreateDevice2)(IUnknown* dxgiDevice, REFIID riid, void** ppv); // 创建DComposition设备 private: DWORD m_dwRefCount; // 引用计数 HMODULE m_hModule; // 模块句柄 INT32 m_iVersion; // 支持的版本 fDCompositionCreateDevice m_pfDCompositionCreateDevice; fDCompositionCreateDevice2 m_pfDCompositionCreateDevice2; }; CDcompFactoryImpl::CDcompFactoryImpl(): m_dwRefCount(0), m_hModule(nullptr), m_iVersion(-1), m_pfDCompositionCreateDevice(nullptr), m_pfDCompositionCreateDevice2(nullptr) { m_hModule = LoadLibrary("dcomp.dll"); if (m_hModule) { m_pfDCompositionCreateDevice = (fDCompositionCreateDevice)GetProcAddress(m_hModule, "DCompositionCreateDevice"); m_pfDCompositionCreateDevice2 = (fDCompositionCreateDevice2)GetProcAddress(m_hModule, "DCompositionCreateDevice2"); m_iVersion = m_pfDCompositionCreateDevice2 ? 2 : m_pfDCompositionCreateDevice ? 1 : 0; } else { m_iVersion = 0;//win8以下不支持 } } CDcompFactoryImpl::~CDcompFactoryImpl() { if(m_hModule)FreeLibrary(m_hModule); } STDMETHODIMP CDcompFactoryImpl::QueryInterface(REFIID riid, void** ppvObject) { if (riid == __uuidof(IDcompFactory)) { *ppvObject = this; AddRef(); return S_OK; } else if (riid == __uuidof(IDcompFactory1)) { *ppvObject = this; AddRef(); return S_OK; } else { *ppvObject = nullptr; return E_NOINTERFACE; } } STDMETHODIMP_(ULONG) CDcompFactoryImpl::AddRef() { return InterlockedIncrement(&m_dwRefCount); } STDMETHODIMP_(ULONG) CDcompFactoryImpl::Release() { ULONG ulCount = InterlockedDecrement(&m_dwRefCount); if (ulCount == 0) { delete this; } return ulCount; } STDMETHODIMP_(INT32) CDcompFactoryImpl::GetDcompVersion()CONST { return m_iVersion; } STDMETHODIMP CDcompFactoryImpl::DCompositionCreateDevice(IUnknown* dxgiDevice, REFIID riid, void** ppv) { HRESULT hr = m_pfDCompositionCreateDevice(dxgiDevice, riid, ppv); return hr; } STDMETHODIMP CDcompFactoryImpl::DCompositionCreateDevice2(IUnknown* dxgiDevice, REFIID riid, void** ppv) { HRESULT hr = m_pfDCompositionCreateDevice2(dxgiDevice, riid, ppv); return hr; } STDAPI D2DRENDER::CreateDcompFactory(REFIID riid, void** ppv) { IDcompFactory* pFactory = new CDcompFactoryImpl(); if (pFactory->GetDcompVersion() == 0)//如果版本太低 { pFactory->Release();//释放对象 *ppv = nullptr; return E_NOINTERFACE;//不支持 } pFactory->AddRef(); *ppv = pFactory; return S_OK; }
最新发布
08-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值