Poor performance while drawing text input fields and buttons

Open forum for end-user questions about Wine. Before asking questions, check out the Wiki as a first step.
Forum Rules
Locked
AmoxT
Level 1
Level 1
Posts: 7
Joined: Wed Jun 16, 2010 4:54 am

Poor performance while drawing text input fields and buttons

Post by AmoxT »

Poor performance while drawing text input fields and buttons with GDI commands using winex11.drv

Hello,
I have noticed that an application compiled under wnidows that makes extensive use of GDI
drawing commands, even when it is run in the latest 1.2rc3 vesion of wine, shows a slow down
while drawing a window with a lot of buttons and text input fields.

I have tried to do verbose debug of the application with the command"WINEDEBUG=+relay wine App.exe"
and the result was that I saw a huge amount of ntdll.RtlEnterCriticalSection() and
ntdll.RtlLeaveCriticalSection(). These calls were made while drawing the graphical elements, so I
have commented out the following rows in the file winex11.drv/x11drv_main.c:

void CDECL wine_tsx11_lock(void)
{
// EnterCriticalSection( &X11DRV_CritSection );
}

void CDECL wine_tsx11_unlock(void)
{
// LeaveCriticalSection( &X11DRV_CritSection );
}


After this I have compiled and installed wine 1.2rc3 and I am going to test the drawing
performance of App.exe with this modified version of wine. Is this a good solution or maybe there
are other solutions that I should try in order to speed-up the drawing of buttons and text input
fields with winex11.drv?

Thanks in advance,

Amox
arquitecto
Level 1
Level 1
Posts: 6
Joined: Wed Jun 16, 2010 4:13 am

Post by arquitecto »

I think this is the same problem that is happening with me.
http://forum.winehq.org/viewtopic.php?t=8697
My windows app makes use of wingdi wich is the same that is causing troubles with you.
AmoxT
Level 1
Level 1
Posts: 7
Joined: Wed Jun 16, 2010 4:54 am

no luck, gdi32.SetBkColor and SetTextColor

Post by AmoxT »

Well,

actually the removal of enter/leave for the critical sections was not of any use... I achieved no speedup.

The drawing of the buttons and of the text input field seems to be slow because of the following calls:

0009:Call gdi32.SetBkColor(00000250,00c8d0d4) ret=004327f3
0009:Ret gdi32.SetBkColor() retval=00ffffff ret=004327f3
0009:Call gdi32.SetTextColor(00000250,00000000) ret=004327d9
0009:Ret gdi32.SetTextColor() retval=00000000 ret=004327d9
0009:Call gdi32.SetBkColor(00000250,00ffffff) ret=004327f3
0009:Ret gdi32.SetBkColor() retval=00ffffff ret=004327f3
0009:Call gdi32.SetTextColor(00000250,00000000) ret=004327d9
0009:Ret gdi32.SetTextColor() retval=00000000 ret=004327d9
0009:Call gdi32.SetBkColor(00000250,00ffffff) ret=004327f3
0009:Ret gdi32.SetBkColor() retval=00ffffff ret=004327f3

Is it possible to reduce in any way the time that each of these spend?

Thanks,

Amox
AmoxT
Level 1
Level 1
Posts: 7
Joined: Wed Jun 16, 2010 4:54 am

real problem in StretchBlt

Post by AmoxT »

Well, actually the problem was in the file dlls/winex11.drv/bitblt.c in the function

Code: Select all

/***********************************************************************
 *           X11DRV_StretchBlt
 */
BOOL CDECL X11DRV_StretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst, INT widthDst, INT heightDst,
                              X11DRV_PDEVICE *physDevSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc,
                              DWORD rop )
because after issuing the command
WINEDEBUG=+bitblt wine ./App.exe
there were a lot of

trace:bitblt:X11DRV_StretchBlt rectdst=25,1 1x13 orgdst=10,10 visdst=(25,1)-(26,14)
trace:bitblt:X11DRV_StretchBlt rectsrc=0,0 1x13 orgsrc=0,0 vissrc=(0,0)-(1,13)
trace:bitblt:BitBlt hdcSrc=0x3ed0 0,0 -> hdcDest=0x1ec8 25,1 1x13 rop=660046
trace:bitblt:X11DRV_StretchBlt rectdst=25,1 1x13 orgdst=10,10 visdst=(25,1)-(26,14)
trace:bitblt:X11DRV_StretchBlt rectsrc=0,0 1x13 orgsrc=0,0 vissrc=(0,0)-(1,13)

