Open insinfo opened 7 years ago
You have most likely allocations elsewhere un your program, where you don't release objects. You can try to diagnostic that by tweaking Configuration.EnableObjectTracking
with ObjectTracker
This is my code
using System;
using System.Collections.Generic;
using System.Windows.Interop;
using System.Windows;
//SharpDX
using SharpDX;
using SharpDX.Direct2D1;
using SharpDX.Direct3D;
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using SharpDX.Mathematics.Interop;
namespace UIDesign
{
class D2DCanvas : System.Windows.Controls.Grid
{
private SharpDX.Direct3D11.Device Direct3D11Device;
private SharpDX.Direct3D11.Texture2D Direct3D11Texture2D;
private SharpDX.Direct2D1.RenderTarget Direct2D1RenderTarget;
private SharpDX.Direct2D1.Factory Direct2D1Factory;
private SharpDX.Direct3D11.Texture2DDescription Direct3D11Texture2DDescription;
private SharpDX.DXGI.Surface DXGISurface;
private SharpDX.Direct2D1.PixelFormat Direct2D1PixelFormat;
private SharpDX.Direct2D1.RenderTargetProperties Direct2D1RenderTargetProperties;
private RawRectangleF rect;
private SharpDX.Direct3D9.DeviceEx Direct3D9DeviceEx;
private SharpDX.Direct3D9.Texture Direct3D9Texture;
private SharpDX.Direct3D9.Surface Direct3D9Surface;
private SharpDX.Direct3D9.Direct3DEx D3DContext;
private SharpDX.Direct3D9.PresentParameters presentParams;
private SharpDX.Direct3D9.CreateFlags createFlags;
private SharpDX.Direct3D9.Format direct3D9Format;
private IntPtr sharedHandle;
private D3DImage d3DImageSource;
private int textureWidth;
private int textureHeight;
private System.Windows.Controls.Image imageControl;
public List<Element> ElementCollection;
public D2DCanvas()
{
}
//Inicializa tudo
public void Initialize()
{
//SharpDX.Configuration.EnableObjectTracking = true;
imageControl = new System.Windows.Controls.Image();
imageControl.Stretch = System.Windows.Media.Stretch.None;
imageControl.HorizontalAlignment = HorizontalAlignment.Stretch;
imageControl.VerticalAlignment = VerticalAlignment.Stretch;
textureWidth = (int)this.MinWidth;
textureHeight = (int)this.MinHeight;
this.Children.Add(imageControl);
ElementCollection = new List<Element>();
Direct2DStart();
Draw();
D3DImageSource();
rect = new RawRectangleF();
}
public void Draw()
{
//Aqui inicia o desenho
Direct2D1RenderTarget.BeginDraw();
//Limpa a tela
Direct2D1RenderTarget.Clear(Util.RGBColorToRawColor4(0, 0, 255));
foreach (Element element in ElementCollection)
{
if (element.GetType() == typeof(Rectangle))
{
Rectangle retangle = (Rectangle)element;
rect.Left = retangle.X;
rect.Top = retangle.Y;
rect.Right = retangle.X + retangle.Width;
rect.Bottom = retangle.Y + retangle.Height;
RawColor4 color = Util.RGBColorToRawColor4(255, 0, 0);
SolidColorBrush solidColorBrush = new SolidColorBrush(Direct2D1RenderTarget, color);
Direct2D1RenderTarget.FillRectangle(rect, solidColorBrush);
Util.SafeDispose(ref solidColorBrush);
}
}
//Finaliza o desenho
Direct2D1RenderTarget.EndDraw();
//
Direct3D11Device.ImmediateContext.Flush();
}
//Redesenha
public void UpdateDraw()
{
Draw();
d3DImageSource.Lock();
d3DImageSource.AddDirtyRect(new System.Windows.Int32Rect(0, 0, d3DImageSource.PixelWidth, d3DImageSource.PixelHeight));
d3DImageSource.Unlock();
}
//Atualiza a tela apos Window Resize
public void UpdateResize()
{
try
{
//Direct2D Reset
Util.SafeDispose(ref Direct2D1RenderTarget);
Util.SafeDispose(ref Direct2D1Factory);
Util.SafeDispose(ref Direct3D11Texture2D);
textureWidth = Math.Max((int)ActualWidth, 100);
textureHeight = Math.Max((int)ActualHeight, 100);
Direct3D11Texture2DDescription.Width = textureWidth;
Direct3D11Texture2DDescription.Height = textureHeight;
Direct2DConfig();
//ImageSource Reset
Direct3D9Texture = null;
d3DImageSource.Lock();
d3DImageSource.SetBackBuffer(D3DResourceType.IDirect3DSurface9, IntPtr.Zero);
d3DImageSource.Unlock();
D3DImageSourceConfig();
UpdateDraw();
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
/*---------------------------------- Direct2D -----------------------------------------*/
private void Direct2DStart()
{
//Inicialiso o dispositivo Direct2D
Direct3D11Device = new SharpDX.Direct3D11.Device(DriverType.Hardware, DeviceCreationFlags.BgraSupport);
//Defino as parametros da Textura 2D do Direct3D 11
Direct3D11Texture2DDescription = new Texture2DDescription();
Direct3D11Texture2DDescription.BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource;
Direct3D11Texture2DDescription.Format = Format.B8G8R8A8_UNorm;
Direct3D11Texture2DDescription.MipLevels = 1;
Direct3D11Texture2DDescription.SampleDescription = new SampleDescription(1, 0);
Direct3D11Texture2DDescription.Usage = ResourceUsage.Default;
Direct3D11Texture2DDescription.OptionFlags = ResourceOptionFlags.Shared;
Direct3D11Texture2DDescription.CpuAccessFlags = CpuAccessFlags.None;
Direct3D11Texture2DDescription.ArraySize = 1;
Direct3D11Texture2DDescription.Width = textureWidth;
Direct3D11Texture2DDescription.Height = textureHeight;
//Inicialiso o PixelFormat do Direct2D
Direct2D1PixelFormat = new SharpDX.Direct2D1.PixelFormat(Format.Unknown, SharpDX.Direct2D1.AlphaMode.Premultiplied);
//Inicialiso o RenderTargetProperties do Direct2D
Direct2D1RenderTargetProperties = new RenderTargetProperties(Direct2D1PixelFormat);
Direct2DConfig();
//Direct3D11Device.ImmediateContext.Rasterizer.SetViewport(0, 0, width, height, 0.0f, 1.0f);
}
private void Direct2DConfig()
{
//Cria uma textura 2D Direct3D 11
Direct3D11Texture2D = new Texture2D(Direct3D11Device, Direct3D11Texture2DDescription);
//Inicialiso a superficie DXGI do Direct3D 11
DXGISurface = Direct3D11Texture2D.QueryInterface<Surface>();
//Inicializo o Factory do Direct2D
Direct2D1Factory = new SharpDX.Direct2D1.Factory();
//Inicialiso o RenderTarget do Direct2D
Direct2D1RenderTarget = new RenderTarget(Direct2D1Factory, DXGISurface, Direct2D1RenderTargetProperties);
//Direct3D11Device.ImmediateContext.Rasterizer.SetViewport(0, 0, width, height, 0.0f, 1.0f);
}
/*---------------------------------- ImageSorce -----------------------------------------*/
private void D3DImageSource()
{
//Cria uma Instancia da class WPF D3DImage
d3DImageSource = new D3DImage();
// Cria o objeto D3D, que é necessário para criar o D3DDevice.
D3DContext = new SharpDX.Direct3D9.Direct3DEx();
// Configurar a estrutura usada para criar o D3DDevice.
presentParams = new SharpDX.Direct3D9.PresentParameters();
presentParams.Windowed = true;
presentParams.SwapEffect = SharpDX.Direct3D9.SwapEffect.Discard;
presentParams.DeviceWindowHandle = NativeMethods.GetDesktopWindow();
presentParams.PresentationInterval = SharpDX.Direct3D9.PresentInterval.Default;
//Cria as Flags Direct3D 9
createFlags = SharpDX.Direct3D9.CreateFlags.HardwareVertexProcessing | SharpDX.Direct3D9.CreateFlags.Multithreaded | SharpDX.Direct3D9.CreateFlags.FpuPreserve;
// Criar o dispositivo Direct3D 9
Direct3D9DeviceEx = new SharpDX.Direct3D9.DeviceEx(D3DContext, 0, SharpDX.Direct3D9.DeviceType.Hardware, IntPtr.Zero, createFlags, presentParams);
direct3D9Format = SharpDX.Direct3D9.Format.A8R8G8B8;
D3DImageSourceConfig();
imageControl.Source = d3DImageSource;
d3DImageSource.Lock();
d3DImageSource.AddDirtyRect(new System.Windows.Int32Rect(0, 0, d3DImageSource.PixelWidth, d3DImageSource.PixelHeight));
d3DImageSource.Unlock();
}
private void D3DImageSourceConfig()
{
sharedHandle = Direct3D11Texture2D.QueryInterface<SharpDX.DXGI.Resource>().SharedHandle;
//Criar uma textura Direct3D 9
Direct3D9Texture = new SharpDX.Direct3D9.Texture(Direct3D9DeviceEx, Direct3D11Texture2D.Description.Width, Direct3D11Texture2D.Description.Height, 1, SharpDX.Direct3D9.Usage.RenderTarget, direct3D9Format, SharpDX.Direct3D9.Pool.Default, ref sharedHandle);
//Criar uma superficie Direct3D 9
Direct3D9Surface = Direct3D9Texture.GetSurfaceLevel(0);
d3DImageSource.Lock();
d3DImageSource.SetBackBuffer(D3DResourceType.IDirect3DSurface9, Direct3D9Surface.NativePointer);
d3DImageSource.Unlock();
}
public void Release()
{
//Direct2D
Util.SafeDispose(ref Direct2D1RenderTarget);
Util.SafeDispose(ref Direct2D1Factory);
Util.SafeDispose(ref d3DImageSource);
Util.SafeDispose(ref Direct3D11Texture2D);
Util.SafeDispose(ref Direct3D11Device);
//ImageSource
Util.SafeDispose(ref Direct3D9Texture);
Util.SafeDispose(ref Direct3D9Surface);
Util.SafeDispose(ref Direct3D9DeviceEx);
Util.SafeDispose(ref D3DContext);
}
}
}
Hey, could you please give me a feedback at least on my previous comment. Have you tried the ObjectTracker
? What are the results? I really cannot afford to debug this for you.
I have created a WPF application on windows 10 64bit to test Direct2D and find out about this scenario. It is terrible because I wanted to use Direct2D to speed up the drawings on the canvas. With this bug, it is impossible, Just keep modifying the size of the window so the memory usage goes up absurdly. I saw that the problem is related to the dispose, it seems that the resources are not being destroyed.
Direct3D11Texture2D.Dispose (); Direct3D11Texture2D = Null; DXGISurface.Dispose (); DXGISurface = null; Direct2D1Factory.Dispose (); Direct2D1Factory = null; Direct2D1RenderTarget.Dispose (); Direct2D1RenderTarget = null;