XP的GDI模型:

XP用的是XPDM驱动模型,简单来说就是GDI32直接调用内核(Win32k.sys)内的图形引擎, 图形引擎会再调用显卡驱动, 对于显卡驱动没有实现的接口, 图形引擎会用软件实现。所以这种情况下我们一般窗口的Render操作都是直接画到显示器上。( 当然也有例外, 就是Layered window (WS_EX_LAYERED) , 所有的Layered windows因为有Alpha通道,系统进行了缓存,  最终才合成输出到显示器上的, 所以Layered windows比较耗资源, 我们抓屏时可以通过CAPTUREBLT表明是否需要过滤该类型窗口。) 

Vista之后系统用了WDDM驱动模型, 该模型从Vista的1.0到Win10已经是2.0。

该模型提供了2套render相关的API, 一套是传统的GDI API, 还有一套是新的Dxgi接口, 当然传统的GDI在内核中也有部分是通过Dxgi实现的。
基于新的Dxgi接口,系统在应用层提供了D2D, D3D, DirectComposition等API。
在该模型下, 所有的窗口在系统中都有缓存(客户区内容), 所以所有的窗口实际上都是Layered windows了。
另外系统提供DWM桌面管理器, 它负责将所有的桌面窗口进行合成,所以我们可以看到3D或者毛玻璃效果, 最后再显示到桌面。
未来微软的期望应该是逐步抛弃现有的GDI,逐步转到Dxgi这套新的API上来, 现在新的系统应用已经都基于这套新的render API, 但是考虑到历史包袱和兼容性,很长世间内应该会2套共存.
这样现在Windows提供了2种应用开发的方式, 一种是传统的桌面程序(很大部分是基于GDI的), 还有一种就是UWP(Universal Windows Platform)应用, 这种应用就是所谓的通用应用(跨Mobile/Surface/PC/Xbox/HoloLens)。


通用应用基于WinRT, 即Windows Runtime, 当然这里runtime和.net的CLR以及java的JVM不同, 人家是真正的runtime(字节码解释器), 而WinRT仅是一套API。当然WinRT的API也有自己的特色: 接口实现基于COM,面向对象; 接口描述基于元数据,跨语言;界面实现基于D3D, 用Xaml描述。对于这套API的实现,不同平台会不一样,如果是X86的PC, 很大程度上是在原有的Win32应用层进行封装(只不过弄了个沙箱, 进行了一些权限控制); 如果是ARM版, 内部实现肯定和X86不一样, 但只要API保持不变, 对上层应用都是透明的。


在Win10上,现在的WinRT桌面应用已经和传统的Win32应用程序没太大差距了,都可以直接以窗口的形式跑在传统桌面上, 只不过权限有些不一样(WinRT app是appContainer权限, 只能访问自己的安装目录)。两者还有一个不一样就是render的方式, 传统的大部分还是基于GDI,而WinRT App是基于Xaml, 而Xaml又是基于D3D和Dxgi的。


Win10的虚拟桌面层让人觉得比较好奇, 可后来发现微软仅仅是在DWM里做了些手脚, 简单来说就是让窗口进程关联了某个虚拟桌面, DWM在合成时仅显示当前虚拟桌面的窗口。曾经也很好奇为什么很多WinRT窗口明明窗口属性是Visible 的,但是桌面上为什么不显示,其实也是DWM做了些手脚, 当然微软后来提供了API让我们区分一个WinRT窗口是否真的可见。
posted on 2016-03-16 22:09 Richard Wei 阅读(3716) 评论(1)  编辑 收藏 引用 所属分类: windows desktop

FeedBack:
# re: GDI VS Dxgi
2016-06-04 09:31 | pdkuionline
写得很好,又长知识了,谢谢!  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理