0

Problem

I am trying to draw Direct2D content to a DirectDraw surface (backbuffer), this part is fine. The problem is the cost of using GetDC() on the DirectDraw surface (on a modern pc), which locks and gets the device context which is then used to BindDC() with Direct2D before the Direct2D drawing occurs. GetDC & ReleaseDC comes at such a substantial cost, that if done once per frame I am getting what feels like 15FPS.

Is there a faster or alternative way to Get/ReleaseDC() on a DirectDraw surface or somehow cache it so as to not have unbearable performance ?

Backstory I have on old game built on the old DirectDraw, the source is lost and I'm trying to use hooks to upgrade the graphics API. I'd eventually like to move all directdraw API calls to direct2d.

Nork
  • 23
  • 5
  • why are you calling `GetDC` on per frame? The usual approach is call it once and remember the handle it returns ... – Spektre May 05 '20 at 09:23
  • @Spektre I was under the impression GetDC had to be called per frame as GetDC also performs the surface lock, atleast from what MSDN was saying on the call. Granted I haven't tried doing it only once before, for that reason. Ill try it and post my result. – Nork May 05 '20 at 11:05
  • I do not use Direct (I have aversion to it based on experience) but I often need GetDC either for winapi based stuff like screenshots and grabbing etc, getting GL context or similar stuff and unless your target app is not thrashing contexts it should be enough to call it just once. I think there are other functions to lock the context like lockbits or something like that ... but I might be wrong here as I am used to GL and VCL encapsulated GDI which is sometimes much different then native GDI and DX – Spektre May 05 '20 at 11:11
  • @Spektre I gave it a go in various ways, but to no success. The DC changes every time, setting the window style to CS_OWNDC has no effect either. Trying to reuse an old DC shows nothing when drawing. – Nork May 06 '20 at 09:20
  • hmm then the target App is thrashing handles and you have no other option... – Spektre May 06 '20 at 11:30
  • 2
    While I haven't found a solution to this exact issue, I made a work around. I created a GDI compatible hWND render target instead of a GDI compatible DC render target, I then stopped the original DirectDraw surface flipping to prevent flickering between them. Then instead of using Direct2D to draw to the DirectDraw surface, I did the opposite, I drawed the DirectDraw backbuffer to the Direct2D render target using GDI BitBlt. Surprisingly the lag from GetDC on the DirectDraw surface seemly disappeared and it's running smoothly. – Nork May 07 '20 at 01:48
  • That indicates the `GetDC` did wait until rendering was done on the App side so where paused probably on both sides every other frame ... good to know :) – Spektre May 07 '20 at 07:24

0 Answers0