cancel
Showing results for 
Search instead for 
Did you mean: 

Does TextureMapper support dynamic bitmaps?

Klemens_Pleiner_STE
Associate III

I'm using a texture mapper to rotate an arrow inside a circle. That works perfectly well as long as the arrow is included as image asset and this image is directly set as image in the texture mapper.

As soon as I remove the arrow from the assets and place it on the SD card to have it dynamically loaded as dynamic bitmap, the following happens:

  • The dynamic bitmap is displayed without any problems by an Image widget.
  • The dynamic bitmap is NOT displayed by the TextureMapper widget.

This happens for RGB, ARGB as well as L8 images (it does not matter if alpha is included in the clut or not). Dynamic bitmaps do not seem to be supported by TextureMapper.

Is this a bug?

Is there a plan in which version the TouchGFX TextureMapper supports dynamic bitmaps?

Kind regards,

Klemens Pleiner

5 REPLIES 5
Martin KJELDSEN
Chief III

A Dynamic Bitmap is also just a bitmap, so it should work. Is TextureMapper feature enabled for the format you want? In "Config" tab of the designer.

Hello Martin,

thanks for the answer!

I've switched to TouchGFX 4.15 and the problem still persists. In the TouchGFX Designer on Config => Framework Features ALL checkboxes are checked. So the TextureMapper should be able to use dynamic L8ARGB images. But obviously it doesn't.

It still works, as long as the image is included as image asset :(

Maybe the problem is triggered by the place where my dynamic bitmap cache is located:

I'm using the STM32L4R9I Discovery board and I've created the dynamic bitmap cache in the PSRAM of this board. Maybe that's the problem?

(I was unable to put the display buffer into the PSRAM. Thus I have the display buffer still in the internal RAM, but the dynamic bitmap cache must be located in the PSRAM as I don't have plenty of internal RAM left.)

Can you show me a screenshot of what it looks like? Your application wouldn't happen to be rotated, would it?

OK, the zip archive attached to this reply contains the following files:

  • MissingWhiteArrow.bmp: Screenshot directly recorded from the image buffer in the internal RAM written to an SD card inserted in to the disco board as BMP file.
  • ExpectedWhiteArrow.png: The white arrow should be below the "rainbow" on top of the screen. It should arc around below the rainbow from blue to red.
  • white_arrow.png: If I use this file as image asset (it does NOT matter if it's encoded as ARGB888 or L8_ARGB888) the TextureMapper draws the white arrow correctly.
  • white_arrow.l8argb: I converted the white_arrow.png to it's l8argb representation myself (with a tool written by myself -- maybe that's erroneous, too?). The first two uint16_t values contain width and height (see code snippet below).
    • When I load this file from the SD card as dynamic bitmap and display it using an image widget, the white arrow is displayed correctly.
    • But when I use the same BitmapId, that displays the arrow on the same screen at the same time, for the TextureMapper, nothing is displayed by the TextureMapper.

Here are some code snippets:

  • This is how I load the l8argb file (using Bitmap::BitmapFormat::L8 as bitmapFormat and Bitmap::ClutFormat::CLUT_FORMAT_L8_ARGB8888 as value for clutFormat):
// I've removed all the error treatment to have it shorter:
BitmapId BitmapLoader::load(const TCHAR* path, Bitmap::BitmapFormat bitmapFormat, Bitmap::ClutFormat clutFormat)
{
  BitmapId result = BITMAP_INVALID;
  uint8_t bytes[2];
  UINT bytesRead;
  FRESULT fResult;
  uint16_t width, height;
  
  fResult = f_open(&file, path, FA_OPEN_EXISTING | FA_READ);
  fResult = f_read(&file, bytes, 2, &bytesRead);
  width = bytes[0] + ((uint16_t)(bytes[1]) << 8);
  fResult = f_read(&file, bytes, 2, &bytesRead);
  height = bytes[0] + ((uint16_t)(bytes[1]) << 8);
  
  result = Bitmap::dynamicBitmapCreate(width, height, bitmapFormat, clutFormat);
  fResult = f_read(&file, Bitmap::dynamicBitmapGetAddress(result), f_size(&file) - 4, &bytesRead);
  f_close(&file);
  
  return result;
}
  • The result of loading the image is stored in bitmapIdwhite_arrow. In the constructur of my screen I load the image and then I pass a Bitmap to the TextureMapper ar00BpmArrow.
ar00BpmArrow.setBitmap(Bitmap(bitmapIdwhite_arrow));
  • The rotation is done later on in handleTickEvent of the screen:
  float bpmAngle = 2.10 * bpm / maxBpm - 1.05;
  ar00BpmArrow.updateAngles(0, 0, bpmAngle);
  ar00BpmArrow.invalidate();

What exactly do you mean with "rotated application"?

The display orientation in TouchGFX Designer => Config => Display is set to landscape, but the display is square.

Do you need anything else?

Thank you very much for your interest & help!

Hi again!

In the meantime we moved the project from the disco board to our "real" hardware where we have much more PSRAM which is also much faster. But the problem still persists:

  • The TextureMapper is NOT able to draw white_arrow.l8argb when this bitmap is loaded as dynamic bitmap and the dynamic bitmap cache is located in the PSRAM.
  • The TextureMapper draws white_arrow.png without any problems when it is stored in the internal flash as L8_ARGB8888. (We do not have any OctoSPI or other storages on our hardware. So I only can store it in the internal flash.)

Interesting is the following: I use TextureMappers in other screens to rotate images loaded as dynamic bitmap to the dynamic bitmap cache (located in the PSRAM). Whenever those images are larger (greater width and greater height compared to white_arrow.png) everything works as expected.

So my workaround is to store this single image in the internal flash.