SharpDX.WPF在渲染期间增加内存使用量

时间:2015-01-14 17:30:04

标签: wpf memory-leaks sharpdx

我已经开始在WPF应用程序中使用DirectX了。我的第一步是使用简单的库: SharpdDX.WPF。基于样本,我实现了WPF控制绘制简单线。 SharpDX.WPF使用D3DImage在WPF中渲染图像。 不幸的是,应用程序的内存一直在增加。

我实现了类TestControlRenderer:D3D10。 顶点着色器初始化为:

        var sizeInBytes = dataLength * sizeof(int) * 3;
        var bufferDescription = new BufferDescription(
            sizeInBytes,
            ResourceUsage.Dynamic,
            BindFlags.VertexBuffer,
            CpuAccessFlags.Write,
            ResourceOptionFlags.None);

        using (var stream = new DataStream(sizeInBytes, true, true))
        {
            stream.Position = 0;
            _graphDataVertexBuffer = new SharpDX.Direct3D10.Buffer(Device, stream, bufferDescription);
        }

        Device.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(_graphDataVertexBuffer, sizeof(int) * 3, 0));
        Device.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineStrip;

然后使用着色器中使用参数的常量缓冲区:

_controlInfoConstantBuffer = new ConstantBuffer<ControlParamsShaderData>(Device);
        Device.VertexShader.SetConstantBuffer(0, _controlInfoConstantBuffer.Buffer);

初始化动画重置方法被覆盖:

        base.Reset(args);
        if (args.RenderSize.Width == 0) return;

        _drawArgs = args;
        InitVertexBuffer(dataLength);

        _controlInfoConstantBuffer.Value = new ControlParamsShaderData
        {
            SamplesInControl = dataLength,
            MinSignalDataY = -1500,
            MaxSignalDataY = 1500
        };

        Device.VertexShader.SetConstantBuffer(0, _controlInfoConstantBuffer.Buffer);

最后一步是RenderScene方法:

        public override void RenderScene(DrawEventArgs args)
    {
        if (args.RenderSize.Width == 0) return;

        Device.ClearRenderTargetView(RenderTargetView, Color.Transparent);

        using (var stream = _graphDataVertexBuffer.Map(MapMode.WriteDiscard, SharpDX.Direct3D10.MapFlags.None))
        {
            for (int i = 0; i < Data.Length; i++)
            {
                stream.Write(new Vector3(i, Data[i], 0));
            }
        }
        _graphDataVertexBuffer.Unmap();
        Device.Draw(Data.Length, 0);
    }

渲染由DispatcherTimer控制,其中OnTickMethod使用点坐标更新数组,然后调用Render()方法。

我的问题很简单,就是每次渲染迭代都会产生内存泄漏或其他内容? 我不会更改后备缓冲区或创建其他对象。仅更改数据阵列,将其更新为GPU,然后着色器处理它以显示。 我的情况是在一个屏幕上显示大约30个wpf控件宽度DirectX。控件具有简单但实时的动画。那可能吗?

1 个答案:

答案 0 :(得分:2)

您很可能是在泄漏资源。您可以通过设置静态配置属性

来查看
SharpDX.Configuration.EnableObjectTracking = true;

然后调用

SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects()

在您的应用程序生命周期的各个点,看看是否有任何泄漏(至少在SharpDX方面)。您可以编辑代码以确保处置这些对象。仅在调试时启用对象跟踪 - 这会影响性能。

SharpDX用于在终结器运行时释放COM对象,如果对象尚未被放置(至少在版本2.4.2中),但后来禁用了(他们详细说明了为什么在他们的一个更改日志中,我忘了哪一个)。

此外,DirectX requires that you release objects in the reverse order they were created - 这可能会造成难以调试的内存泄漏。所以当你的代码是

var device = new Devie(...);
var effect = new Effec(Device, byteCode);
technique = effect.GetTechniqueByName(techniqueName);
inputLayout = new InputLayout(Device, _technique.GetPassByIndex(0).Description.Signature, ...);

然后你的处理代码必须是

_inputLayout.Dispose();
_technique.Dispose();
_effect.Dispose();
_device.Dispose();