If DGA is not available, Wine falls back to creating offscreen primary surface and blitting all changes to the screen. It knows which part of the surface might have changed by watching unlock calls.
However, as Jukka Heinonen pointed out in his message posted on 17.10.2001, the update logic in asynchronous mode (when SYNC_UPDATE is not defined, which is the default) is broken: "(...)if more than one lock/unlock pair happens between update thread blits, display might not be updated correctly". Synchronous mode on the other hand, causes applications, which constantly lock and unlock big areas just to change a few pixels, run very slow.
As this bug prevents me from playing "Warlords: Battlecry", I decided to do something about it.
Here are my changes:
- User_add_dirty_rect is now an asynchronous equivalent of User_copy_to_screen. It adds the rectangle to the list of dirty rectangles and signal the update thread that there is some work to do. - update thread calls User_get_dirty_rect to iterate over the list of dirty rectangles - current "naïve" algoritm keeps only one rectangle which is a union of all dirty rectangles, so it tends to redraw too much, but better algoritms may be implemented - removed now unused lastlockrect variable, and the code which updates it
I attached the patch for your reviews, comments, suggestions.
The game is almost playable now, there are remaining issues with DirectMusic (must be run with NODIRECTMUSIC switch or crashes) and windows managers (kwin cannot raise the window, metacity complains that the window attributes do not make sense).