§ ¶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:
- In the default configuration and on that system, Wine needs to emulate the blit.
- Like in the Microsoft HEL (hardware emulation layer), the blit is emulated by locking both the primary and the off-screen buffer, and copying the surface data over using the CPU.
- X doesn't support locking the primary buffer, so that must be emulated by maintaining a backing store and updating the screen from it.
- The other programs don't know about the backing store, so the backing store for the primary is black everywhere except for where the blit happened.
- The emulated Blt() routine locks the entire primary surface, thus causing the whole screen to be updated -- and turn black everywhere except for the video panes.
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:
- CodeWeavers had a hack to better emulate locking the primary by blitting from the screen into the backing store. That sort of works, I guess, but boy is it slooooooowwww, and it's also extraneous if the data is going to be overwritten anyway.
- Blt() was changed to lock only the pertinent subrect of the destination. I'm guessing this was the change that made the real difference.
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.
Would be interesting for the Wine Team to have a look too, after all Wine is working almost perfect here (for my use cases), since years, and more win apps are working with every some release too :)
mark - 06 01 09 - 08:31
Just a question, did/do you ever consider implementing an SDL mode?
Yogarine (link) - 06 01 09 - 08:46
avidemux is a nice replacement for virtualdub.
at least the last version of virtualdub I actually used, which was some long years ago.
bart9h - 06 01 09 - 12:03
SDL is kinda awkward to use when you only want to use it for a single window/HWND in your program. You have to pass the handle around in an environment variable before making the SDL calls.
Darkstar - 06 01 09 - 18:06
Current versions of Wine do look pretty nice -- in fact, they've got most of the UI metrics tuned well enough that it's a pretty close visual match. I haven't really tried any other apps, but I can believe that a lot of them are very usable with what I saw of 1.0.
That's nice. I don't care and it's off-topic.
SDL is an application layer that rides on top of the OS APIs, so it wouldn't buy me anything. DirectDraw through SDL wouldn't be any more compatible than using DirectDraw directly. In portable code, I wouldn't choose a video display method first without looking at what integration problems might arise with the widget toolkit used.
I actually do have a display minidriver layer in place, so I could hook it up if I were bored. So far, though, I've avoided creating a display plugin API for lack of interest.
Phaeron - 07 01 09 - 01:29
Bart9h's comment is, obviously, off-topic - but if you consider Yogarine's comment, it raises an interesting question: if Virtualdub added support for SDL, how hard would it be to have a native Linux version of Virtualdub? OK, the controls alone would be a problem, the codec issue another headache-inducing work, and a bunch of code behind the UI would probably need some modifications. I don't even want to think about what would be required to support V4L and/or V4L2 for video capture (as far as I know, SDL handles sound, 2D and 3D graphics, but not video/stream handling). Finally, a Linux port would probably be successful only with a plain C/C++ version as fallback, instead of the current highly optimized but platform specific assembly code. That would probably lead to a complete rewrite, making Virtualdub look like Avidemux in the end.
Or, Virtualdub adds support for SDL, a Wine SDL layer mapping to a Linux SDL install is made (akin to the OpenGL layer in wine), and all is well with the world.
Still, both solutions would require quite a lot of work - when there's already Avidemux on UNIX systems. Would it be an interesting engineering achievement? Yes. Would it be useful? Not really.
Mitch 74 (link) - 07 01 09 - 05:33
I think the best option is to let the Wine developers fix their bug, or bring some help at it, as it may fix problems with another apps as well.
I don't think that a bug in Wine justifies a big change in VirtualDub's display code... If they got to modify Wine to somehow map Windows SDL to Linux libraries, they may better use their time to fix the DirectX emulation bug.
sarkw - 07 01 09 - 07:04
I agree. I am pretty satisfied how well VD works under Wine. One can use it productively to work with videos. Any minor things left, should not be worked aroun in VD but if someone has a nice idea how to fix it, he should submit it the the wine bug database and help wine. Thus other allications benefit too.
DJT-Rex - 07 01 09 - 11:16
the discussion (and more technical details) on the Wine bug can be found at http://bugs.winehq.org/show_bug.cgi?id=1..
Avery, it may be worth it to add this bug reference to your post, as it is quite enlightening - your comments included.
Mitch 74 (link) - 08 01 09 - 06:01
I didn't want to link to the Wine bug because the original specific issue (screen blanking) doesn't affect VirtualDub anymore, and I didn't want to slashdot the bugzilla entry. The Wine guys are already aware of the issues I've raised.
Phaeron - 09 01 09 - 00:16
Yeah that was more or less the issue wanted to raise. ;-) Thanks for doing it for me.
However I was thinking about how possible it would be to make VirtualDub portable not because we need a VirtualDub for Linux per se, but rather because I read so much posts from Phaeron on this blog complaining about MS Visual Studio & co that I thought it would really be nice if he focused all his programming skills and experience towards free & open source projects like Eclipse/CDT/GCC/GTK++ which are developed by communities that actually care when someone complains (or where you have the possibility to send patches).
Everytime I read a post from you complaining about VS I just thinkg, "why don't you just start developing on Linux with GCC?" Linux is a platform that embraces programmers, that loves programmers, etc, etc... So my question is: did you ever try developing on a modern distro? If yes, what is it that made you return to Windows? If not, is it because your job requires you to work mainly on Windows projects, or just because you can't be bothered?
Yogarine (link) - 09 01 09 - 11:38
Please feel free to try your hand at Wine programming, Phaeron. We're always looking for new contributors, and you seem to have a handle on what's going on here. I think you'll find that hacking Wine is just freakishly hard. Frankly, most C programmers just flat out aren't good enough to do it. But the folks who *do* have the chops to hack Wine seem to find the ridiculous degree of difficulty sort of intriguing. ;-)
Jon Parshall (link) - 09 01 09 - 12:20
As much as I have issue with Visual Studio, I'm not at all fond of GCC and its customary development environments. You might say that one of the reasons I complain about Visual Studio is because I don't want to have to go to GCC!
If I had had Wine built from source, I probably would have just hacked on it and seen if I could have fixed the problem. Unfortunately, it was a system that wasn't set up for development and I just pulled binaries via the package manager. Like I said, I just abused a MythTV box for the evening. I already had someone ask about test cases, which I can do since I can develop them on Windows, but I'm not really set up for Linux development simply because I don't maintain a Linux box. My computing life is in Windows, and I'm afraid that's all I really have time for.
I am curious as to why DDTest blows up, though....
Phaeron - 10 01 09 - 02:08
would you have any idea of launching for Mac OS X?
Gopal Balaji (link) - 11 01 09 - 22:54
To get a cross platform UI for VirtualDub would require two steps.
1) Designing it
2) Hooking it up to the code.
Already I had designed the main window and the menu items (as accurately as I could with screenshots, but I think I still made mistakes in the design) and buttons with scroll bar. I don't really want to do the dialogs until I can actually "hook up" the code to the main window UI code, which I'm trying to figure out.
Pharaoh Atem (link) - 03 02 09 - 04:31
And in case anyone was wondering, the UI was designed with QT Designer (Qt 4.4.3-msvc)
Pharaoh Atem (link) - 03 02 09 - 04:32