Can DirectDraw game access a backbuffer without locking it?
Asked Answered
V

1

12

I'm modding an old Windows DirectDraw game. I've created a DirectDraw proxy. It logs every IDirectDraw and IDirectDrawSurface call. The backbuffer looks like this after one BltFast call:

enter image description here

And like this before the next BltFast call:

enter image description here

These pictures are dumped by Locking-copying-Unlocking the backbuffer before and after any BltFast call. There are no other IDirectDraw(Surface) calls between these two BltFast calls, especially no Lock/Unlock calls. How is this possible?

Vansickle answered 17/6, 2014 at 20:57 Comment(3)
Completely wild guess: Is it posslble the second image is somehow the result of the first BltFast call, that hadn't actually made it through the pipeline in time for the first Lock/copy/Unlock?Swap
Well... I don't think so... This API is direct and synchronous as far as I know. I think that there is some possible bypass of DirectDraw API. Only very dynamic objects are drawn thia way. Only someone with deep understanding of DirectDraw and WinApi could know.Vansickle
Isn't it true that DirectDraw can be used in conjunction with the GDI? In which case you should probably take a look at potential GDI or GDI+ calls that modify the said back bufferAndyane
N
1

As far as I can tell, it looks like the game might be drawing in multiple stages, and you are catching it in-between. IE, the game calls blit once to render its background, then again (possibly multiple times) to render interactive 'sprites'. (However, the order could well be reversed, meaning that the second frame you capture is actually the first layer of the next loop.)

As far as the backbufer goes, I was able to find this in MSDNs documentation for DirectDraw: https://msdn.microsoft.com/en-us/library/windows/desktop/gg426183(v=vs.85).aspx

BltFast always attempts an asynchronous blit if it is supported by the hardware.

So it could be a race, possibly, but I would imagine that any attempt to lock would block until this completes.

And also... https://msdn.microsoft.com/en-us/library/windows/desktop/gg426208%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

Do not call DirectDraw bitblt functions to bitblt from a locked region of a surface. If you do, the bitblt returns either DDERR_SURFACEBUSY or DDERR_LOCKEDSURFACES. GDI blit functions also silently fail when used on a locked video memory surface.

This implies that bitblt itself has locking semantics. Given that GDI is not allowed to access a surface that is explicitly locked, it's also likely that it cannot access a surface in the middle of an asynchronous blit operation.

So to specifically answer your question, it appears GDI might be able to access a surface without locking it.

Of course, there's all kinds of weird things that can be done in the name of performance, so who knows what other kind of hacks they might have done?

I will say though, that I am not an expert by any means at DirectDraw, and am operating under the assumption that the backbuffer is just like any other surface.

Nims answered 18/8, 2016 at 23:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.