MixColors - different behaviour when using _DMA_MixColors or LCD_AA_MixColors16

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • MixColors - different behaviour when using _DMA_MixColors or LCD_AA_MixColors16

      Hi,

      we are using emWin V5.48 for an application running on STM32 microcontroller and windows desktop (as emulator).
      The microcontroller uses a DMA2D controller.
      The problem we are facing is that screenshots taken from the microcontroller are slightly different to screenshots taken from the desktop application.
      They only differ in areas with antialiased text and the color difference is very little.

      As I found out, the difference comes from different behaviour of the function

      C Source Code: GUI__Alpha.c

      1. LCD_COLOR GUI__MixColors(LCD_COLOR Color, LCD_COLOR BkColor, U8 Intens)
      used in desktop mode and

      C Source Code: LCDConf.c

      1. static LCD_COLOR _DMA_MixColors(LCD_COLOR Color, LCD_COLOR BkColor, U8 Intens)
      used on microcontroller.
      Example:
      The function _DrawCharAA4_NoTrans calculates LCD_COLOR _aColor[16]; when drawing a white text on a blue background.The different results can be seen in the attached images.
      Thanks for any help.
      Images
      • aColor_STM.PNG

        19.55 kB, 307×428, viewed 46 times
      • aColor_DESKTOP.PNG

        19.27 kB, 295×427, viewed 48 times

      The post was edited 2 times, last by thni_macio ().

    • In case someone else runs into the same problem, we implemented our own MixColors function used in windows desktop version of our application that generates the same results as the DMA2D controller.
      It is of curse not so nice and short as the default one shipped with emWin, but since performance is not a problem when running on windows desktop for us it is way more important the screenshots are identical.

      I tried to understand why the GUI__MixColors function shipped whith emWin generates different results than my implementation or the DMA2D controller - but to be honest I never really understood how that function works.

      C Source Code

      1. static LCD_COLOR _MixColorsARGB(LCD_COLOR Color, LCD_COLOR BkColor, U8 Intens) {
      2. // Reset alpha channel for input colors if we don't use transparency
      3. #if (GUI_USE_ARGB == 0)
      4. BkColor ^= 0xFF000000;
      5. Color ^= 0xFF000000;
      6. #endif
      7. // Split up foreground color into ARGB parts
      8. // (intensity is only applied to alpha channel)
      9. U32 fgColorA = (((Color & 0xFF000000) >> 24) * Intens) / 255;
      10. U32 fgColorR = ((Color & 0x00FF0000) >> 16);
      11. U32 fgColorG = ((Color & 0x0000FF00) >> 8);
      12. U32 fgColorB = ((Color & 0x000000FF) >> 0);
      13. // Split up background color into ARGB parts
      14. U32 bkColorA = ((BkColor & 0xFF000000) >> 24);
      15. U32 bkColorR = ((BkColor & 0x00FF0000) >> 16);
      16. U32 bkColorG = ((BkColor & 0x0000FF00) >> 8);
      17. U32 bkColorB = ((BkColor & 0x000000FF) >> 0);
      18. // Calculate resulting alpha channel
      19. U32 rColorA = (((255 - fgColorA) * bkColorA) / 255) + fgColorA;
      20. U32 rColorR;
      21. U32 rColorG;
      22. U32 rColorB;
      23. // Calculate RGB channels
      24. if (rColorA > 0) {
      25. rColorR = (((((255 - fgColorA) * bkColorA) / 255) * bkColorR) + (fgColorA * fgColorR)) / rColorA;
      26. rColorG = (((((255 - fgColorA) * bkColorA) / 255) * bkColorG) + (fgColorA * fgColorG)) / rColorA;
      27. rColorB = (((((255 - fgColorA) * bkColorA) / 255) * bkColorB) + (fgColorA * fgColorB)) / rColorA;
      28. } else {
      29. // Special case if rColorA is zero
      30. rColorR = (bkColorR + fgColorR) / 2;
      31. rColorG = (bkColorG + fgColorG) / 2;
      32. rColorB = (bkColorB + fgColorB) / 2;
      33. }
      34. // Calculate resulting mix color by shifting ARGB parts back to position
      35. U32 rColor = (rColorA << 24) + (rColorR << 16) + (rColorG << 8) + (rColorB << 0);
      36. // Reset alpha channel for output color if we don't use transparency
      37. #if (GUI_USE_ARGB == 0)
      38. rColor ^= 0xFF000000;
      39. #endif
      40. return rColor;
      41. }
      Display All