【发布时间】:2017-05-10 22:01:41
【问题描述】:
我对 DirectX 和 Direct2D 还很陌生。我正在尝试使用 SharpDx 卸载硬件上的工作,而不是消耗 CPU 进行持续渲染。
我有一个媒体基础管道。我实现了一个自定义渲染器。我的应用程序使用 C# 和 WPF。
我从管道中获取原始像素并将它们推送到正在更新图像控件的 WritableBitamps。显然,图像控件存在一个已知问题,它可以固定画笔。我的应用程序可以针对这个问题抛出内存异常。如果原始框架不大,则问题不明显。比方说 800x600 视频。
如果播放 1920 x 1080 的视频,我会遇到更多问题。
我尝试创建一个 BitmapSource 并更新后台缓冲区(以防止不断创建 bitamp),但这并没有帮助。在某些情况下,记忆会疯狂增长。到目前为止,我正在为每幅画创建新的 bitamp。我知道这是测试的临时解决方案。
所以现在我正在试验的是 SharpDx。我正在使用一个名为 D2DControl 的包装器,它包装了一个 D3DImage 和设置代码,并允许创建一个 WPF 控件,您可以将其插入到您的视图中(类似于 D3DImage。D2DControl 派生自 D3DImage)我知道有些人讨厌外部链接,但这里是链接以防有人感兴趣。
https://github.com/dalance/D2dControl/tree/master/D2dControl
这个包装器所做的是它隐藏了很多细节。它公开了一个允许绘图发生的 Render() 方法。
这就是我所拥有的。
public class MediaDisplayControl : D2dControl.D2dControl
{
private Bitmap backBufferBmp;
public FrameRenderer Renderer { get; set; }
public override void Render(RenderTarget target)
{
var sampleData = Renderer.Samples.FirstOrDefault();
if (sampleData != null)
{
if (backBufferBmp == null)
backBufferBmp = new Bitmap(target, new SharpDX.Size2(sampleData.Width, sampleData.Height), new BitmapProperties(target.PixelFormat));
backBufferBmp.CopyFromMemory(sampleData.Pixels, sampleData.Stride);
target.Transform = new RawMatrix3x2 { M11 = target.Size.Width / backBufferBmp.Size.Width, M22 = target.Size.Height / backBufferBmp.Size.Height };
target.DrawBitmap(backBufferBmp, 1f, BitmapInterpolationMode.Linear);
}
}
}
我尝试了在每次渲染上创建新的 bitamp 或重复使用它的变体。在 1920x1080 视频帧上,内存一次跳跃 300mg,直到达到 1.2GB 并停止。
我正在缩放位图,因为 D3DImage 没有缩放位放大器。使用 Image 控件,您可以编写一个大的 bitamp,它会缩放到视图大小。使用此代码,如果图像大于容器,则图像会被裁剪。
无论如何,转换不会改变结果。 CopyFromMemory 和 DrawBitamp 的行为增加了内存。
所以我的问题是: 1)我在做什么有意义吗? 2) 我可以采取其他措施来防止内存问题吗?
感谢您花时间阅读本文。
【问题讨论】:
标签: memory-leaks bitmap directx sharpdx hardware-acceleration