Эффективная многопоточность Direct2D
Я пишу приложение для чтения электронных книг для Магазина Windows. Я использую цепочки обмена Direct2D + DXGI для отображения страниц книги на экране.
Содержание моей книги иногда бывает довольно сложным (геометрия, растровые изображения, маски и т. Д.), Поэтому его рендеринг может занять до 100 мс. Поэтому я пытаюсь сделать внеэкранный рендеринг растрового изображения в отдельном потоке, а затем просто показать это растровое изображение в основном потоке.
Тем не менее, я не могу понять, как это сделать эффективно.
До сих пор я пробовал два подхода:
Используйте одинID2D1Factory
с флагом D2D1_FACTORY_TYPE_MULTI_THREADED создайтеID2D1BitmapRenderTarget
и использовать его в фоновом потоке для рендеринга за пределами экрана. (Это дополнительно требуетID2D1Multithread::Enter/Leave
наIDXGISwapChain::Present
операции). Проблема в том,ID2D1RenderTarget::EndDraw
работа в фоновом потоке иногда занимает до 100 мс, и рендеринг основного потока блокируется на этот период из-за внутренней блокировки Direct2D.
Используйте отдельныйID2D1Factory
в фоновом потоке (как описано вhttp://www.sdknews.com/ios/using-direct2d-for-server-side-rendering) и отключите внутреннюю синхронизацию Direct2D. В этом случае нет перекрестной блокировки между двумя потоками. К сожалению, в этом случае я не могу использовать результирующее растровое изображение в основномID2D1Factory
напрямую, потому что он принадлежит другому заводу. Я должен переместить растровые данные в память процессора, а затем скопировать их в память графического процессора основногоID2D1Factory
, Эта операция также приводит к значительным задержкам (я полагаю, что это связано с большим доступом к памяти, но я не уверен).
Есть ли способ сделать это эффективно?
Постскриптум Все сроки приведены для планшета Acer Switch 10. На обычном ПК Core i7 оба подхода работают без видимой задержки.