vczh-libraries / GacUI

GPU Accelerated C++ User Interface, with WYSIWYG developing tools, XML supports, built-in data binding and MVVM features.
Other
2.35k stars 297 forks source link

x64位模式下崩溃问题 #75

Closed bizehao closed 2 years ago

bizehao commented 2 years ago

32位模式下正常,64位下会崩溃. 在有动画的情况下尤为明显,一会就崩了,

我经过排查,感觉像是画刷资源共用的问题,但是32位下没事,就解释不同了。 我把颜色随机改变,资源缓冲区里的每一个画刷都是唯一的,就不会崩溃。或者说 image 这样,也不会崩溃。

这是堆栈信息: KernelBase.dll!00007fff8a0dd532() 未知 d2d1debug3.dll!DebugLayer::OutputGlobalErrorMessage(unsigned int,...) 未知 d2d1debug3.dll!ResourceSDK::CResourceUsageMgr<struct IUnknown ,struct ResourceSDK::NoExemptionPolicy,struct ResourceSDK::DefaultNewAndDeleteOperators,struct ResourceSDK::RentalThreadedResourceUsagePolicy,struct Reporter,class DebugTracker,class ResourceSDK::CDictionary<struct IUnknown ,class DebugTracker,struct ResourceSDK::DefaultNewAndDeleteOperators> >::ClosedHandleCheck(struct IUnknown ) 未知 d2d1debug3.dll!DebugLayer::TestResourcePreApi(struct IUnknown const ,struct DebugTracker::Storage const ,bool) 未知 d2d1debug3.dll!DebugRenderTargetGenerated::FillEllipse(struct D2D1_ELLIPSE const ,struct ID2D1Brush *) 未知

MyGacUiTest.exe!ID2D1RenderTarget::FillEllipse(const D2D1_ELLIPSE & ellipse, ID2D1Brush brush) 行 3137 C++ MyGacUiTest.exe!vl::presentation::elements_windowsd2d::GuiSolidBackgroundElementRenderer::Render(vl::presentation::Rect<__int64> bounds) 行 392 C++ MyGacUiTest.exe!vl::presentation::compositions::GuiGraphicsComposition::Render(vl::presentation::Size_<__int64> offset) 行 309 C++ MyGacUiTest.exe!vl::presentation::compositions::GuiGraphicsComposition::Render(vl::presentation::Size_<__int64> offset) 行 325 C++ MyGacUiTest.exe!vl::presentation::compositions::GuiGraphicsComposition::Render(vl::presentation::Size_<__int64> offset) 行 325 C++ MyGacUiTest.exe!vl::presentation::compositions::GuiGraphicsComposition::Render(vl::presentation::Size_<__int64> offset) 行 325 C++ MyGacUiTest.exe!vl::presentation::compositions::GuiGraphicsComposition::Render(vl::presentation::Size_<__int64> offset) 行 325 C++ MyGacUiTest.exe!vl::presentation::compositions::GuiGraphicsComposition::Render(vl::presentation::Size_<__int64> offset) 行 325 C++ MyGacUiTest.exe!vl::presentation::compositions::GuiGraphicsComposition::Render(vl::presentation::Size_<__int64> offset) 行 325 C++ MyGacUiTest.exe!vl::presentation::compositions::GuiGraphicsComposition::Render(vl::presentation::Size_<__int64> offset) 行 325 C++ MyGacUiTest.exe!vl::presentation::compositions::GuiGraphicsComposition::Render(vl::presentation::Size_<__int64> offset) 行 325 C++ MyGacUiTest.exe!vl::presentation::compositions::GuiGraphicsComposition::Render(vl::presentation::Size_<__int64> offset) 行 325 C++ MyGacUiTest.exe!vl::presentation::compositions::GuiGraphicsHost::Render(bool forceUpdate) 行 637 C++ MyGacUiTest.exe!vl::presentation::compositions::GuiGraphicsHost::GlobalTimer() 行 560 C++ MyGacUiTest.exe!vl::presentation::windows::WindowsCallbackService::InvokeGlobalTimer() 行 49 C++ MyGacUiTest.exe!vl::presentation::windows::WindowsController::InvokeGlobalTimer() 行 1943 C++ MyGacUiTest.exe!vl::presentation::windows::GodProc(HWND__ hwnd, unsigned int uMsg, unsigned int64 wParam, int64 lParam) 行 1978 C++ [外部代码]
MyGacUiTest.exe!vl::presentation::windows::WindowsController::Run(vl::presentation::INativeWindow window) 行 1863 C++ MyGacUiTest.exe!vl::presentation::controls::GuiApplication::Run(vl::presentation::controls::GuiWindow _mainWindow) 行 124 C++ MyGacUiTest.exe!GuiMain() 行 16 C++ MyGacUiTest.exe!vl::presentation::controls::GuiApplicationInitialize() 行 477 C++ MyGacUiTest.exe!GuiApplicationMain() 行 497 C++ MyGacUiTest.exe!RendererMainDirect2D() 行 781 C++ MyGacUiTest.exe!WinMainDirect2D(HINSTANCE hInstance, void()() RendererMain) 行 629 C++ MyGacUiTest.exe!SetupWindowsDirect2DRenderer() 行 644 C++ MyGacUiTest.exe!WinMain(HINSTANCE hInstance, HINSTANCE__ hPrevInstance, char * lpCmdLine, int CmdShow) 行 31 C++ [外部代码]

