Direct2D вызывает предупреждения LiveObjects с D3DC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Direct2D вызывает предупреждения LiveObjects с D3D

Сообщение Anonymous »

Я пытаюсь использовать совместимость Direct2D и Direct3D, как описано в Microsoft Docs
и я использую C# с Silk.Net, поэтому я создал этот класс, который инкапсулирует логику D2D1 и DWrite, цель рендеринга привязана к задний буфер .

Код: Выделить всё

    internal class Silk2DOverLay : IDisposable
{
private bool _isDisposed;
private bool _isDrawing;
private D2D _d2D;
private ComPtr _factory;

private ComPtr _renderTarget;

private ComPtr _mouseOverBrush;
private ComPtr _solidColorBrush;
private ComPtr _backColorBrush;

private ComPtr[] _textFormats;

public unsafe Silk2DOverLay()
{
_d2D = D2D.GetApi();

var guid = ID2D1Factory.Guid;
var options = new FactoryOptions { DebugLevel = DebugLevel.None };
ID2D1Factory* factory;
var ppFactory = (void**)&factory;

SilkMarshal.ThrowHResult(
_d2D.D2D1CreateFactory(FactoryType.SingleThreaded, ref guid, in options, ppFactory)
);
_factory = factory;
factory->Release();
factory = null;
InitFont();
}

public unsafe void Dispose()
{
if (!_isDisposed)
{
if (_isDrawing)
End();

for (var i = 0; i < _textFormats.Length; i++)
Disposer.Dispose(ref _textFormats[i]);

if (_renderTarget.Handle != null)
{
ulong tag1 = 0;
ulong tag2 = 0;
_renderTarget.Flush(&tag1, &tag2);
_renderTarget.Dispose();
}
if (_solidColorBrush.Handle != null)
_solidColorBrush.Dispose();
if (_backColorBrush.Handle != null)
_backColorBrush.Dispose();
if (_mouseOverBrush.Handle != null)
_mouseOverBrush.Dispose();

Disposer.Dispose(ref _factory);
Disposer.Dispose(ref _d2D);
GC.SuppressFinalize(this);
_isDisposed = true;
Debug.WriteLine("2DDevise Disposed");

}
}
public void Release()
{
Disposer.Dispose(ref _renderTarget);
Disposer.Dispose(ref _solidColorBrush);
Disposer.Dispose(ref _backColorBrush);
Disposer.Dispose(ref _mouseOverBrush);
}
private unsafe void InitFont()
{
// Dispose of existing text formats
if (_textFormats != null)
for (var i = 0; i < _textFormats.Length; i++)
Disposer.Dispose(ref _textFormats[i]);

ComPtr dWriteFactory;
var dWrite = DWrite.GetApi();
SilkMarshal.ThrowHResult(
dWrite.DWriteCreateFactory(Silk.NET.DirectWrite.FactoryType.Isolated, out dWriteFactory)
);

var fontManager = new SoulsFontManager((IntPtr)dWriteFactory.Handle);
var fontCollection = (IDWriteFontCollection*)fontManager?.GetFontCollection();

// Define font settings for each text format
var fontSettings = new[]
{
new
{
FontName = "ViewPortIcons",
FontSize = 23f,
Weight = FontWeight.Normal,
},
new
{
FontName = "Jura",
FontSize = 20f,
Weight = FontWeight.Normal,
},
new
{
FontName = "Jura",
FontSize = 15f,
Weight = FontWeight.Normal,
},
};

// Initialize text formats array
_textFormats = new ComPtr[fontSettings.Length];

for (var i = 0; i < fontSettings.Length;  i++)
{
var setting = fontSettings[i];
_textFormats[i] = CreateTextFormat(
dWriteFactory,
setting.FontName,
fontCollection,
"en-US",
setting.FontSize,
FontWeight.Normal,
FontStyle.Normal
);
_textFormats[i].SetTextAlignment(TextAlignment.Center);
_textFormats[i].SetParagraphAlignment(ParagraphAlignment.Center);
}

dWrite.Dispose();
dWriteFactory.Dispose();
fontManager?.Dispose();
}

// Helper method to create a text format
private unsafe ComPtr CreateTextFormat(
ComPtr factory,
string fontName,
IDWriteFontCollection* fontCollection,
string localeName,
float fontSize,
FontWeight fontWeight,
FontStyle fontStyle
)
{
ComPtr textFormat = default;

fixed (char* fontname = fontName)
fixed (char* localname = localeName)
{
SilkMarshal.ThrowHResult(
factory.CreateTextFormat(
fontname,
fontCollection,
fontWeight,
fontStyle,
FontStretch.Normal,
fontSize,
localname,
textFormat.GetAddressOf()
)
);
}

return textFormat;
}

/// 
///     Update all resources
/// 
/// 
BackBuffer
internal unsafe void UpdateResources(ID3D11Texture2D* backBuffer)
{
var d2dSurface = backBuffer->QueryInterface();

var props = new RenderTargetProperties(
RenderTargetType.Default,
new PixelFormat(Format.FormatUnknown, AlphaMode.Premultiplied),
96,
96
);
ID2D1RenderTarget* pRenderTarget = null;
SilkMarshal.ThrowHResult(
_factory.CreateDxgiSurfaceRenderTarget(d2dSurface.Handle, props, &pRenderTarget)
);
_renderTarget = pRenderTarget;
if (pRenderTarget != null)
{
pRenderTarget->Release();
pRenderTarget = null;
}

d2dSurface.Dispose();
CreateFontBrush();
}

internal unsafe void CreateFontBrush()
{
Disposer.Dispose(ref _solidColorBrush);
Disposer.Dispose(ref _backColorBrush);
Disposer.Dispose(ref _mouseOverBrush);

ID2D1SolidColorBrush* brush = null;
var fontcolor = SilkColors.White.D3DColor;
var props = new BrushProperties { Opacity = 1f, Transform = Matrix3X2.Identity };
SilkMarshal.ThrowHResult(_renderTarget.CreateSolidColorBrush(&fontcolor, props, &brush));
_solidColorBrush = brush;

fontcolor = SilkColors.Black.D3DColor;
props.Opacity = 0.2f;
SilkMarshal.ThrowHResult(_renderTarget.CreateSolidColorBrush(&fontcolor, props, &brush));
_backColorBrush = brush;
props.Opacity = 0.3f;
fontcolor = SilkColors.Snow.D3DColor;
SilkMarshal.ThrowHResult(_renderTarget.CreateSolidColorBrush(&fontcolor, props, &brush));
_mouseOverBrush = brush;
if (brush != null)
{
brush->Release();
brush = null;
}
}

/// 
///     Draw 2D Block
/// 
public unsafe void Draw2D(D2DBlock block)
{
if (_textFormats.Length < 3)
throw new InvalidOperationException();

IDWriteTextFormat* tFormat = null;

if (block.TextFormat <  _textFormats.Length)
tFormat = _textFormats[block.TextFormat];
else
tFormat = _textFormats[2];

var textFormat = (Silk.NET.Direct2D.IDWriteTextFormat*)tFormat;

ID2D1Brush* brush2 = default;
if (block.IsMouseOver)
brush2 = (ID2D1Brush*)_mouseOverBrush.Handle;
else
brush2 = (ID2D1Brush*)_backColorBrush.Handle;

if (block.HasBackground)
_renderTarget.FillEllipse(block.BackGroundEllipse, brush2);

var brush = (ID2D1Brush*)_solidColorBrush.Handle;
fixed (char* pText = block.ContentText)
{
_renderTarget.DrawTextA(
pText,
(uint)block.ContentText.Length,
textFormat,
block.BoundingBox,
brush,
DrawTextOptions.EnableColorFont,
DwriteMeasuringMode.Natural
);
}
}

/// 
///     Begin a 2D drawing session
/// 
public void Begin()
{
_isDrawing = true;
_renderTarget.BeginDraw();
}

/// 
///     End drawing session
/// 
public unsafe void End()
{
ulong tag1 = 0;
ulong tag2 = 0;
SilkMarshal.ThrowHResult(_renderTarget.EndDraw(&tag1, &tag2));
_isDrawing = false;
}
}
проблема в том, что при закрытии приложения я получаю множество предупреждений о живых объектах D3D11Device, но проверяю, что все ресурсы D3D удалены правильно.
И при использовании ReportLiveObjects()
code> все живые объекты — это ресурсы D3D11.
но если я не инициализирую экземпляр Silk2DOverLay, предотвращая его использование, предупреждения исчезнут

