- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
在微软的example对于如何使用 PixelShader,他们使用单例。我在 other places 中看到了相同的模式, 他们在这里说
The pixel shader is stored in a private static field _pixelShader. This field is static, because one instance of the compiled shader code is enough for the whole class.
我们在使用此模式时遇到了几个内存泄漏问题。 PixelShader 涉及的事件处理并不总是正确清除。我们不得不freeze他们,并看到了一些改进。我们不得不手动进行一些分离
// Attach/detach effect as UI element is loaded/unloaded. This avoids
// a memory leak in the shader code as described here:
element.Loaded += (obj, args) =>
{
effect.PixelShader = ms_shader;
element.Effect = effect;
};
element.Unloaded += (obj, args) =>
{
effect.PixelShader = null;
element.Effect = null;
};
即使在压力下,该区域仍然存在内存泄漏。有谁知道 PixelShader 使用繁重的资源是否值得使用单例?
最佳答案
绝对没有。然而,原因不在于 PixelShader
本身,而在于它在 ShaderEffect
中的使用。
几乎所有 WPF 自定义着色器效果的实现都基于 Microsoft 的 .NET 3.5 示例,这些示例未针对 .NET 4.0 进行更新。可以为所有效果使用单例 PixelShader
实例,它仅支持 ps_2_0 着色器。在 .NET 4.0 中,Microsoft 引入了对 ps_3_0 像素着色器(用于 GPU 加速设备)的支持,并因此将内存泄漏引入了 ShaderEffect
类。ShaderEffect
跟踪它的 PixelShader
属性,并通过强订阅名为 _shaderBytecodeChanged
的 PixelShader 内部事件来检查它没有使用 ps_2_0 字节码的 ps_3_0 寄存器。因此,多个 ShaderEffect
实例使用的单例 PixelShader
充当 GC 的支配根,并重新保留与相应 ShaderEffect
的任何实例一起使用的所有对象。即known memory leak ,这不会被修复。
如果您想将 PixelShader
用作无泄漏的单例,那么您将不得不使用运行时黑客:每次将 PixelShader
实例分配给 PixelShader
ShaderEffect
类的属性,PixelShader
实例的 _shaderBytecodeChanged
字段应手动清除,例如:
var ei = typeof(PixelShader).GetEvent("_shaderBytecodeChanged",
BindingFlags.Instance | BindingFlags.NonPublic);
var fi = typeof(PixelShader).GetField(ei.Name,
BindingFlags.Instance | BindingFlags.NonPublic);
fi.SetValue(pixelShader,null);
当然,这些操作可以通过 DynamicMethod
基础设施或类似机制在运行时生成辅助方法来优化。但是,这应该仅用于肯定是 ps_2_0 或肯定是 ps_3_0 的着色器
关于c# - 使用单例 PixelShader 应该是最佳实践吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33176446/
在微软的example对于如何使用 PixelShader,他们使用单例。我在 other places 中看到了相同的模式, 他们在这里说 The pixel shader is stored in
我发现它们之间明显不匹配,但我不明白为什么或如何它们不匹配。我已经看了这么久了,现在什么也看不见了,所以也许多看几双眼睛...... Here are the members of the verte
我尝试编译一些像素着色器示例。但是它们都给出相同的错误信息。 “不能将着色器模型 3.0 与早期着色器模型混合使用。如果顶点着色器或像素着色器编译为 3.0,则它们必须都是。” 问题似乎是像素着色器使
我在 WPF (.NET 4.5) 应用程序的 VS2017 设计器 View 中收到此错误消息。我搜索了它但找不到解决方案。有人遇到过这个错误吗?如果是这样,您能分享修复它的详细信息吗? Inval
我是一名优秀的程序员,十分优秀!