Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

提供了Direct2D渲染支持,大幅提升任务栏窗口透明渲染效果 #1156

Merged
merged 70 commits into from
Feb 5, 2023

Conversation

BombaxCeiba
Copy link
Contributor

@BombaxCeiba BombaxCeiba commented Apr 29, 2022

下载

GitHub Action
*下载方式:点击上面的 GitHub Action ,进入后选择带TransparentSupport标识的最新的一项点进去,拉到网页最下面,32位系统选择x86开头的文件下载,64位系统选择x64开头的文件下载即可。

系统兼容性

程序在Windows 11 22000.918上正常工作,但因为在Windows 7和Windows 8上任务栏窗口调用函数UpdateLayeredWindowIndirect更新窗口内容时会失败并得到错误87,所以这一功能暂不支持这两个系统版本。

对于Windows 8.1以及以上的系统版本,由于支持Direct Composition,在UpdateLayeredWindowIndirect失败后会使用Direct Composition对D2D渲染结果进行呈现。

在Windows Server 2022 20348.1366上,也会因为相同的原因使用Direct Composition进行呈现。

HDR兼容性

程序在Windows Server 2022 20348.1366上,在使用Direct Composition时可以正常呈现。

D2D渲染实现说明

通过对原有的CDrawCommon类在CTaskBarDlg类的ShowInfo方法中用到的函数进行提取后,添加了apha参数后单独放到IDrawCommon类中定义为纯虚函数。再将ShowInfo中用到的CDrawCommon类全部替换为IDrawCommon来实现对老代码的兼容。

D2D和GDI互操作

为了兼容插件的GDI调用,所有插件的绘制会被重定向到一个临时的DIB上,并且插件(包括通过MFC间接)调用的User32.dll中的DrawText和DrawTextEx系列函数都会被hook到一个支持透明度的版本上。在插件绘制完成后,DIB会被上传到显卡。显卡会将透明度为1的值(对应未被GDI绘制过的部分)修改为0,将透明度为0的值修改为255(对应被GDI绘制过的部分),其余透明度的值保留,得到的结果再和程序绘制的部分相叠加以得到最终显示用的结果。

由于微软的神奇bug,IDXGISurface1::GetDC的调用会偶尔出现下面这种报错:

0x00007FFD8D73474C 处(位于 TrafficMonitor.exe 中)引发的异常: Microsoft C++ 异常: _com_error,位于内存位置 0x000000FDDC3AB6C8 处。

可以不用理会。

禁用D2D绘图

找到任务栏窗口设置,勾选这个(在最下面的)选项即可
image

D2D绘图和GDI绘图效果对比

D2D:
image
image

GDI:
image
image

*使用D2D渲染时,可以避免背景颜色变化导致的闪烁现象。
并且D2D内存占用大一点

fix #955
fix #837
fix #1068

类DrawCommonBuffer会在构造时创建一个ARGB32的缓冲区用于绘图,并在析构时调用::UpdateLayeredWindowIndirect通知Windows更新窗口后删除缓冲区
同时修复了编译错误
使用IDrawCommon抽象了原有的渲染接口并使用D2D实现。使用IDrawBuffer抽象了原有的双缓冲类。
修复了DrawCommonUnion和DrawCommonBufferUnion未正确初始化Nullable类型对象导致的内存错误。
修复了D2D1DCSupport未正确初始化内存导致的错误。
修复了DWriteFont未释放的内存泄露问题。
修复了无法正常检测D2D是否存在的问题
修复了D2D渲染器无法绘制虚线的问题。
修复了D2D渲染器DPI处理不正确的问题。
修复了D2D渲染器函数ExecuteGdiOperation无法在绘制过程中正确与GDI交互的问题。
为D2D渲染器引入了延迟加载特性,如果软件本身不触发D2D渲染则渲染器将不会初始化。

zhongyang219#777 zhongyang219#955 zhongyang219#837
@BombaxCeiba BombaxCeiba changed the title 通过添加D2D渲染提供了更好的任务栏窗口的背景透明效果 提供了Direct2D渲染支持,大幅提升任务栏窗口透明渲染效果 Apr 30, 2022
DrawCommonBuffer更新窗口失败时会弹窗提示并自动禁用D2D渲染,同时也会写入错误日志
减小了DrawCommonBuffer类体积
修复了DrawCommonHelper::ForEachPixelInBitmapForDraw函数遍历范围不正确的问题
但是关闭了插件自绘时的文本抗锯齿,会影响渲染的文本质量
@soloopooo
Copy link

使用@eritpchy构建的版本发现:

对于点阵字体,D2D渲染会导致程序直接崩溃,例如Terminal、Terminal Greek与Terminal Greek 869等系列点阵字体。
image

对于部分字体,D2D会出现 fallback 到默认字体的现象,如FOT-Aokane Std,GenSenMaruGothic TW TTF,Victor Mono等

经过检查发现,这些出现 fallback 问题所涉及到的字体,均没有使用“为所有用户安装”这一选项。
而MFC渲染则没有这个问题。

image

image

image

image

在D2D1DrawCommon中抛出异常不会引起程序崩溃,而是回退到GDI渲染并记录日志。
@BombaxCeiba
Copy link
Contributor Author

使用@eritpchy构建的版本发现:

对于点阵字体,D2D渲染会导致程序直接崩溃,例如Terminal、Terminal Greek与Terminal Greek 869等系列点阵字体。 image

对于部分字体,D2D会出现 fallback 到默认字体的现象,如FOT-Aokane Std,GenSenMaruGothic TW TTF,Victor Mono等

