wpf D3DImage 偶现性无法渲染图像,D3D设备丢失的解决办法

    最近碰到这样的现象,在一些笔记本上使用D3DImage控件渲染时,会有一定几率无法显示图形。图形显示流程大概是C++  创建Surface,渲染好后传递指针给D3DImage显示。查了一遍C++ 层,返回值都是对的,连个错误码都没有,而且C++写的渲染Demo在同样的环境下可以正常运行。

    然后就怀疑C# 层渲染出了问题,果不其然D3DImage的一个属性IsFrontBufferAvailable为false了,MSDN说该属性偶尔可能为  false,为false的时候D3DImage是无法渲染图形的,说明wpf丢失了D3D设备。google了一下,网上说这种情况是D3DImage 失去D3DDevice的控制权,什么原因引起的,还不清楚,直到 MSDN 上一篇文章引起我的注意:https://social.msdn.microsoft.com/Forums/vstudio/en-US/2779ab41-6f84-47cf-a1d6-7851cc168096/d3dimage-losing-its-d3ddevice?forum=wpf

  大意是当使用远程桌面时,wpf识别出有用户使用远程桌面,或者有程序调用类似mirror display 驱动时,wpf出于性能和稳定考虑,可能下调渲染级别,严重的由Tier2降到Tier0,用以下代码查了下,渲染等级还真是降为0了(0表示硬件加速不可用)。

int level = System.Windows.Media.RenderCapability.Tier >> 16;

  什么原因引起渲染等级下调呢?发现向日葵远程控制有一个虚拟显示器驱动,看过抓屏相关的代码,第一直觉就是它搞得鬼。

 将改驱动禁用后重启,发现D3DImage 能正常显示图形,渲染级别也变为2了。这个驱动会使wpf渲染等级降为tier0,但不是对所有PC都有影响,台式机几乎不受影响,个别性能差的笔记本直接缴械投降,aero特效也没了。Tier 0是无法利用硬件加速的,好在D3DImage 提供CPU软渲染的方法。

public void SetBackBuffer(D3DResourceType backBufferType, IntPtr backBuffer, bool enableSoftwareFallback);

 所以最后的解决办法就是,在渲染前先查询目前wpf所在的渲染等级,决定使用软渲染还是硬件加速。

private void CheckHardWareSupport()//查询硬件支持
{
   int level = System.Windows.Media.RenderCapability.Tier >> 16;
   useSoftRender = level == 0?true:false;
}

var showRect = new Int32Rect(0, 0, d3dImage.PixelWidth, d3dImage.PixelHeight);

private void Render(IntPtr surface)
{  
    if(!useSoftRender)//硬件加速,IsFrontBufferAvailable为false返回
    {
        if(!d3dImage.IsFrontBufferAvailable)
        {
            return;
        }
    }
       
    d3dImage.Lock();
    d3dImage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, surface, useSoftRender);
    d3dImage.AddDirtyRect(showRect);
    d3dImage.Unlock();
}

注:软渲染会耗费较多CPU,而且软渲染检查IsFrontBufferAvailable是没有意义的

参考链接:

https://stackoverflow.com/questions/61122452/d3dimage-and-remote-desktop

https://social.msdn.microsoft.com/Forums/vstudio/en-US/2779ab41-6f84-47cf-a1d6-7851cc168096/d3dimage-losing-its-d3ddevice?forum=wpf

https://docs.microsoft.com/zh-cn/dotnet/api/system.windows.interop.d3dimage.isfrontbufferavailable?view=netframework-4.7.1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值