Hi, I'm trying to get Settlers 3 to run on Wine. After fixing some race condition (seems like the thread calling WaitForXXXObject was giving up time-slice too early after the call) it seems that the only problem left is very slow text output. What I could understand from the forum archives is that with no DIB engine, the rendering into a DC causes copying of the bitmap to/from server (is that correct?). I'd like to contribute to the DIB engine if it's possible/needed, so I'd like to ask about a few things. There were some discussion recently about an implementation of DIB engine by Jesse Allen - what is the status of DIB engine? I compiled winedib.drv but ExtTextOut function is missing there and overall there are regressions visible when running Settlers 3 (wrong colors, no text at all). Which docs/urls/sources would you recommend to read to get some quick introduction to the DIB engine? Which particular functions are making current impl slow? Or, in general: where to start? Sorry for any silly questions... Thanks & regards Piotr
-- ----- AlphaNet - najtaniej w sieci! -------- Odnowienia domen w rewelacyjnych cenach! .pl - 65 zl, .com.pl - 50 zl, reg - 20 zl http://www.domeny.alpha.pl --------------------------------------------
On 9/8/07, Skrzynka skrzynka365@konto.pl wrote:
Hi, I'm trying to get Settlers 3 to run on Wine. After fixing some race condition (seems like the thread calling WaitForXXXObject was giving up time-slice too early after the call) it seems that the only problem left is very slow text output. What I could understand from the forum archives is that with no DIB engine, the rendering into a DC causes copying of the bitmap to/from server (is that correct?). I'd like to contribute to the DIB engine if it's possible/needed, so I'd like to ask about a few things. There were some discussion recently about an implementation of DIB engine by Jesse Allen - what is the status of DIB engine? I compiled winedib.drv but ExtTextOut function is missing there and overall there are regressions visible when running Settlers 3 (wrong colors, no text at all). Which docs/urls/sources would you recommend to read to get some quick introduction to the DIB engine? Which particular functions are making current impl slow? Or, in general: where to start? Sorry for any silly questions... Thanks & regards Piotr
Hello,
Yes ExtTextOut will probably need to be implemented, as well as whatever family of functions that might go with it. There might be some cooperation necessary with the display driver here I don't know. You're pretty much on your own right now if you go there, as you'll need to figure out how to do everything.
A simpler project might be to implement the drawing algorithms in graphics.c. It needs to be done, and I do believe I have enough infrastructure here (with some tweaking) to get this stuff done. So I would take a look at things like LineTo, Filling, Circles, etc. The docs for the drawing functions are in dib_*.c.
Stretching needs to be done, as well finish support for RLE compression and proper checking for bitmaps recieved into the dib engine.
A task I will start very soon is forwarding to the display driver. This will probably fix most of the regressions if it indeed works, but it will slow the whatever bitmap operations down that go through the dib engine that just foward back--this is okay for the time being while this stuff gets written.
If you want to start hacking on it, I would very appreciate it. I can commit your patches to my tree and you will receive credit for your work. I hope to get the driver into the tree someday soon, but only when correct forwarding, bitmap support, and blitting is fully supported.
Jesse
Jesse Allen wrote:
On 9/8/07, Skrzynka skrzynka365@konto.pl wrote:
Hi, I'm trying to get Settlers 3 to run on Wine. After fixing some race condition (seems like the thread calling WaitForXXXObject was giving up time-slice too early after the call) it seems that the only problem left is very slow text output. What I could understand from the forum archives is that with no DIB engine, the rendering into a DC causes copying of the bitmap to/from server (is that correct?). I'd like to contribute to the DIB engine if it's possible/needed, so I'd like to ask about a few things. There were some discussion recently about an implementation of DIB engine by Jesse Allen - what is the status of DIB engine? I compiled winedib.drv but ExtTextOut function is missing there and overall there are regressions visible when running Settlers 3 (wrong colors, no text at all). Which docs/urls/sources would you recommend to read to get some quick introduction to the DIB engine? Which particular functions are making current impl slow? Or, in general: where to start? Sorry for any silly questions... Thanks & regards Piotr
Hello,
Yes ExtTextOut will probably need to be implemented, as well as whatever family of functions that might go with it. There might be some cooperation necessary with the display driver here I don't know. You're pretty much on your own right now if you go there, as you'll need to figure out how to do everything.
A simpler project might be to implement the drawing algorithms in graphics.c. It needs to be done, and I do believe I have enough infrastructure here (with some tweaking) to get this stuff done. So I would take a look at things like LineTo, Filling, Circles, etc. The docs for the drawing functions are in dib_*.c.
Stretching needs to be done, as well finish support for RLE compression and proper checking for bitmaps recieved into the dib engine.
A task I will start very soon is forwarding to the display driver. This will probably fix most of the regressions if it indeed works, but it will slow the whatever bitmap operations down that go through the dib engine that just foward back--this is okay for the time being while this stuff gets written.
If you want to start hacking on it, I would very appreciate it. I can commit your patches to my tree and you will receive credit for your work. I hope to get the driver into the tree someday soon, but only when correct forwarding, bitmap support, and blitting is fully supported.
Jesse
-- ----- AlphaNet - najtaniej w sieci! -------- Odnowienia domen w rewelacyjnych cenach! .pl - 65 zl, .com.pl - 50 zl, reg - 20 zl http://www.domeny.alpha.pl
I'll do what I can. However it's far too early to bother about my commits :) I'm trying to compare and understand the control flow of both drivers (winex11 and winedib). At which function in winex11 is copying data to/from server taking place? And in what function/file is the check for winedib driver availability done? Thanks Piotr
-- ----- AlphaNet - najtaniej w sieci! -------- Odnowienia domen w rewelacyjnych cenach! .pl - 65 zl, .com.pl - 50 zl, reg - 20 zl http://www.domeny.alpha.pl --------------------------------------------
On 9/8/07, Skrzynka skrzynka365@konto.pl wrote:
I'll do what I can. However it's far too early to bother about my commits :) I'm trying to compare and understand the control flow of both drivers (winex11 and winedib). At which function in winex11 is copying data to/from server taking place? And in what function/file is the check for winedib driver availability done? Thanks Piotr
Feel free to use this list if you want to ask anything or discuss (it's what it's for). I was calling Settlers 3 a test app, and rightfully so as you have shown you have regressions. As for copying to a from winex11? If you are talking about getting a dib from a ddb, you use GetDIBits. If you are talking about the old needless copying done with winex11 (because graphics are done in the server), well, using the dib engine is going to make it go away, and since we are writing the dib engine from scratch, it doesn't have any of it.
Jesse
Does this mean that the current _painfully_ slow Imperialism II that uses the DIB drawing to draw it's in game maps will work faster? I'm waiting for this functionality and have pledged $20 just in case it can spur on the solution.
Best Regards, Martin Owens
On 08/09/2007, Jesse Allen the3dfxdude@gmail.com wrote:
On 9/8/07, Skrzynka skrzynka365@konto.pl wrote:
I'll do what I can. However it's far too early to bother about my commits :) I'm trying to compare and understand the control flow of both drivers (winex11 and winedib). At which function in winex11 is copying data to/from server taking place? And in what function/file is the check for winedib driver availability done? Thanks Piotr
Feel free to use this list if you want to ask anything or discuss (it's what it's for). I was calling Settlers 3 a test app, and rightfully so as you have shown you have regressions. As for copying to a from winex11? If you are talking about getting a dib from a ddb, you use GetDIBits. If you are talking about the old needless copying done with winex11 (because graphics are done in the server), well, using the dib engine is going to make it go away, and since we are writing the dib engine from scratch, it doesn't have any of it.
Jesse
On 9/8/07, Martin Owens doctormo@gmail.com wrote:
Does this mean that the current _painfully_ slow Imperialism II that uses the DIB drawing to draw it's in game maps will work faster? I'm waiting for this functionality and have pledged $20 just in case it can spur on the solution.
Best Regards, Martin Owens
I don't know, you'll have to try it yourself. It depends on what the app is doing. You can get a checkout of the tree here: http://repo.or.cz/w/wine/dibdrv.git
Beware there are probably visual regressions, but it's speed you're checking here right? :)
Jesse
Jesse Allen wrote:
On 9/8/07, Martin Owens doctormo@gmail.com wrote:
Does this mean that the current _painfully_ slow Imperialism II that uses the DIB drawing to draw it's in game maps will work faster? I'm waiting for this functionality and have pledged $20 just in case it can spur on the solution.
Best Regards, Martin Owens
I don't know, you'll have to try it yourself. It depends on what the app is doing. You can get a checkout of the tree here: http://repo.or.cz/w/wine/dibdrv.git
Beware there are probably visual regressions, but it's speed you're checking here right? :)
Jesse
Hi, as a part of struggle to understand the drivers I played a little with winex11.drv and made some simple optimizations. Actually the changes make 'Settlers 3' playable. On my Duron/900 the delay caused by copying bitmaps is hardly noticable (it's no longer a .5sec lag, now it looks like a frame or two dropped once every few seconds). If anyone wants to give it a try with S3, then there's another problem with races condition on WaitFor..Object/SetEvent/ResetEvent, but that can be overcome by just disabling ResetEvent (simple return STATUS_SUCCESS; at the beginning of NtResetEvent). I'm trying to get some more generic solution to the ResetEvent problem but it seems related to the lack of thread boost after WaitFor(Single|Multiple)Object on Wine (seems like poor design of game code) and is quite difficult in general. As I'm new to Wine/X development, what I'd appreciate the most, is critical comments on the attached patch: is omitting XGetPixel/XSetPixel and reading directly XImage data a correct solution? Am I allowed to use inline assembler in above case? Any other issues? Thanks & regards Piotr Maceluch
-- ----- AlphaNet - najtaniej w sieci! -------- Odnowienia domen w rewelacyjnych cenach! .pl - 65 zl, .com.pl - 50 zl, reg - 20 zl http://www.domeny.alpha.pl --------------------------------------------
From 9d26b16c37a08aaf54f66712563cdcd523c1a95a Mon Sep 17 00:00:00 2001
From: Piotr Maceluch skrzynka365@konto.pl Date: Mon, 10 Sep 2007 22:56:25 +0200 Subject: [PATCH] Optimized copying of 1bit bitmaps to and from XImage data.
The copying operations for copying 1bit bitmap to memory and other way no longer employ XGetPixel/XSetPixel. Instead memory operations are used. They're implemented in asm memcpy which does bit order swapping on the fly (swapping is lookup table based). --- dlls/winex11.drv/dib.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 137 insertions(+), 0 deletions(-)
diff --git a/dlls/winex11.drv/dib.c b/dlls/winex11.drv/dib.c index 00b1f23..0e938b8 100644 --- a/dlls/winex11.drv/dib.c +++ b/dlls/winex11.drv/dib.c @@ -58,6 +58,9 @@ static PVOID dibs_handler;
static int ximageDepthTable[32];
+static BYTE bit_reversal_lookup_table[0x100]; //bit-order-reversed value for every 8bit value +static int bit_reversal_lookup_table_initialized = 0; + /* This structure holds the arguments for DIB_SetImageBits() */ typedef struct { @@ -101,6 +104,9 @@ static INT X11DRV_DIB_Coerce(X_PHYSBITMAP *,INT,BOOL); static INT X11DRV_DIB_Lock(X_PHYSBITMAP *,INT,BOOL); static void X11DRV_DIB_Unlock(X_PHYSBITMAP *,BOOL);
+static void X11DRV_InitBitReversalLookupTable(); +static void X11DRV_MemoryCopyWithBitOrderSwap(void *dest, const void *src, int byteCount); + /* Some of the following helper functions are duplicated in dlls/gdi/dib.c @@ -508,6 +514,30 @@ static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits, width = min(srcwidth, dstwidth);
/* ==== pal 1 dib -> any bmp format ==== */ + if(((bmpImage->bits_per_pixel | bmpImage->depth) == 1) && + (bmpImage->byte_order == bmpImage->bitmap_bit_order)) + { + //optimization for 1to1 copy + int y; + BYTE* bitmapPtr = ((BYTE*)(bmpImage->data)) + (bmpImage->xoffset >> 3) + + ((lines - 1) * bmpImage->bytes_per_line); + const BYTE* dataPtr = srcbits; + + TRACE("1 bit data -> 1 bit bmp, copy: width=%i, lines=%i, image->bpl=%i, dest_bpl=%i\n", + width, lines, bmpImage->bytes_per_line, linebytes); + + X11DRV_InitBitReversalLookupTable(); + + for (y = 0; y != lines; y++) + { + X11DRV_MemoryCopyWithBitOrderSwap(bitmapPtr, dataPtr, (width + 7) >> 3); + + dataPtr += linebytes; + bitmapPtr -= bmpImage->bytes_per_line; + } + } + else + { for (h = lines-1; h >=0; h--) { srcbyte=srcbits; /* FIXME: should avoid putting x<left pixels (minor speed issue) */ @@ -537,6 +567,7 @@ static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits, } srcbits += linebytes; } + } }
/*********************************************************************** @@ -561,6 +592,27 @@ static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits, switch (bmpImage->depth) { case 1: + { + int y; + const BYTE* bitmapPtr = ((BYTE*)(bmpImage->data)) + (bmpImage->xoffset >> 3) + + ((lines - 1) * bmpImage->bytes_per_line); + BYTE* dataPtr = dstbits; + + TRACE("1 bit bmp -> 1 bit data, copy: width=%i, lines=%i, image->bpl=%i, dest_bpl=%i\n", + width, lines, bmpImage->bytes_per_line, linebytes); + + X11DRV_InitBitReversalLookupTable(); + + for (y = 0; y != lines; y++) + { + //used (width + 7) so rounded down will always contain last pixels in line when ((width % 8) != 0) + X11DRV_MemoryCopyWithBitOrderSwap(dataPtr, bitmapPtr, (width + 7) >> 3); + + dataPtr += linebytes; + bitmapPtr -= bmpImage->bytes_per_line; + } + } + break; case 4: if (X11DRV_DIB_CheckMask(bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask) && srccolors) { @@ -4880,3 +4932,88 @@ Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc ) TRACE("Returning Pixmap %ld\n", pixmap); return pixmap; } + + +/** Returns given input byte with bit order reversed. */ +static BYTE X11DRV_ReverseBits(BYTE input) +{ + BYTE output = 0; + int i; + for(i = 0; i != 8; i++) + { + output |= (input & 1); + input >>= 1; + if(i != 7) + { + output <<= 1; + } + } + return output; +} + +/* Initializes bit_reversal_lookup_table with bit-order-reversed values for + * every possible byte value. */ +static void X11DRV_InitBitReversalLookupTable() +{ + int i; + + if(bit_reversal_lookup_table_initialized) + { + //skip if already initialized + return; + } + + for(i = 0; i != 0x100; i++) + { + bit_reversal_lookup_table[i] = X11DRV_ReverseBits((BYTE)i); + } + + bit_reversal_lookup_table_initialized = 1; +} + +/* Copies byteCount bytes from src to dest and changes bit order of copied + * data bytes. + * FIXME: The function doesn't work when declared as inline or static inline. + * */ +static void X11DRV_MemoryCopyWithBitOrderSwap(void *dest, const void *src, int byteCount) +{ + __asm__ __volatile__ ( + "pushl %%ecx\n" + "cld\n" + "xorl %%edx, %%edx\n" + "shr $2, %%ecx\n" + "jz 2f\n" + + "1:\n" + "lodsl\n" + "movb %%al, %%dl\n" + "movb bit_reversal_lookup_table(%%edx),%%al\n" + "movb %%ah, %%dl\n" + "movb bit_reversal_lookup_table(%%edx),%%ah\n" + "bswap %%eax\n" + "movb %%al, %%dl\n" + "movb bit_reversal_lookup_table(%%edx),%%al\n" + "movb %%ah, %%dl\n" + "movb bit_reversal_lookup_table(%%edx),%%ah\n" + "bswap %%eax\n" + + "stosl\n" + "loop 1b\n" + + "2:\n" + "popl %%ecx\n" + "andl $3, %%ecx\n" + "jz 4f\n" + + "3:\n" + "lodsb\n" + "movb %%al, %%dl\n" + "movb bit_reversal_lookup_table(%%edx),%%al\n" + "stosb\n" + "loop 3b\n" + + "4:\n" + : //output + : "S" (src), "D" (dest), "c" (byteCount) //input + : "eax", "edx", "cc" );//cc - condition codes (flags) +}
On 9/10/07, Piotr Maceluch skrzynka365@konto.pl wrote:
As I'm new to Wine/X development, what I'd appreciate the most, is critical comments on the attached patch: is omitting XGetPixel/XSetPixel and reading directly XImage data a correct solution? Am I allowed to use inline assembler in above case? Any other issues? Thanks & regards
Does this problem still appear with the DIB engine? As I don't know winex11, I can't tell you for sure if not using X Get/Set Pixel really matters. However you may be fixing a bug in the process, so you might want to look at bug 4277 and concentrate on that first. Speed is nice, but correctness should come first.
As for the DIB engine, all this shouldn't matter, however, winex11 probably still needs to be able to read and set DIBs, and that means we should fix existing issues like you are having.
Jesse
On 9/8/07, Skrzynka skrzynka365@konto.pl wrote:
I compiled winedib.drv but ExtTextOut function is missing there and overall there are regressions visible when running Settlers 3 (wrong colors, no text at all).
Oh, it would be quite nice if you use this "test app" and document the missing and incorrect functionality. Don't open bug reports, just send the info straight to me. This will give me info on what things are most important for an app like this.
Jesse