经过检查发现,这些出现 fallback 问题所涉及到的字体,均没有使用“为所有用户安装”这一选项。 而MFC渲染则没有这个问题。

image

image

image

image

应该不会崩溃了,但是字体的问题还没解决。

@SpecterShell
Copy link

开启 Direct2D 渲染前,整块任务栏窗口都可以右键或双击。开启 Direct2D 渲染后,只有在渲染了文字的地方操作才会正确响应,在其它部分操作会变成任务栏右键。
8d1ea689-5cf5-412f-99e4-f53f4023278d

@BombaxCeiba
Copy link
Contributor Author

开启 Direct2D 渲染前,整块任务栏窗口都可以右键或双击。开启 Direct2D 渲染后,只有在渲染了文字的地方操作才会正确响应,在其它部分操作会变成任务栏右键。 8d1ea689-5cf5-412f-99e4-f53f4023278d 8d1ea689-5cf5-412f-99e4-f53f4023278d

后续会给渲染的背景给个1的透明度,应该能解决问题

@BombaxCeiba BombaxCeiba marked this pull request as draft June 3, 2022 14:04
@BombaxCeiba BombaxCeiba marked this pull request as draft December 13, 2022 14:34
@NeoFantom
Copy link

请问如何下载此PR中的 D2D 版本的软件?我不会编译。

@BombaxCeiba
Copy link
Contributor Author

请问如何下载此PR中的 D2D 版本的软件?我不会编译。

我更新了PR的说明,添加了下载的教程,你可以再看看下载部分的内容。

@SpecterShell
Copy link

任务栏调至浅色后,任务栏窗口会出现白色不透明背景,重新关闭并打开“背景透明”选项无效。
image
勾选“禁用Direct2D渲染”后,背景颜色仍为白色,而前景文字颜色变成透明。同时任务栏无论是深色还是浅色,在任务栏窗口右键点击无法打开程序菜单,而是打开任务栏的菜单。
image

@BombaxCeiba
Copy link
Contributor Author

任务栏调至浅色后,任务栏窗口会出现白色不透明背景,重新关闭并打开“背景透明”选项无效。 image 勾选“禁用Direct2D渲染”后,背景颜色仍为白色,而前景文字颜色变成透明。同时任务栏无论是深色还是浅色,在任务栏窗口右键点击无法打开程序菜单,而是打开任务栏的菜单。 image

试一下GitHub Action里面最新的版本,问题已经被修复了。

@zhongyang219 zhongyang219 merged commit 7122420 into zhongyang219:master Feb 5, 2023
@zhongyang219
Copy link
Owner

代码已合并,感谢你为TrfficMonitor做出的改进

fengjixuchui added a commit to fengjixuchui/TrafficMonitor that referenced this pull request Feb 5, 2023
Merge pull request zhongyang219#1156 from BombaxCeiba/TransparentSupport
@miyouzi
Copy link

miyouzi commented Jul 1, 2023

CI 版本已过期,请求新的下载方式

@BombaxCeiba
Copy link
Contributor Author

CI 版本已过期,请求新的下载方式

见最新的版本 #1656

@IMLHF
Copy link

IMLHF commented Nov 29, 2023

下载

GitHub Action *下载方式:点击上面的 GitHub Action ,进入后选择带TransparentSupport标识的最新的一项点进去,拉到网页最下面,32位系统选择x86开头的文件下载,64位系统选择x64开头的文件下载即可。

系统兼容性

程序在Windows 11 22000.918上正常工作,但因为在Windows 7和Windows 8上任务栏窗口调用函数UpdateLayeredWindowIndirect更新窗口内容时会失败并得到错误87,所以这一功能暂不支持这两个系统版本。

对于Windows 8.1以及以上的系统版本,由于支持Direct Composition,在UpdateLayeredWindowIndirect失败后会使用Direct Composition对D2D渲染结果进行呈现。

在Windows Server 2022 20348.1366上,也会因为相同的原因使用Direct Composition进行呈现。

HDR兼容性

程序在Windows Server 2022 20348.1366上,在使用Direct Composition时可以正常呈现。

D2D渲染实现说明

通过对原有的CDrawCommon类在CTaskBarDlg类的ShowInfo方法中用到的函数进行提取后,添加了apha参数后单独放到IDrawCommon类中定义为纯虚函数。再将ShowInfo中用到的CDrawCommon类全部替换为IDrawCommon来实现对老代码的兼容。

D2D和GDI互操作

为了兼容插件的GDI调用,所有插件的绘制会被重定向到一个临时的DIB上,并且插件(包括通过MFC间接)调用的User32.dll中的DrawText和DrawTextEx系列函数都会被hook到一个支持透明度的版本上。在插件绘制完成后,DIB会被上传到显卡。显卡会将透明度为1的值(对应未被GDI绘制过的部分)修改为0,将透明度为0的值修改为255(对应被GDI绘制过的部分),其余透明度的值保留,得到的结果再和程序绘制的部分相叠加以得到最终显示用的结果。

由于微软的神奇bug,IDXGISurface1::GetDC的调用会偶尔出现下面这种报错:

0x00007FFD8D73474C 处(位于 TrafficMonitor.exe 中)引发的异常: Microsoft C++ 异常: _com_error,位于内存位置 0x000000FDDC3AB6C8 处。

可以不用理会。

禁用D2D绘图

找到任务栏窗口设置,勾选这个(在最下面的)选项即可 image

D2D绘图和GDI绘图效果对比

D2D: image image

GDI: image image

*使用D2D渲染时,可以避免背景颜色变化导致的闪烁现象。 并且D2D内存占用大一点

fix #955 fix #837 fix #1068

This artifact has expired and you can no longer download it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
7 participants