Код: Выделить всё

 public SilkGraphicsDevice(ISilkView viewport)
{
_viewport = viewport;
InitializeApis();
Initialize();
_silk2DOverLay = new Silk2DOverLay();//if i removed this line
OnResize();
CreateFence();
}
вот почему я не понимаю проблемы, если проблемы связаны с моей логикой удаления, предупреждения будут появляться независимо от Silk2DOverLay. Может ли кто-нибудь мне помочь?
логика удаления устройства и цепочки обмена
public void Dispose()
{

Код: Выделить всё

  _silk2DOverLay.Release();
Disposer.Dispose(ref _backBufferView);
Disposer.Dispose(ref _factory);
Disposer.Dispose(ref _swapChain);
Disposer.Dispose(ref _depthBufferView);
Disposer.Dispose(ref _deviceContext);
Disposer.Dispose(ref _threadShield);

Disposer.Dispose(ref _d3d11);
Disposer.Dispose(ref _dxgi);
Disposer.Dispose(ref _fence);
Disposer.Dispose(ref _device);
Disposer.Dispose(ref _silk2DOverLay);
GC.SuppressFinalize(this);

}
все объекты будут удалены при событии закрытия окна с этим классом

Код: Выделить всё

public static class Disposer
{
public static void Dispose(ref T disposable)
where T : class?, IDisposable?
{
if (disposable != null)
{
disposable.Dispose();
disposable = null;
}
}

public static unsafe void Dispose(ref ComPtr disposable)
where T : unmanaged, IComVtbl
{
if (disposable.Handle != null)
{
disposable.Dispose();
disposable = null;
}
}
}
вывод предупреждений и вывод ReportLiveObjects() здесь

Подробнее здесь: https://stackoverflow.com/questions/793 ... s-with-d3d
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»