首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >高效Direct2D多线程

高效Direct2D多线程
EN

Stack Overflow用户
提问于 2015-10-15 08:32:30
回答 2查看 2.1K关注 0票数 8

我正在为Windows商店编写电子书阅读器应用程序。我使用Direct2D + DXGI交换链在屏幕上呈现图书页面。

我的书内容有时相当复杂(几何,位图,面具等),所以它可以用100毫秒来渲染。因此,我试图在一个单独的线程中对位图进行屏幕外呈现,然后在主线程中显示这个位图。

然而,我不知道如何有效地做到这一点。

到目前为止,我已经尝试了两种方法:

  1. 使用带有D2D1_FACTORY_TYPE_MULTI_THREADED标志的单个D2D1_FACTORY_TYPE_MULTI_THREADED,创建ID2D1BitmapRenderTarget并在后台线程中使用它进行屏幕外呈现。(这还需要ID2D1Multithread::Enter/Leave on IDXGISwapChain::Present操作)。问题是,后台线程中的ID2D1RenderTarget::EndDraw操作有时占用高达100 is,并且由于内部Direct2D锁定,主线程呈现在此期间被阻塞。
  2. 在后台线程中使用单独的ID2D1Factory (如http://www.sdknews.com/ios/using-direct2d-for-server-side-rendering所述),并关闭内部Direct2D同步。在这种情况下,在两个线程之间没有交叉锁定。不幸的是,在这种情况下,我不能直接在主ID2D1Factory中使用生成的位图,因为它属于不同的工厂。我必须将位图数据移动到CPU内存,然后将其复制到主ID2D1Factory的GPU内存中。这个操作还引入了很大的延迟(我认为这是由于内存访问很大,但我不确定)。

有办法有效地做到这一点吗?

这里所有的时间都给出了宏碁开关10平板电脑的时间。在常规的核心i7 PC上,这两种方法都没有任何明显的滞后。

EN

Stack Overflow用户

回答已采纳

发布于 2015-10-22 07:59:28

好吧,我找到了解决办法。

基本上,我所需要的只是修改方法2,以便在两个DirectX工厂集之间使用DXGI资源共享。我将跳过所有血淋淋的细节(它们可以在这里找到:http://xboxforums.create.msdn.com/forums/t/66208.aspx),但基本步骤是:

  1. 创建两组DirectX资源: main (将用于屏幕上呈现)和辅助资源(用于屏幕外呈现)。
  2. 使用主资源集的ID3D11Device2,通过CreateTexture2D D3D11_BIND_RENDER_TARGETD3D11_BIND_SHADER_RESOURCED3D11_RESOURCE_MISC_SHARED_NTHANDLED3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX标志创建D3D 2D纹理。
  3. 从它获得共享句柄,方法是将它转换为IDXGIResource1,并使用XGI_SHARED_RESOURCE_READDXGI_SHARED_RESOURCE_WRITE从它调用CreateSharedHandle
  4. 通过调用ID3D11Device2::OpenSharedResource1在后台线程中的辅助资源集中打开此共享纹理。
  5. 获取这个纹理的键互斥体(IDXGIKeyedMutex::AcquireSync),从它创建渲染目标(ID2D1Factory2::CreateDxgiSurfaceRenderTarget),在其上绘制并释放互斥体(IDXGIKeyedMutex::ReleaseSync)。
  6. 在主线程上,在主资源集中,从步骤2中创建的纹理中获取互斥体并创建共享位图,绘制此位图,然后释放互斥体。

注意,互斥锁是必要的。不这样做会导致一些神秘的DirectX调试错误消息,错误的操作甚至崩溃。

票数 9
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33143589

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档