Gpu_mem_xxx_cp() functions

Hi ,I’m using STM32F769-Disco , I want to activate the DMA2D accelerator .
So I need to implement this two functions :
static void my_mem_fill_cb(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, const lv_area_t * dest_area, const lv_area_t * fill_area, lv_color_t color)

static void my_mem_blend_cb(lv_disp_drv_t * disp_drv, lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa).

In DMA2D side I have the function :
HAL_DMA2D_BlendingStart (pointer, srcAdress1, srcAdress2,destAdress, WIDTH, HEIGHT).

I want to know how to put the adresses, width(number of pixels per line )and the height(number of lines) from Gpu_mem_xxx_cp() arguments.

Have a look at the driver for F746. It already uses DMA and the calls should be identical.

Thanks !
But I get an error in mem_fill_cb() function :

lv_color_t * dest_buf_ofs = dest_buf;

Error :
**incompatible types when initializing type ‘lv_color_t *** {aka union *}’ using type ‘lv_color_t {aka union }’ tft.c /stm32f769_discovery_no_os/hal_stm_lvgl/tft line 150 C/C++ Problem

Please show the code. It looks like you must have changed something from my version. I can compile and run that just fine.

I reverified the code and It’s OK… ! Please can you comment this three lines of code :

   dest_buf_ofs += dest_width * fill_area->y1;
   dest_buf_ofs += fill_area->x1;
   lv_coord_t area_w = lv_area_get_width(fill_area); 

Thanks a lot !

I don’t understand. Am I supposed to comment on the code, or comment out those lines?

(pinging @kisvegabor)

There are used to fill the area line by line. Probably DMA2D support to fill the whole area at once but I didn’t have time to immerse in it.

OK thanks.
I’m trying to invoke gpu_mem_blend_cb() function for blending two images or rendering anti-aliased fonts … But always gpu_mem_fill_cb() is invoked not mem_blend().
This is my implementation :

static void my_mem_blend_cb(lv_disp_drv_t *disp_drv, lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa)
{
	/*Wait for the previous operation*/
	HAL_DMA2D_PollForTransfer(&hdma2d, 100);
	hdma2d.Init.Mode         = DMA2D_M2M_BLEND;
#if LV_COLOR_DEPTH == 8
    hdma2d.Init.ColorMode = DMA2D_INPUT_A8;
#elif LV_COLOR_DEPTH == 16
    hdma2d.Init.ColorMode = DMA2D_INPUT_RGB565;
#elif LV_COLOR_DEPTH == 24 || LV_COLOR_DEPTH == 32
    hdma2d.Init.ColorMode = DMA2D_INPUT_ARGB8888;
#endif
	/* DMA2D Initialization */
	if(HAL_DMA2D_Init(&hdma2d) != HAL_OK)
	{
		/* Initialization Error */
		while(1);
	}
    hdma2d.LayerCfg[1].InputAlpha = 0xff;
#if LV_COLOR_DEPTH == 8
    hdma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_A8;
#elif LV_COLOR_DEPTH == 16
    hdma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565;
#elif LV_COLOR_DEPTH == 24 || LV_COLOR_DEPTH == 32
    hdma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_ARGB8888;
#endif
	hdma2d.LayerCfg[1].InputOffset = 0x0;
	hdma2d.LayerCfg[1].RedBlueSwap = DMA2D_RB_REGULAR;
	hdma2d.LayerCfg[1].AlphaInverted = DMA2D_REGULAR_ALPHA;

	  //   Background Configuration
	hdma2d.LayerCfg[0].AlphaMode = DMA2D_REGULAR_ALPHA;
	hdma2d.LayerCfg[0].InputAlpha = 0x0;
#if LV_COLOR_DEPTH == 8
    hdma2d.LayerCfg[0].InputColorMode = DMA2D_INPUT_A8;
#elif LV_COLOR_DEPTH == 16
    hdma2d.LayerCfg[0].InputColorMode = DMA2D_INPUT_RGB565;
#elif LV_COLOR_DEPTH == 24 || LV_COLOR_DEPTH == 32
    hdma2d.LayerCfg[0].InputColorMode = DMA2D_INPUT_ARGB8888;
#endif
	hdma2d.LayerCfg[0].InputOffset = 0x0;

	HAL_DMA2D_ConfigLayer(&hdma2d, 0);
	HAL_DMA2D_ConfigLayer(&hdma2d, 1);
	HAL_DMA2D_BlendingStart(&hdma2d, (uint32_t) src, (uint32_t) dest, (uint32_t)dest, length, 1);
}

To try blending function I thinked simply create two images one after the other, the first is JPG format and the second PNG format (256 Indexed color format). But blending operation dosen’t work and the display is normally filled.

Most likely LittlevGL doesn’t see a need to accelerate blending the two images. Did you set opacity on the top image?

you mean setting alpha when converting image by littlevgl converter ?

No I mean setting opacity on the image object itself (i.e. with a style or lv_obj_set_opa_scale).

understanded ! Otherwise did you have an example to test gpu_mem_blend_cb () function ? because my goal is using DMA2D blending feature using LittlevGL blending function !
and thanks for helping @embeddedt

Did you try enabling opacity on the image object?

yes I set the opacity of the second image by : lv_obj_set_opa_scale(img1,LV_OPA_TRANSP);
and tried other alpha values but there is no diffrence --> I don’t see any transparency changes !
This is the portion of the main code :

//screen
	    lv_obj_t * scr = lv_obj_create(NULL, NULL);
		lv_scr_load(scr);
//image1
	    lv_obj_t * img1 = lv_img_create(scr, NULL);
		lv_img_set_src(img1, &birdy);
		lv_obj_set_size(img1,512,512);
		lv_obj_align(img1,NULL, LV_ALIGN_CENTER, 0, 0);
//image2		
	    lv_obj_t * img2 = lv_img_create(scr, NULL);
	    lv_img_set_src(img2, &StLogo);
	    lv_obj_set_size(img2,100,186);
	    lv_obj_align(img2,NULL, LV_ALIGN_CENTER, 0, 0);
	    lv_obj_set_opa_scale(img1,LV_OPA_TRANSP);

You made the bottom image transparent. That isn’t going to do what you want. You need to make the top image slightly transparent, so that you actually blend two images.

Blending is only done when you can see through one image into another one. With the current setup you’ve described you won’t be able to see the bottom image, so there is no need to blend.

The img1 (bottom one) will be created then img2 (top one) which alpha have to be set , to see img1 through it ! no ?

You need to set partial alpha on img2, because it is drawn on top. If you set full alpha LittlevGL is smart enough to not render a fully transparent image and no blending will occur.

how to set partial alpha ?

The same way you did, but don’t use LV_OPA_TRANSP - use one of the other possibilities instead.

I don’t see any effect of partial alpha value on the image