我正在为Windows商店编写电子书阅读器应用程序。我使用Direct2D + DXGI交换链在屏幕上呈现图书页面。
我的书内容有时相当复杂(几何,位图,面具等),所以它可以用100毫秒来渲染。因此,我试图在一个单独的线程中对位图进行屏幕外呈现,然后在主线程中显示这个位图。
然而,我不知道如何有效地做到这一点。
到目前为止,我已经尝试了两种方法:
ID2D1BitmapRenderTarget
并在后台线程中使用它进行屏幕外呈现。(这还需要ID2D1Multithread::Enter/Leave
on IDXGISwapChain::Present
操作)。问题是,后台线程中的ID2D1RenderTarget::EndDraw
操作有时占用高达100 is,并且由于内部Direct2D锁定,主线程呈现在此期间被阻塞。ID2D1Factory
(如http://www.sdknews.com/ios/using-direct2d-for-server-side-rendering所述),并关闭内部Direct2D同步。在这种情况下,在两个线程之间没有交叉锁定。不幸的是,在这种情况下,我不能直接在主ID2D1Factory
中使用生成的位图,因为它属于不同的工厂。我必须将位图数据移动到CPU内存,然后将其复制到主ID2D1Factory
的GPU内存中。这个操作还引入了很大的延迟(我认为这是由于内存访问很大,但我不确定)。有办法有效地做到这一点吗?
这里所有的时间都给出了宏碁开关10平板电脑的时间。在常规的核心i7 PC上,这两种方法都没有任何明显的滞后。
发布于 2015-10-22 07:59:28
好吧,我找到了解决办法。
基本上,我所需要的只是修改方法2,以便在两个DirectX工厂集之间使用DXGI资源共享。我将跳过所有血淋淋的细节(它们可以在这里找到:http://xboxforums.create.msdn.com/forums/t/66208.aspx),但基本步骤是:
ID3D11Device2
,通过CreateTexture2D
D3D11_BIND_RENDER_TARGET
、D3D11_BIND_SHADER_RESOURCE
、D3D11_RESOURCE_MISC_SHARED_NTHANDLE
和D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX
标志创建D3D 2D纹理。IDXGIResource1
,并使用XGI_SHARED_RESOURCE_READ
和DXGI_SHARED_RESOURCE_WRITE
从它调用CreateSharedHandle
。ID3D11Device2::OpenSharedResource1
在后台线程中的辅助资源集中打开此共享纹理。IDXGIKeyedMutex::AcquireSync
),从它创建渲染目标(ID2D1Factory2::CreateDxgiSurfaceRenderTarget
),在其上绘制并释放互斥体(IDXGIKeyedMutex::ReleaseSync
)。注意,互斥锁是必要的。不这样做会导致一些神秘的DirectX调试错误消息,错误的操作甚至崩溃。
发布于 2015-10-19 19:54:42
tl;dr:在软件模式下对后台线程上的位图进行渲染。在硬件模式下从位图中绘制UI线程上的目标。
到目前为止,我能够找到的最佳方法是使用带有软件呈现的后台线程(IWICImagingFactory::CreateBitmap
和ID2D1Factory::CreateWicBitmapRenderTarget
),然后将其复制到线程上的硬件位图中,并通过ID2D1RenderTarget::CreateBitmapFromWicBitmap
将硬件呈现目标复制到线程上。然后用ID2D1RenderTarget::DrawBitmap
来解释。
这就是paint.net 4.0进行选择呈现的方式。当您使用lasso工具绘制选择时,它将使用后台线程异步绘制选择大纲( UI线程不会等待它完成)。你可以结束一个非常复杂的多边形,因为笔画风格和动画。我渲染它4次,其中每个动画帧有一个稍微不同的偏移量的虚线笔画风格。
显然,当多边形变得更加复杂时,这种呈现可能需要一段时间(也就是说,如果您继续涂鸦一段时间)。当您使用移动选择工具时,我还有其他一些特殊的优化,它允许您进行转换(旋转、平移、缩放):如果背景线程还没有用新的转换重新呈现当前多边形,那么我将使用新的转换呈现旧位图(包含当前多边形和旧转换)。当后台线程追赶时,选择轮廓可能会被扭曲(缩放)或剪裁(在可视区域外翻译),但是要为60 for的响应度付出很小的代价。此优化工作非常好,因为您不能同时修改多边形和选择的转换。
https://stackoverflow.com/questions/33143589
复制相似问题