WIN10系统 Indirect Display 虚拟显示器之特殊应用

WIN10系统 Indirect Display 虚拟显示器之特殊应用byfanxiushu2020-05-20转载或引用请注明原始作者。有人询问我是否可以实现这样一种功能:对windows输出的每一帧图像数据显示做一些特殊处理(比如球形桌面,曲面化等特效),然后再显示到显示器上。而且还不止一个人这样咨询过,虽然我不大清楚这种需求具体用在何处,估计也是一些特殊场所。这种需求,最先想到的,也最直观的想法就是能否给显卡驱动添加一个过滤驱动,然后拦截图像数据,然后再做些特殊处理。可惜想法是美好的,却是难以实现的,甚至是不大可能实现的。首先windows中就没显卡过

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

by fanxiushu 2020-05-20 转载或引用请注明原始作者。

有人询问我是否可以实现这样一种功能:
对windows输出的每一帧图像数据显示做一些特殊处理(比如球形桌面,曲面化等特效),然后再显示到显示器上。
而且还不止一个人这样咨询过,虽然我不大清楚这种需求具体用在何处,估计也是一些特殊场所。

这种需求,最先想到的,也最直观的想法就是能否给显卡驱动添加一个过滤驱动,然后拦截图像数据,然后再做些特殊处理。
可惜想法是美好的,却是难以实现的,甚至是不大可能实现的。
首先windows中就没显卡过滤驱动一说。虽然windows许多的设备驱动程序,都有对应的过滤驱动,但是显卡驱动是个特例。
这是显卡驱动复杂性造成的,
显卡处理的本身就是数据量庞大的图像数据,少量数据是在系统内存中处理,大部分都是直接在显存中处理的。
如果给显卡驱动再挂载过滤驱动,获得的图像数据是继续在GPU中处理呢,还是运到CPU中处理呢,
系统中的软件绝大部分都需要借助CPU才能工作,这样就不得不把图像数据从显存搬到内存,处理完成之后再次搬到显存中,
这样不是没事找事么,这样的结果就是显示效率极其低下。
再说windows绘图是多方位的,显存中存储了多个windows窗口的图像数据,假设存在这么一个总的“framebuffer”,
由windows的dwm.exe窗口管理程序根据绘图变化情况,动态的把这些windows窗口数据合并到 “framebuffer”中,
再根据显示器的刷新率,比如每秒60HZ刷新率,
也就是大约16毫秒dwm.exe就再次把 “framebuffer” 中数据通过HDMI,DisplayPort等显示接口输出到显示器中,
这个速度都是极其快速的,基本都是利用显卡硬件在操作。
如果在其中硬插一杆,来个显卡过滤驱动,要我们通过软件方式转换变形一下 ”framebuffer“中的图像数据,这不是严重破坏显示速度么!

有人说windows中没有显卡过滤驱动,我们可以利用HOOK手段,自己制造一个”显卡过滤驱动“啊,确实可以这样做。
我CSDN上的文章也也介绍过这方面的内容:
https://blog.csdn.net/fanxiushu/article/details/82731673  WIN7以上系统WDDM虚拟显卡开发(WDDM Filter/Hook Driver 显卡过滤驱动开发之一)
但是这种HOOK,大部分都是用于制造一个额外的虚拟显示器,
因为在WIN10之前(WIN7,WIN8),是没法通过通用的编程方式生成额外显示器。
即使不生成额外显示器,通过HOOK DRIVER_INITIALIZATION_DATA结构里边的 DxgkDdiSetVidPnSourceAddress 回调函数,获取到
图像渲染的显存地址索引,再配合 HOOK DxgkddiQueryadapterinfo 回调函数,从而获取图像渲染的真正的显存的物理地址,
可是获取到这些显存地址能干嘛? 而且对于FLIP翻转渲染,这些地址都是动态变化的。
如果是单纯截屏,我们还得想办法把这个图像数据,从显存搬运到内存中,这样做的效果还不如GDI截屏来的简洁和有效。
如果是拦截,这事就更大了,这段显存地址不是我们能控制的,没办法像水龙头那样能截流。
即便能拦截,我们也会面临同样的问题:是在GPU中处理呢,还是在CPU中处理呢?
要获得更好的处理自由度,就不得不使用CPU,把数据搬运到内存中处理,处理完成再次搬运回到显存。这样的效果谁能接受?

或许我们在应用层中,打dwm.exe程序的主意,dwm.exe是桌面管理程序,WIN8以上下图,dwm.exe是强制运行的。
主要功能是对桌面图像进行管理,比如多种窗口合成,各种绘图库的生成的图像合成,dwm.exe大部分时间任然是直接操作显存中的图像。
也许我们通过dwm.exe里边的某些未知接口函数,拦截到图像数据,
但是因为是“未知接口”,因此谁知道究竟该拦截哪些呢?我也不是专门搞激活成功教程的。
再说,即便拦截成功了,也是同样的问题:是在GPU中处理呢,还是搬运到CPU中处理?

