Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

设备丢失问题依然存在 #4

Closed
bajdcc opened this issue Feb 16, 2015 · 3 comments
Closed

设备丢失问题依然存在 #4

bajdcc opened this issue Feb 16, 2015 · 3 comments

Comments

@bajdcc
Copy link

bajdcc commented Feb 16, 2015

目前学习Gac框架中(0.7.5最新版本),想借助Gac和VFS自己做个东东,将算法和数据结构方面用STL和WTF替换了,相关的宏如DEFINE_GUI_GRAPHICS_ELEMENT等用类模板替代了(方便调试),从实现基本的控件做起(代码太庞大不易掌握),做一个袖珍版。
D2D当设备丢失时会有D2DERR_RECREATE_TARGET
,这时需要重新创建资源,这可以在Cache类中实现,由于Cache是资源的所有者,RecreateRenderTarget时就可以调用Cache重新创建资源。
发生设备丢失的情况:打开GUI程序,并最小化,这时一旦有UAC窗口出现(如打开Spy++等),关掉UAC后,GUI程序便空白。这是由于0.7.5版本中的GacUIWindows.cpp中144行,发现index == -1一直为false,导致没有处理。

解决方法是:在D2DERR_RECREATE_TARGET时调用D2DProvider::RecreateRenderTarget,windowComposition->SetAttachedWindow不必调用了,然后在D2DWindowListener::RecreateRenderTarget中将renderTarget先lock住(防止RenderTargetChanged执行过程中调用D2DRenderTarget::GetDirect2DRenderTarget出错,使之返回nullptr),使得D2DRenderTarget::GetDirect2DRenderTarget返回null,然后执行GetMainComposition()->SetRenderTarget(nullptr)触发RenderTargetChanged操作,最后unlock。
这时,renderTarget已经为空,还未创建,创建的时机在D2DWindowListener::RebuildCanvas中(设备丢失时,窗口不会有焦点,是不用展示的,故不用立即创建资源)。CreateHwndRenderTarget成功后,调用ID2DRenderTarget的RecreateResource和GetDirect2DResourceManager的RecreateResource,原因是,两者都有cache资源需要重新创建。等创建完资源过后,调用GetMainComposition()->SetRenderTarget设置renderTarget并触发RenderTargetChanged,完成资源的全部重新创建。

期间还发现了Gac的一些细节上的问题,如多行TextBox中按左右键,焦点在竖直方向上有“节奏”变化等(仅当TextBox比较小时),选中文本时鼠标移至TextBox外下方不断移动,也会发生这种情况。
解决方法是TextBoxCommonInterface::Move(TextPos pos, bool shift)中连续调用两次callback->ScrollToView(viewPoint),负负得正。。

最后感谢轮子哥分享这么好的代码(>^ω^<)

@vczh
Copy link
Owner

vczh commented Feb 26, 2015

不错,我回头试试……

@vczh
Copy link
Owner

vczh commented Feb 26, 2015

index == -1是我写错了,应该是反过来的。然后我发现最小化的时候创建失败,其实是因为计算出来的ClientSize的高度是负数导致CreateHwndRenderTarget失败了,所以我在RebuildCanvas上面加了两句
if (size.x <= 1) size.x = 1;
if (size.y <= 1) size.y = 1;
然后测试了一下你说的场景,好像没问题了……代码会在0.7.7.0里面进去。你也可以手动改这两个地方看看我的做法是不是在你那也可以。

@vczh vczh closed this as completed Feb 26, 2015
@bajdcc
Copy link
Author

bajdcc commented Feb 27, 2015

ok问题解决了~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants