I'm writing a ebook reader app for Windows Store. I'm using Direct2D + DXGI swap chains to render book pages on screen.
My book content sometimes is quite complex (geometry, bitmaps, masks, etc), so it can take up to 100 ms to render it. So I'm trying to do an off-screen rendering to a bitmap in a separate thread, and then just show this bitmap in main thread.
However, I can't figure how to do it efficiently.
So far I've tried two approaches:
Use a single
ID2D1Factory
with D2D1_FACTORY_TYPE_MULTI_THREADED flag, createID2D1BitmapRenderTarget
and use it in background thread for off-screen rendering. (This additionally requiresID2D1Multithread::Enter/Leave
onIDXGISwapChain::Present
operations). Problem is,ID2D1RenderTarget::EndDraw
operation in background thread sometimes take up to 100ms, and main thread rendering is blocked for this period due to internal Direct2D locking.Use a separate
ID2D1Factory
in background thread (as described in http://www.sdknews.com/ios/using-direct2d-for-server-side-rendering) and turn off internal Direct2D synchronization. There is no cross-locking betwen two threads in this case. Unfortunately, in this case I can't use resulting bitmap in mainID2D1Factory
directly, because it belongs to a different factory. I have to move bitmap data to CPU memory, then copy it into GPU memory of the mainID2D1Factory
. This operation also introduce significant lags (I believe it to be due to large memory accesses, but I'm not sure).
Is there a way to do this efficiently?
P.S. All the timing here are given for Acer Switch 10 tablet. On regular Core i7 PC both approaches work without any visible lag.