或许我们从更底层实现这种特殊需求,就是在显卡的输出接口,
比如HDMI,DisplayPort接口的地方,再插入一个我们制造的特殊硬件设备,这个硬件设备拦截HDMI,DP显示接口的图像数据流,
做些转换再发送到显示器。
但是这种做法就是纯硬件的做法了,已经与具体的操作系统没啥关系。这也不是本文描述的范围了。

我们也可以找到具体的显卡制造厂商,让他们在驱动和显卡中集成这种特殊需求,
但是这是具体的定制需求,也不是本文讨论的范围。

在CSDN上,专门介绍过windows10以上平台的Indirect Display Driver 虚拟显卡驱动。
https://blog.csdn.net/fanxiushu/article/details/93524220
Windows远程桌面开发之九-虚拟显示器(Windows 10 Indirect Display 虚拟显示器驱动开发)

当时的目的是为了给windows增加一个额外的虚拟显示器,以方便xdisp_virt远程控制程序使用扩展桌面效果。
然而 Indirect Display Driver 的实际用处,却不单是这样。
它的用处是给电脑增加一个其他接口,比如USB接口,来增加一个新的显示器。还比如Miracast无线接口的显示器。
这些都需要增加一个虚拟显示器驱动,然后把windows桌面图像输出到这些显示器中。
有些人把USB接口输出到显示器的设备,称作USB外置显卡,其实不是”显卡”,   严格来说就是个扩展坞。
真正的显卡功能还是电脑内部插上的那块显卡。
那为何不制造真正的外置显卡呢? 首先就是接口速度跟不上。
现在电脑内插的独立显卡大都是 PCI-E 2.0 X16 接口的,X16代表速度,能达到 16GB/s 的速度,注意是字节,换算成位的话是 128 Gbps 。
我们再来看看电脑外接接口的速度:
USB3.0    5 Gbps
USB3.1   10Gbps
USB3.2    20Gbps
USB4.0    40Gbps (4.0标准正在指定中,这是据称的速度)
雷电3       40Gbps
HDMI2.0  18Gbps
HDMI2.1   48Gbps
DP1.4       32.4Gbps
DP2.0       80Gbps

这些外置接口算是电脑外置接口速度中最快的了,除了DP2.0 勉强能与PCI-E 2.0 X8相比较外,其他都无法比较,
因此目前的情况来看,实现真正的外置显卡还不大现实。
但是作为扩展坞,还是可行的。我们做个简单计算(实际速度会有少许差别):

1920X1080,32位真彩色,60HZ每秒的刷新率,需要多大的传输带宽:
1920*1080* 4 * 60* 8 = 3,996,057,600 bps = 3.7 Gbps,  USB3.0接口就能胜任这个速度。
如果是 120HZ的刷新率(比如有些刷新率),需要 3.7*2=7.4Gbps,需要USB3.1以上才可以。

至于 4K 显示器, 60HZ刷新率:
3840*2169*4*60*8 = 14.9 Gbps, 这个需要 USB3.2以上才能支持。
120HZ刷新率, 需要 14.9=30Gbps,这个需要USB4.0以上或雷电3以上才能支持。

至于8K显示器,60HZ刷新率:
7680*4320*4*60*8 = 60Gbps, 这个目前来说,就只有DP2.0才能支持了。

列举了这些数据,与我们文章最开头提到的需要实现特殊功能有何用处?
其实就是我们完全可以使用Indirect Display Driver驱动,实现一个USB显卡扩展坞的显示器。
然后在Indirect Display驱动中实现我们需要的各种效果(比如球面化桌面,曲面化桌面等)。这是目前最好的选择。
因为 Indirect Display驱动是UMD驱动,也就是应用层驱动,图像数据的处理截取全都在应用层。
我们完全可以在Indirect Display驱动中使用DirectX做GPU加速的图像处理,或者实现CPU加速方式的各种图像转换,等等。
而这些图像处理都是非常方便的,而且也是高效的。
再把转换好的图像数据输入给USB接口。
我们需要制造一个专门的USB接口的设备,因为现在显示器大都是HDMI或DisplayPort接口的,所以增加一个接口转换硬件。
相信这对硬件工程师来说,都是容易办到的。这也花不了多少成本。
显示器接到这个简单的硬件设备上,而真正的显卡不需要接任何显示器。
这样windows10系统,就只会把我们这个USB扩展坞接的显示器当成主显示器,也是唯一的显示器。
(当然这样的显示器,windows的启动过程是看不到的,是黑屏的。但是如果不在意或者不出BUG,估计也不会去关心。)
这样文章开头提到的特殊效果自然就能实现了。
其实像DuetDIsplay,DisplayLink这些专门做扩展显示器的,把他们的思路稍微转换一下,
在生成的虚拟显示器驱动中,增加对这些桌面输出图像特效的处理,自然就能满足文章开头提到的特殊需求。

