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的方式来截取虚拟桌面的图像数据。

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • java中高级工程师面试汇总

    java中高级工程师面试汇总1接口服务数据被劫包如何防止数据恶意提交1.1:防篡改客户端提交请求之前,先对自己请求的参数全部进行拼接加密得到一个加密字符串sign 请求参数加上sign,然后再发送给服务器 服务器将参数获取后也进行相同的拼接加密得到自己的sign 比较与客户端发来的sign是否相同 不相同则是被第三方修改过的,拒绝执行关键:第三方不知道加密方式和请求参数拼接规则,而客户端与服务器是知道的,因此第三方不知道修改参数后如何生成与服务器生成相同的sign 只要请求修改了一点点加密得到的就是不同的签名

    2022年7月8日
    20
  • 固态硬盘开盘数据恢复的方法是_硬盘数据恢复原理

    固态硬盘开盘数据恢复的方法是_硬盘数据恢复原理在电脑的使用中有时因为一些不当的操作会导致固态硬盘损坏,有的网友就在现实中遇到了这种情况,咨询小编固态硬盘开盘数据恢复的方法,下面小编就将怎么恢复固态硬盘数据教给大家。更多一键重装系统的方法在这里工具/原料系统版本:win10教育版品牌型号:华为MateBookXPro方法一、固态硬盘开盘数据恢复的方法1、怎么恢复固态硬盘数据呢,首先可以查看回收站,如果被删除的数据还在回收站里点击还原即可。方法二、固态硬盘开盘数据恢复的方法1、下载安装嗨格式数据恢复大师,在首界面选择恢复模式和文件存储位置,点击扫描,

    2022年9月20日
    3
  • 一些能用的 BT Tracker 服务器地址【不定时更新】[通俗易懂]

    一些能用的 BT Tracker 服务器地址【不定时更新】[通俗易懂]不定时更新可用的BTTracker服务器列表(BTTrackerList);相关工具BEncodeEditor:https://sites.google.com/site/ultimasites/bencode-editorTrackerEditor:https://github.com/GerryFerdinandus/bittorrent-tracker-editor/releases可以将服务器列表写入TrackerEditor程序同目录下的add_trackers.txt

    2022年6月18日
    153
  • Double转BigDecimal进行四舍五入操作时会出现数据损失

    Double转BigDecimal进行四舍五入操作时会出现数据损失工作中遇到四舍五入的处理,查了资料都是讲三种常见的方法。这里就不说了。实际上你会发现,在用BigDecimal转换时根本不是想像中的那么简单。看代码:java.math.BigDecimalbd=newjava.math.BigDecimal(115.5225);//这里将浮点数转化为BigDecimalDoubled=bd.setScale(3,java.math.Bi

    2022年5月16日
    53
  • docker使用教程视频_docker到底怎么用

    docker使用教程视频_docker到底怎么用前言docker主要用于运维,当然了,开发也可以用,可以在启动应用项目的时候使用docker方式,docker是虚拟化技术,每一个docker容器都是一个linux虚拟机,而且还可以根据不同的应用定制,最小的可以直接依赖linux内核,仅仅几M就可以运行。下面,正式开始。 注意:如果是使用docker-compose方式,只看到第三的第6即可。 一、安装dockercent…

    2022年10月15日
    3
  • 阿里云邮箱POP3、SMTP设置教程

    阿里云邮箱POP3、SMTP设置教程

    2021年9月21日
    270

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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