that were synchronized with the slow display of the buttons and text input fields.

Can anyone provivde me an optimized version of this function?
Thanks very much

Amox
Thunderbird
Level 5
Level 5
Posts: 336
Joined: Mon Nov 24, 2008 8:10 am

Post by Thunderbird »

These days our StretchRect and some other calls are accelerated by XRender. If you have good display drivers (e.g. Nvidia, and perhaps in case of ATI catalyst 10.6 and perhaps recent Intel as well) then XRender is hardware accelerated and thus StretchRect as well.

Note the frequency of calls doesn't say anything about performance. If something is slow you would have to profile it to find the real cause. If the app is doing a lot of drawing to DIBs then X11 might be the issue (on Windows DIBs are rendered to in software using a DIB engine but in Wine we cheat and offload everything to X11 which can cause performance issues in some cases).
AmoxT
Level 1
Level 1
Posts: 7
Joined: Wed Jun 16, 2010 4:54 am

buttons are windows

Post by AmoxT »

Hello,

I discovered that as it should be the drawing of buttons and text input fields are related to calls like:

Code: Select all

dlls/user32/uitools.c: BOOL WINAPI DrawEdge( HDC hdc, LPRECT rc, UINT edge, UINT flags )

Code: Select all

dlls/user32/button.c: LRESULT ButtonWndProc_common(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL unicode )
and CreateWindowEx functions, since buttons are windows that receive also messages, so how can I improve the performance of drawing these elements?

Thanks
Amox
AmoxT
Level 1
Level 1
Posts: 7
Joined: Wed Jun 16, 2010 4:54 am

DIBEngine and gdi32/user32 controls drawing loop performance

Post by AmoxT »

Hello,
since I had a poor performance in drawing many buttons and text input fields at the same time into a window with wine, I applied the DIBEngine patch (http://wiki.winehq.org/DIBEngine) that is available for wine 1.1.44 (http://bugs.winehq.org/attachment.cgi?id=27879) to the 1.1.44 version of wine and started my application program that needs to draw many button and text input fields in a single window with the enviroment variable "WINEDIB=ON wine ./App.exe".
Now that the DIBEngine patch is applied a little speedup in the drawing of the buttons and the text input fields is shown, but now the problem is that they are still drawn in blocks of a subset of the total number and then wine waits a little bit, then it draws another block of text input fields and buttons and then wine still waits, then it draws, and so on. The result is that my App.exe application window that is full of buttons and text input fields is drawn in subsequent times, and groups of buttons and input fields are drawn in blocks with a delay between the drawing of a group of controls and the others.
The fact that not all the controls are drawn at a time but in more times is frustrating, since the CPU is a core2duo, and I think that it is powerful enough to draw all of the controls in the window at a time, specially with the DIBEngine patch applied and the DIBEngine activated. So I thought that the problem could be in the main event loop that manages the App.exe application window, and in particular the problem could be that the loop yields the drawing of the controls after a certain number of controls have been drawn in order to avoid CPU high load and then the loop starts again to draw other controls after a while and then it stops and yields and waits again, and so on.
Where can I modify such a behaviour? In particular my App.exe program use many gdi32 drawing commands for drawing buttons and text input fields, so the files dlls/user32/button.c and dlls/user32/edit.c are involved. I think that the dlls/user32/winproc.c file, where the

Code: Select all

LRESULT WINAPI EditWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    return wow_handlers.edit_proc( hwnd, msg, wParam, lParam, FALSE );
}
function is defined is the file where I should do some changes; this function calls

Code: Select all

LRESULT EditWndProc_common( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode )
that is implemented in the dlls/user32/edit.c file, but the fact is that in the EditWndProc_common function there are many cases like this one that manages the various edit messages and window messages sent

Code: Select all

	switch (msg) {
	case EM_GETSEL:
		result = EDIT_EM_GetSel(es, (PUINT)wParam, (PUINT)lParam);
		break;
        ....
and I don't know how to modify the fact that the main loop of the window should handle more messages in order to draw all of the controls at a time and that it should not yield for waiting and then starting drawing again after some time.

What can I do?

Thanks in advance,

AmoxT
Locked