上面介绍的是使用一个实实在在的USB硬件设备来达到这种特殊效果,
有没有不使用任何额外的硬件设备,就利用现成的硬件来达到这种效果呢?
这也是提问者的最终目的,不需要另外制造硬件,但是也要达到这种特殊效果。
其实利用Indirect Display驱动也可以办到,就是不大完美,但是这也是一个解决办法:
windows10系统利用Indirect display 驱动生成一个不需要任何硬件的虚拟显示器,然后再利用电脑中一个真实的显示器。
这样系统中实际上有两个显示器,设置成分辨率大小一样的成扩展显示模式,让虚拟显示器成为主显示器,
再然后运行一个程序,这个程序以全屏方式填充到真实显示器中,并且这个程序截取虚拟显示器内容并且显示出来。
这样看到的效果就是真实显示器显示的完全是虚拟显示器的内容,这个程序再对截取到的虚拟显示器的图像数据做些转换,
自然就能达到这种特殊效果。
至于说这种办法不大完善,是因为系统中毕竟出现了两个显示器,而且还是扩展模式。
鼠标移动后很容易”飘“,不知道移到哪去了(其实是移动到别的显示器上了)
还有就是新打开的程序也很容易跑到别的显示器上面。因此还得开发一些额外的程序解决这些问题。

如果对这种办法有兴趣,可以自行去实现。至于Indirect Display驱动的开发问题。
可以直接借用我在GITHUB上xdisp_virt项目下的indirect_display目录中的驱动。
https://github.com/fanxiushu/xdisp_virt
上面链接中的indirect_display目录中有详细安装使用介绍。

其中的indirect_display-plug.exe程序是模拟插入虚拟显示器。
而 indirect_display-image.exe程序则是显示虚拟显示器内容的程序。
这次我把indirect_display-image.exe稍微做些修改,把图形数据做个球面化的效果,如下图所示:
这个就是变形之后的虚拟桌面图像,

WIN10系统 Indirect Display 虚拟显示器之特殊应用

然后把这个程序全屏化,就像下图这样:
WIN10系统 Indirect Display 虚拟显示器之特殊应用

如果不看最上面的远程桌面抓屏图像,就只看笔记本的屏幕效果,谁能知道其实就是简单的两个扩展桌面玩的把戏。
如果有兴趣,可以直接使用我的Indirect Display驱动来实现类似功能,虽然 indirect_display-image.exe并没公开如何获取图像数据源。
但是你可以使用DXGI的方式来截取虚拟桌面的图像数据。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/171795.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • Linux 下搭建流媒体服务器

    Linux 下搭建流媒体服务器

  • 实战 FastCGI「建议收藏」

    实战 FastCGI「建议收藏」
    当网站日益走红,联机人数直线上升而心中暗自窃喜之时,突然客服中心涌来大批反应电话:『网站连不上去』、『按下去等好久画面才出来』、『一直出现ServerTooBusy…』...。看来又要把硬件升级了,但是再加更多的内存,更多CPU、换更贵的机器真的能解决问题吗?有没有比较省钱的方法呢?本文将介绍如何在阿帕契服务器上安装FastCGI的模块,如何设定及使用FastCGI网站应用程序,让你的网站程序在现有的架构上以全速执行。
    ————————

  • stimulsoft mysql_Stimulsoft Server

    stimulsoft mysql_Stimulsoft ServerStimulsoftReports.Server是一个客户服务器系统,允许您轻松、高效地使用报表实现完整的工作周期,包括从执行信息处理任务的设计和自动化到为用户准备便利的结果演示。快速和现代化的StimulsoftReports技术实现了报表模块的功能,并且灵活性和可靠性都经过了测试。StimulsoftReports.Server的特性概括:使用图形元素和不同的图表可以将通用数据源转换为明亮和…

  • hawq 遇到难题了

    hawq 遇到难题了

  • MATLAB矩阵复制及扩充

    MATLAB矩阵复制及扩充文章目录一、repmat()方法二、Kron()方法一、repmat()方法例一:(行方向和列方向分别平铺矩阵,红框2,3表示平铺倍数)TIPS:【原矩阵】处可用用户自定义的矩阵变量代替   即Mat=[123;456],可用Mat替代function中原矩阵的位置例二:(行方向和列方向分别平铺矩阵,红框2,3表示平铺倍数)例三:(列方向平铺矩阵,红框2表示平铺矩阵的倍数)例四:(行方向平铺矩阵,红框3表示平铺矩阵的倍数)二、Kron()方法kron(A,B)

  • 面向对象和面向过程的区别理解_c是面向对象还是面向过程

    面向对象和面向过程的区别理解_c是面向对象还是面向过程一、面向对象和面向过程面向对象面向过程编程是一种以过程为中心的编程思想,分析出解决问题的步骤,然后用函数把这些步骤一步一步实现。面向过程编程,数据和对数据的操作是分离的,函数本身只

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号