Hi
I've been profiling various emWin parts of some projects, trying to work out what core function is taking what time. I appear to have a bit of a bottleneck with text and I'm wondering if anyone, including Segger, has any comments on the time taken to draw a character?
I am finding that it is generally taking around 0.2ms/character on a 168MHz STM32F4 (GUICC_M565 -> GUIDRV_LIN_16). Of course, it varies with font,text mode, etc but it is always centreing around 0.2ms/char. I have checked with all my non-GUI tasks disabled and with a single hWin (in addition to HWIN_BKWIN). It is only marginally affected by my config of WM_SetCreateFlags(WM_CF_MEMDEV), WM_MULTIBUF_Enable(1), GUI_EnableAlpha(1). It is only marginally affected by BkColor being solid or transparent, and only marginally affected by the text mode (NORMAL or TRANS).
0.2ms/char is around 80k ops per character. Given the font is around 150px area this is 500 ops per char pixel. Given I am using GUI_TM_HASTRANS and the font-painter will be skipping the vast majority of pixels when painting then it may be 10kops per painted pixel. This seems rather a lot.
My wonders are:
Thanks
Mark
Code:
My WMX is a wrapper for each hWin object. It catches the main WM _cb and paints the background including background image (if enabled). I use it as my base window class which I inherit down from, adding settings, events handlers, etc. If I do not paint the text in this example the timing for my background tasks is around 10ms. De-commenting the FILLRECT adds about 10ms to the paint() time. My _cb handler includes a trap every 20 paints to I can see paint times. Window refresh is set at 500ms.
Display All
I've been profiling various emWin parts of some projects, trying to work out what core function is taking what time. I appear to have a bit of a bottleneck with text and I'm wondering if anyone, including Segger, has any comments on the time taken to draw a character?
I am finding that it is generally taking around 0.2ms/character on a 168MHz STM32F4 (GUICC_M565 -> GUIDRV_LIN_16). Of course, it varies with font,text mode, etc but it is always centreing around 0.2ms/char. I have checked with all my non-GUI tasks disabled and with a single hWin (in addition to HWIN_BKWIN). It is only marginally affected by my config of WM_SetCreateFlags(WM_CF_MEMDEV), WM_MULTIBUF_Enable(1), GUI_EnableAlpha(1). It is only marginally affected by BkColor being solid or transparent, and only marginally affected by the text mode (NORMAL or TRANS).
0.2ms/char is around 80k ops per character. Given the font is around 150px area this is 500 ops per char pixel. Given I am using GUI_TM_HASTRANS and the font-painter will be skipping the vast majority of pixels when painting then it may be 10kops per painted pixel. This seems rather a lot.
My wonders are:
- is if the middleware included with Keil MDK is, in some way, throttled/de-optimized?
- are others getting better draw times? If so, I'll go have a further prod at my code.
- is this just what it is?
Thanks
Mark
Code:
My WMX is a wrapper for each hWin object. It catches the main WM _cb and paints the background including background image (if enabled). I use it as my base window class which I inherit down from, adding settings, events handlers, etc. If I do not paint the text in this example the timing for my background tasks is around 10ms. De-commenting the FILLRECT adds about 10ms to the paint() time. My _cb handler includes a trap every 20 paints to I can see paint times. Window refresh is set at 500ms.
C Source Code
- static void _paint(WMX* this) {
- GUI_RECT rect = WMX_GetRect(this);
- uint8_t rpt;
- if (!this) return;
- GUI_SetFont(&GUI_Font20B_1);
- GUI_SetColor(GUI_WHITE);
- GUI_SetBkColor(GUI_BLUE);
- GUI_SetTextMode(GUI_TM_TRANS);
- rpt = 50;
- while(rpt--){
- GUI_DispStringAt("hello", 400, 240);
- //GUI_FillRect(10, 10, 70, 70);
- }
- }
- static void _cb(WM_MESSAGE * pMsg) {
- GUI_KEY_STATE* pKeyState;
- WMX_X_HELLOWORLD* this;
- WM_GetUserData(pMsg->hWin, &this, sizeof(WMX*));
- switch (pMsg->MsgId) {
- case WM_POST_PAINT:
- if (WMXPrivate(this)->Profiling.iProfile == 0) {
- WMXPrivate(this)->Profiling.iProfile = 0;
- }
- break;
- case WM_PAINT:
- _paint((WMX*)this);
- break;
- }
- }