Current version

v1.10.4 (stable)


Main page
Archived news
Plugin SDK
Knowledge base
Contact info
Other projects


Blog Archive

Wine's DirectDraw implementation

I had a support question about VirtualDub blanking out screens again in Wine, so I decided to take another look out of curiosity.

A long time ago, when I released VirtualDub 1.5.5, I started receiving reports of issues with Wine. Specifically, as soon as VirtualDub tried to display any video, the entire screen would be overwritten. Wine was fairly immature at the time and still had a lot of major problems with commercial applications, so I wasn't surprised to determine that it was an issue with Wine and left it as such. That was the first version that had full support for DirectDraw video display, and so the workaround was to disable it in Options and fall back to GDI.

Surprisingly, there are still display compatibility issues with VirtualDub running under Wine.

VirtualDub doesn't do anything too fancy in its default DirectDraw mode. It creates a single off-screen surface in default memory (usually video, can be system) and then calls Blt() to draw it onto the primary surface through a clipper. I use the older DirectDraw 3 API, because that was the highest version supported by Windows NT 4.0 and there isn't anything in DirectDraw 6 or 7 that I need. There was a problem with Windows Vista where the panes sometimes wouldn't update (mixed DX and GDI in the same window no longer allowed, first I'd ever heard of it), but I fixed that by splitting off the display minidrivers to a child window, at the cost of flickering at mode switches. As far as I know, everything works now, both in XP and Vista. But it doesn't work in Wine, at least not so well.

In Wine 1.0, the current stable release, the old screen blanking problem is still around. I didn't have a debugging setup that I could use to check the Wine code -- realistically, I shouldn't even have been installing and running Wine on a running MythTV box -- but as best as I could tell from behavior and the Wine source, here's what's going on:

Note that VirtualDub is blitting with both a destination subrect and a clipper attached, so the entire screen should definitely not be getting overwritten in this way.

In the current alpha release -- I think it was Wine-1.1.2 that I tested -- the situation is a bit better, as the video panes no longer blank the screen. There appear to be two changes possibly involved, although I'm not sure which are in the mainline:

The clipping situation is still pretty bad in the current version, as blits that are partially outside of the primary surface still fail, even if a clipper is attached. It seems that the top-level Blt() function immediately rejects any blits where the destination rect overlaps the right or bottom boundary, clipper or not. The underlying blit code in wined3d seems to be able to handle clipping to some extent, but unfortunately it lacks the ability to clip a stretchblt. It's a relatively minor issue, but it looks like the fractional stepping on the stretchblt case is also off by half a pixel.

How hard would it be to fix? I'm not sure. It's easy to be an armchair programmer, and I've never worked on Wine before. The clip and stretch problems, I'd say, shouldn't be too bad. As far as I know, the real DirectDraw only clips blits to pixel precision on both destination and source, which is easier but leads to seam artifacts. There is a path that does clip properly, but it's only used by Direct3D Present() calls. A more worrisome problem is that the old Microsoft DirectDraw Test (ddtest.exe) program doesn't work at all under Wine, as it displays garbage in its status panes and crashes out as soon as you try to create the primary surface. I suspect the reason might be that the DX3 interfaces aren't implemented properly and are expecting and returning DX7 structures, which would require a much bigger fix than just a few tweaks to the clipping and scaling routines.

So, if you're wondering why VirtualDub has drawing problems on Wine... there's your answer.


This blog was originally open for comments when this entry was first posted, but was later closed and then removed due to spam and after a migration away from the original blog software. Unfortunately, it would have been a lot of work to reformat the comments to republish them. The author thanks everyone who posted comments and added to the discussion.