bizehao commented 2 years ago

https://github.com/vczh-libraries/Release/tree/master/Tutorial/GacUI_Controls/Animation 这个的几个小球转动的界面很容易触发

bizehao commented 2 years ago

和#3 的现象一样

vczh commented 2 years ago

我估摸着这是Direct2D的问题,在Windows 10的第一版及所有旧版Windows都不要用Direct2D的64位。我先close了,有什么新发现的话再reopen。

我并不exactly知道为什么这个现象会发生,但是32位和64位的代码是完全一样的。但是自从我用Windows 10并更新一次之后,无论64位跑多少次都看不到这个崩溃了。

bizehao commented 2 years ago

我这也是最新版本win10,哎,搞不懂,我也觉得是direct2d的问题

vczh commented 2 years ago

下断点看看GacUI跑起来用的是Direct2D 2.0还是2.1?搜2_1就能快速定位到代码。

bizehao commented 2 years ago

我刚刚加了些修改,不会崩了,下面是我的修改 GuiGraphicsRenderersWindowsDirect2D.cpp

#define IMPLEMENT_BRUSH_ELEMENT_RENDERER_LINEAR_GRADIENT_BRUSH(TRENDERER)\
            void TRENDERER::CreateBrush(IWindowsDirect2DRenderTarget* _renderTarget)\
            {\
                if(_renderTarget)\
                {\
                    oldColor=Pair<Color, Color>(element->GetColor1(), element->GetColor2());\
                    brush=_renderTarget->CreateDirect2DLinearBrush(oldColor.key, oldColor.value);\
                    brush->AddRef();\ //新增
                }\
            }\
            void TRENDERER::DestroyBrush(IWindowsDirect2DRenderTarget* _renderTarget)\
            {\
                if(_renderTarget && brush)\
                {\
                    _renderTarget->DestroyDirect2DLinearBrush(oldColor.key, oldColor.value);\
                    brush->Release(); \ //新增
                    brush = nullptr; \ //新增 可有可无
                }\
            }\
vczh commented 2 years ago

这就很奇怪,CreateDirect2DLinearBrush内部就是保证refcount是1的,而且也没人Release过(除了render target没了之后释放全部东西),理应不需要这么修改。不过如果这样确实能解决问题那我就加上去。

不过既然能这么修,说不定真的是Direct2D的bug后来被修掉了,才解释了为什么现在我一直没办法在新的win10上repro。