57 views
in GUI Development by

Good morning,

I have the following issue with memory management.

I am using an ESP32-WROVER, and I have 4MB of RAM available on the device.
I have currently configured Embedded Wizard GUI as follows:

EW_USE_PSRAM 0x157C00  // 1,408,000 Kbytes as EW_MEMORY_POOL_SIZE

#define EW_USE_IMMEDIATE_GARBAGE_COLLECTION

#define EW_MAX_STRING_CACHE_SIZE           0          
#define EW_MAX_SURFACE_CACHE_SIZE          0          
#define EW_MAX_GLYPH_SURFACE_WIDTH       256          
#define EW_MAX_GLYPH_SURFACE_HEIGHT      256          
#define EW_MAX_ISSUE_TASKS                80 

#define EW_LAZY_LOAD_BITMAPS                              1
#define EW_LAZY_LOAD_BITMAPS_IF_ANIMATED_ONLY             1
#define EW_DISCARD_BITMAPS                                1
#define EW_DISCARD_BITMAPS_IF_ANIMATED_ONLY               1
#define EW_DISCARD_BITMAPS_IF_NOT_USED_IN_CURRENT_UPDATE  0
#define EW_DISCARD_BITMAPS_IF_NOT_USED_IN_RECENT_UPDATES  0
#define EW_CACHE_OFFSCREEN_SURFACES                       0

Everything works perfectly, but the problem arises when I use EwLoadExternBitmap in specific situations. 

The problem in detail:
If I load for example an image of 695 × 480 × 3 = 980 KB, using:

bitmap = EwCreateBitmap( EW_PIXEL_FORMAT_NATIVE, frameSize, 0, 1 );

The operation is successful, the graphics work perfectly, and I can correctly render the image: Even when I implement an image carousel, continuously changing EwLoadExternBitmap, everything works fine.

 

However, the issue occurs when the Device Driver requests the GUI to reload the same page. In this phase I recall the page (pagetoreload for example) with:

this.PresentDialog(pagetoReload, null, null, null, null, null, null, null, null, false);

But when the code reaches:

bitmap = EwCreateBitmap( EW_PIXEL_FORMAT_NATIVE, frameSize, 0, 1 );

There is not enough memory available!! So, I don't understand why!??
Using the function:

EwPrintProfilerStatistic(1);

I can see that the page "pagetoReload" is loaded twice into memory (and so probably the previous bitmap is still stored in the EW_MEMORY_POOL_SIZE). As a result, I run out of RAM, and of course, the call to EwCreateBitmap( EW_PIXEL_FORMAT_NATIVE, frameSize, 0, 1 ) fails.

What I have tried:

  • Using SwitchToDialog instead of PresentDialog However, EwPrintProfilerStatistic(1) still shows two instances of the "pagetoReload" page in RAM, and EwCreateBitmap() fails.
  • Calling DismissDialog before PresentDialog, in this case, the UI crashes.
  • Calling EwReclaimMemory(); before this.PresentDialog: Unfortunately, this did not improve the situation.


I do not understand why the page is duplicated in memory.
Unfortunately, I cannot increase the RAM because I am already at the limit.

Is there anything I can do to free the previous page properly before loading a new one?

Thank you in advance.

1 Answer

0 votes
by

Hello,

first at all the calculation 695 × 480 × 3 = 980 KB is incorrect in case of NATIVE bitmap. Depending on the color format in the target system, the NATIVE bitmap occupies per pixel 4, 2 or 1 byte. See also: Bitmap color format EW_PIXEL_FORMAT_NATIVE variant RGBA8888Bitmap color format EW_PIXEL_FORMAT_NATIVE variant RGBA4444Bitmap color format EW_PIXEL_FORMAT_NATIVE variant LumA44 or Bitmap Color format EW_PIXEL_FORMAT_NATIVE variant Index8 according to the format in your target system.

Furthermore, each regularly created bitmap reserves additional 1-pixel space transparent border. That means internally the bitmap is two pixel wider and higher. Assuming you are working with RGBA8888, then the correct calculation will result in ( 695 + 2 ) × ( 480 + 2 ) × 4 = 1313 KB.

However, the issue occurs when the Device Driver requests the GUI to reload the same page. In this phase I recall the page (pagetoreload for example) with this.PresentDialog(pagetoReload, ... ).

If you perform this code while other instance of the pagetoReload dialog is already presented, then it will have the expected behavior of two dialogs existing at the same time. The already presented and the new dialog will exist simultaneously. If each dialog instance allocates memory for an own bitmap, then two bitmaps occupy memory.

Using SwitchToDialog instead of PresentDialog However, EwPrintProfilerStatistic(1) still shows two instances of the "pagetoReload" page in RAM, and EwCreateBitmap() fails.

SwitchToDialog() presents a new dialog by replacing the preceding dialog. During the transition both dialogs exist. This is necessary for eventual animations, like fading-in/out the dialogs.

Calling DismissDialog before PresentDialog, in this case, the UI crashes.

Without knowing your implementation, difficult to say what exactly happens.

Calling EwReclaimMemory(); before this.PresentDialog: Unfortunately, this did not improve the situation.

Bad idea. Calling EwReclaimMemory() will surely crash the application. The function EwReclaimMemory() may be invoked in the main loop only. See also Platform Package reference: Function EwReclaimMemory().

What can you do?

For me it is still not clear what do you mean with '... when the Device Driver requests the GUI to reload the same page'? Assuming, you want reload the bitmap content, then see Force an Extern Bitmap object to reload its content. You could, for example, react on a System Event sent from Device Interface object and react to this event inside the component displaying the external bitmap. As reaction, the bitmap to reload its content.

If my above assumption is wrong and you in fact want a new dialog to be presented as reaction to the Device Driver request. Then you will need to first dismiss the old dialog displaying the bitmap and then present the new dialog. This is essential to ensure that memory used by the old dialog is freed before the new dialog is presented. One possible approach to achieve that is to use the parameter aComplete in DismissDialog(). In this manner you receive a signal when DismissDialog() finished the operation and you can thereupon present the new dialog. See also Handle the completion of a Dialog transition.

I hope it helps you further.

Best regards

Paul Banach

 

Ask Embedded Wizard

Welcome to the question and answer site for Embedded Wizard users and UI developers.

Ask your question and receive answers from the Embedded Wizard support team or from other members of the community!

Embedded Wizard Website | Privacy Policy | Imprint

...