iodes / L2DLib

Managed Live2D For .NET
38 stars 9 forks source link

L2DNative.dll crash #1

Open MikiraSora opened 6 years ago

MikiraSora commented 6 years ago
iodes commented 6 years ago

In my opinion, it seems that exceptions occur while the render device status changes. I'll try to fix it, but I'm not that good at Direct X. Or can you debug L2DNative and Pull request it?

MikiraSora commented 6 years ago

I found it's D3DERR_DEVICELOST when I make another program fullscreen. I'm trying to debug but I'm also almost not good at DX because I jsut know OpenGL.(Even I spend all time on getting ready for build project yesterday LOL.) Maybe you have to implement reset D3D Device and reload resources.

UlyssesWu commented 6 years ago

I will try to fix it if the author is not ready.

UlyssesWu commented 6 years ago

Sorry but I've encountered a problem so I probably couldn't fix this...

I always get a System.AccessViolationException at HRESULT.Check(NativeMethods.GetBackBufferNoRef(out pSurface)); for my recompiled L2DNative.dll, even if I'm not changing any code except link settings...

Still looking for a solution.

MikiraSora commented 6 years ago

Sorry but I've encountered a problem so I probably couldn't fix this...

I always get a System.AccessViolationException at HRESULT.Check(NativeMethods.GetBackBufferNoRef(out pSurface)); for my recompiled L2DNative.dll, even if I'm not changing any code except link settings...

Still looking for a solution.

Same.

UlyssesWu commented 6 years ago

In fact I've got that fixed by replacing the SDK lib with the newest 2.1 version (using vs140 version to avoid this issue). However, the next error comes soon at HRESULT CRendererL2D::EndRender(long hModel) when executing model->draw();. Yet another Access Violation.

Edit: Also get this fixed by copying new include.

UlyssesWu commented 6 years ago

(TBH, some code here is awful.)

A explaination about how this happened:

// We could delete resources and wait for D3DERR_DEVICENOTRESET and reset // the devices, but if the device is lost because of an adapter order // change then our existing D3D objects would have stale adapter // information. We'll delete everything to be safe rather than sorry.

The code is using CRendererManager::CleanupInvalidDevices() to clean all objects when device lost happens. Then it will use GetBackBufferNoRef to re-create them. However, the recreated m_pCurrentRenderer does not have any model loaded. While at this time the methods (BeginRender etc.) who need models are called, and throw the error you met when looking for a model in m_models.

The "trick" to "delete everything to be safe" brings more troubles, and it's very inefficient in the mean time. (When you reset the device you still reuse other objects, rather than delete & recreate.)

UlyssesWu commented 6 years ago

It may also lead to memory leak at this situation - the CRendererL2D doesn't seems to dispose L2DModel correctly. If we just reload a model when device lost happens, the memory usage will increase. I understand the CRendererManager is borrowed from D3DImage samples, but in fact the there are methods to handle device lost in L2D systems, like LAppModel::deviceLostCommon() and LAppModel::deviceResetCommon(). The design of CRendererManager is not suitable for these.

You may refer to Live2D_SDK_DirectX\sample\SampleApp1\src for a better framework, since it implements many L2D features and handles device lost & reset as well. I think I prefer such a implementation rather than fixing this. Sorry.

My (unsuccessful) attempt to fix this is located here. It will detect device lost and try to reload the model. However the reloaded model is somehow filled in black, and there will be an obvious memory leak.

iodes commented 6 years ago

Thank you for your help. This project was developed for the simple use of Live2D's basic functionality in WPF.

I agree with @UlyssesWu 's opinion and the L2DNative has design flaws. and this framework only supports Live2D Cubism 2 models. (Because it uses the older SDK) So, if I have a chance in the future, I want to completely redesign this project using the Cubism 3 OpenGL SDK.

If you are interested in Cubism 3 OpenGL SDK, please visit https://live2d.github.io. use it with like SharpGL, Maybe you will get higher performance than D3DImage.

I'm sorry you were not able to help directly.

UlyssesWu commented 6 years ago

(IMO I still prefer DX solutions.)

I have some experience on this since I made FreeMote.NET which demonstrate the "simple use of Emote's basic functionality in WPF". It renders in 60FPS and can be used directly in WPF or combined with SharpDX, and device lost is also handled. I don't have much time to make such a project for L2D for now... FreeMoteViewer

MikiraSora commented 6 years ago

I prefer DX ,too. Because of obs for streaming. Normally when a program is full screen ,obs cant get other programs' rendering to show except WPF(I dont know why).

Samples project of Live2d dx11 are fine for me.I try to use them.