cancel
Showing results for 
Search instead for 
Did you mean: 

How to use off screen rendering of a textarea in a ARGB8888 bitmap

PJEN
Associate III

Working on a STM32H7B3I-DK with a LCD16 (565) frame buffer. I would like to render a text field in an offscreen bitmap to be able to show it in a ScalableImage. For this I will use the drawToDynamicBitmap function. It works if the dynamic bitmap is created as Bitmap::RGB565

but then the text is drawn on a solid background.

If I want a transparent background I need to create the dynamic bitmap with ARGB8888. After some search and tries I found that I had to register a LCD32bpp class and set it as Auxiliary LCD in the hal. The first problem is that the 32bits pixels are not handled by the STM32DMA.cpp code provided (only RGB565 and RGB888 are supported). After some tweak in the SetupDataCopy(blitOp) function in this source file, I managed to have the DMA2D to write correctly in the dynamic bitmap with 32 bits pixels.... but this only works when I run the code in the debugger with a breakpoint in the SetupDataCopy. If I let it run full speed I only get the first 3 letters properly rendered (using 32 bits pixels) but the remaining letters are rendered with 16 bits pixels (the format used for the framebuffer LCD16).

The problem comes from the line 'uint8_t bitDepth = HAL::lcd().bitDepth();' in the beginning of the SetupDataCopy that should provide the LCD class to be used for the blit operation. When calling drawToDynamicBitmap, the bitDepth is reported correctly as 32 for the first 3 calls to SetupDataCopy but after that the bitDepth is 16 !! It looks like the variable useAuxiliaryLCD was changed at a wrong time

'

1 REPLY 1
PJEN
Associate III

To be complete, the changes in STM32DMA.cpp for the H7 to support 32 bits pixels is to modify all lines where you find

(bitDepth == 16) ? CM_RGB565 : CM_RGB888

to

(bitDepth==32) ? CM_ARGB8888 : (bitDepth == 16) ? CM_RGB565 : CM_RGB88

and also ..

(bitDepth == 16) ? DMA2D_RGB565 : DMA2D_RGB888

to

(bitDepth==32) ? DMA2D_ARGB8888 : (bitDepth == 16) ? DMA2D_RGB565 : DMA2D_RGB888

And with the following 'quick and dirty' hack, the rendering is correct in ARGB8888 for the whole text 😉

I put a global variable like this in the first lines of STM32DMA.cpp

bool bForce32 = false;

I test this variable in the beginning of SetupDataCopy function to force bitDepth=32 when this variable is true (whatever the bitDepth reported by the HAL::lcd().bitDepth(); call).

void STM32H7DMA::setupDataCopy(const BlitOp& blitOp)
{
  uint32_t dma2dTransferMode = DMA2D_M2M_BLEND;
  uint32_t dma2dColorMode = 0;
 
  bool blendingImage = (blitOp.operation == BLIT_OP_COPY_ARGB8888
             || blitOp.operation == BLIT_OP_COPY_ARGB8888_WITH_ALPHA
             || blitOp.operation == BLIT_OP_COPY_WITH_ALPHA);
 
  bool blendingText = (blitOp.operation == BLIT_OP_COPY_A4
             || blitOp.operation == BLIT_OP_COPY_A8);
 
  uint8_t bitDepth = HAL::lcd().bitDepth();
  if (bForce32)
  {
  	bitDepth = 32;
  }
 
  switch (blitOp.operation)
       ........
 
 
 

Then when rendering my text offscreen I call :

bForce32=true;

textArea.drawToDynamicBitmap(bmpid);

bForce32=false;