problem with silly CreateBitmap call

Reece Dunn msclrhd at googlemail.com
Wed Sep 12 14:23:22 CDT 2007


On 12/09/2007, Rolf Kalbermatter <r.kalbermatter at hccnet.nl> wrote:
> denis.bonnenfant at diderot.org wrote:
>
> >I experienced exactly the same problem with Solidworks 2007
> >http://appdb.winehq.org/appview.php?iVersionId=8983
> >with occasionnal big slowdowns caused by a 10000x10000x24bpp bitmap
> >allocation.
> >In this case it doesn't crashed, but allocate more than 1GB of swap.
> >
> >I filed a bug :
> >
> >http://bugs.winehq.org/show_bug.cgi?id=9561
>
> Well in the log at around line 3000 and 3072 I see the problem.
> A 10000 * 10000 24 bit bitmap seems quite a little excessive to me
> and it creates two of them. And it creates a third bitmap with a
> different y dimension but the rest is the same.
> Could be really an unitialized variable somehow. Now to find out
> who calls CreateCompatibleBitmap at that position! Could be the
> app itself so the question would be where did it get those parameters
> from. Other debug channels inside Wine could be +bitblt, +cursor,
> +icon, or one of the comdlg controls such as +imagelist.
>
> Several calls to
>
> trace:x11drv:X11DRV_SetWindowPos win 0x30274 window (0,0)-(10000,14)
> client (0,0)-(10000,14) style 5001000b
>
> right after that look also suspicious.

Hmm... because the size of the window on the X axis, I would suspect
the bug lies in one of the API that is used by flicker-free drawing
logic when rendering to a DC. The idiom is something like:

    void FlickerFree(HWND window, HDC dc)
    {
        RECT client;
        HDC memoryDC;
        HBITMAP memoryBuffer, oldBitmap;

        GetClientRect(window, &client);

        /* Create a DC that has the same properties as the one we are
drawing to... */
        memoryDC = CreateCompatibleDC(dc);

        /* Create a bitmap to contain the image data of what is being
drawn... */
        memoryBuffer = CreateCompatibleBitmap(dc,
client.right-client.left, client.bottom-client.top);
        oldBitmap = SelectObject(memoryDC, memoryBuffer);

        /* Do the drawing operations that may cause a flicker. */

        /* Update the actual DC with the content of what we have just
drawn... */
        BitBlt(dc, client.left, client.top, client.right-client.left,
client.bottom-client.top,
                 memoryDC, client.left, client.top, SRCCOPY);

        SelectObject(memoryDC, oldBitmap);
        DeleteObject(memoryBuffer);
        DeleteDC(memoryDC);
    }

> trace:x11drv:X11DRV_CreateBitmap (0xed4) 2147483646x2147483646
> 1 bpp

If the problem is indeed flicker free logic as above, this looks as
though it may be CW_DEFAULT x CW_DEFAULT, where CW_DEFAULT is a
constant passed to CreateWindow (see the MSDN documentation) that
tells Windows to pick a default width and/or height.

This leads me to suspect that a WM_PAINT message is processed before
WM_SIZE or related messages, or (least likely) CW_DEFAULT is not
handled properly.

- Reece



More information about the wine-devel mailing list