25 #include "ui_drawing.h" 26 #include "ui_drawing_soft.h" 33 #if DRAWING_DMA2D_BPP == 16 34 #define DRAWING_DMA2D_FORMAT DMA2D_RGB565 35 #elif DRAWING_DMA2D_BPP == 24 36 #define DRAWING_DMA2D_FORMAT DMA2D_RGB888 37 #elif DRAWING_DMA2D_BPP == 32 38 #define DRAWING_DMA2D_FORMAT DMA2D_ARGB8888 40 #error "Define 'DRAWING_DMA2D_BPP' is required (16, 24 or 32)" 49 typedef void (*t_drawing_notification)(
bool under_isr);
56 static DMA2D_HandleTypeDef g_hdma2d;
61 static t_drawing_notification g_callback_notification;
67 static bool g_dma2d_running;
72 static void* g_dma2d_semaphore;
79 static inline void _drawing_dma2d_wait(
void)
81 while(g_dma2d_running)
83 LLUI_DISPLAY_IMPL_binarySemaphoreTake(g_dma2d_semaphore);
90 static inline void _drawing_dma2d_done(
void)
92 g_dma2d_running =
false;
93 LLUI_DISPLAY_IMPL_binarySemaphoreGive(g_dma2d_semaphore,
true);
99 static inline uint8_t* _drawing_dma2d_adjust_address(uint8_t* address, uint32_t x, uint32_t y, uint32_t stride, uint32_t bpp)
101 return address + ((y * stride + x) * bpp / 8);
107 static inline void _drawing_dma2d_configure_alpha_image_data(MICROUI_GraphicsContext* gc, jint* alphaAndColor)
110 *(alphaAndColor) <<= 24;
111 *(alphaAndColor) |= (gc->foreground_color & 0xffffff);
116 void DRAWING_DMA2D_IRQHandler(
void)
119 HAL_DMA2D_IRQHandler(&g_hdma2d);
122 _drawing_dma2d_done();
125 g_callback_notification(
true);
130 void DRAWING_DMA2D_initialize(
void* binary_semaphore_handle)
133 g_dma2d_running =
false;
134 g_dma2d_semaphore = binary_semaphore_handle;
137 HAL_NVIC_SetPriority(DMA2D_IRQn, 5, 3);
138 HAL_NVIC_EnableIRQ(DMA2D_IRQn);
141 g_hdma2d.Init.ColorMode = DRAWING_DMA2D_FORMAT;
142 g_hdma2d.Instance = DMA2D;
145 void DRAWING_DMA2D_configure_memcpy(uint8_t* srcAddr, uint8_t* destAddr, uint32_t xmin, uint32_t ymin, uint32_t xmax, uint32_t ymax, uint32_t stride,
DRAWING_DMA2D_memcpy* memcpy_data)
147 _drawing_dma2d_wait();
149 uint32_t width = (xmax - xmin + 1);
150 uint32_t height = (ymax - ymin + 1);
153 HAL_DMA2D_DeInit(&g_hdma2d);
156 g_hdma2d.LayerCfg[1].InputOffset = stride - width;
157 g_hdma2d.LayerCfg[1].InputColorMode = DRAWING_DMA2D_FORMAT;
158 HAL_DMA2D_ConfigLayer(&g_hdma2d, 1);
161 g_hdma2d.Init.Mode = DMA2D_M2M;
162 g_hdma2d.Init.OutputOffset = stride - width;
163 HAL_DMA2D_Init(&g_hdma2d) ;
166 memcpy_data->src_address = _drawing_dma2d_adjust_address(srcAddr, xmin, ymin, stride, DRAWING_DMA2D_BPP);
167 memcpy_data->dest_address = _drawing_dma2d_adjust_address(destAddr, xmin, ymin, stride, DRAWING_DMA2D_BPP);
168 memcpy_data->width = width;
169 memcpy_data->height = height;
172 g_callback_notification = &LLUI_DISPLAY_flushDone;
173 g_dma2d_running =
true;
180 (uint32_t)memcpy_data->src_address,
181 (uint32_t)memcpy_data->dest_address,
189 DRAWING_Status UI_DRAWING_fillRectangle(MICROUI_GraphicsContext* gc, jint x1, jint y1, jint x2, jint y2)
191 if (LLUI_DISPLAY_isClipEnabled(gc) && !LLUI_DISPLAY_clipRectangle(gc, &x1, &y1, &x2, &y2))
198 _drawing_dma2d_wait();
200 LLUI_DISPLAY_setDrawingLimits(gc, x1, y1, x2, y2);
202 uint32_t rectangle_width = x2 - x1 + 1;
203 uint32_t rectangle_height = y2 - y1 + 1;
204 uint32_t stride = LLUI_DISPLAY_getStrideInPixels(&gc->image);
207 HAL_DMA2D_DeInit(&g_hdma2d);
210 g_hdma2d.Init.Mode = DMA2D_R2M;
211 g_hdma2d.Init.OutputOffset = stride - rectangle_width;
212 HAL_DMA2D_Init(&g_hdma2d);
215 g_callback_notification = &LLUI_DISPLAY_notifyAsynchronousDrawingEnd;
216 g_dma2d_running =
true;
219 uint8_t* destination_address = _drawing_dma2d_adjust_address(LLUI_DISPLAY_getBufferAddress(&gc->image), x1, y1, stride, DRAWING_DMA2D_BPP);
220 HAL_DMA2D_Start_IT(&g_hdma2d, gc->foreground_color, (uint32_t)destination_address, rectangle_width, rectangle_height);
222 return DRAWING_RUNNING;
225 DRAWING_Status UI_DRAWING_drawImage(MICROUI_GraphicsContext* gc, MICROUI_Image* image, jint x_src, jint y_src, jint width, jint height, jint x_dest, jint y_dest, jint alpha)
227 if (LLUI_DISPLAY_isClipEnabled(gc) && !!LLUI_DISPLAY_clipRegion(gc, &x_src, &y_src, &width, &height, &x_dest, &y_dest))
234 if ((uint32_t)&(gc->image) == (uint32_t)image) {
237 if ((y_dest > y_src && y_dest < (y_src + height)) || (y_dest == y_src && x_dest > x_src && x_dest < (x_src + width))) {
239 UI_DRAWING_SOFT_drawImage(gc, image, x_src, y_src, width, height, x_dest, y_dest, alpha);
244 _drawing_dma2d_wait();
249 switch(image->format)
251 case MICROUI_IMAGE_FORMAT_RGB565:
255 case MICROUI_IMAGE_FORMAT_ARGB8888:
256 format = CM_ARGB8888;
259 case MICROUI_IMAGE_FORMAT_RGB888:
263 case MICROUI_IMAGE_FORMAT_ARGB1555:
264 format = CM_ARGB1555;
267 case MICROUI_IMAGE_FORMAT_ARGB4444:
268 format = CM_ARGB4444;
271 case MICROUI_IMAGE_FORMAT_A4:
275 jint xAlign = x_src & 1;
276 jint wAlign = width & 1;
282 UI_DRAWING_SOFT_drawImage(gc, image, x_src + width, y_src, 1, height, x_dest + width, y_dest, alpha);
291 UI_DRAWING_SOFT_drawImage(gc, image, x_src, y_src, 1, height, x_dest, y_dest, alpha);
295 UI_DRAWING_SOFT_drawImage(gc, image, x_src + width, y_src, 1, height, x_dest + width, y_dest, alpha);
303 UI_DRAWING_SOFT_drawImage(gc, image, x_src, y_src, 1, height, x_dest, y_dest, alpha);
310 _drawing_dma2d_configure_alpha_image_data(gc, &alpha);
315 case MICROUI_IMAGE_FORMAT_A8:
316 _drawing_dma2d_configure_alpha_image_data(gc, &alpha);
322 UI_DRAWING_SOFT_drawImage(gc, image, x_src, y_src, width, height, x_dest, y_dest, alpha);
326 uint32_t srcStride = LLUI_DISPLAY_getStrideInPixels(image);
327 uint32_t destStride = LLUI_DISPLAY_getStrideInPixels(&gc->image);
328 uint8_t* srcAddr = _drawing_dma2d_adjust_address(LLUI_DISPLAY_getBufferAddress(image), x_src, y_src, srcStride, bpp);
329 uint8_t* destAddr = _drawing_dma2d_adjust_address(LLUI_DISPLAY_getBufferAddress(&gc->image), x_dest, y_dest, destStride, DRAWING_DMA2D_BPP);
332 HAL_DMA2D_DeInit(&g_hdma2d);
335 g_hdma2d.LayerCfg[0].InputOffset = destStride - width;
336 g_hdma2d.LayerCfg[0].InputColorMode = DRAWING_DMA2D_FORMAT;
337 g_hdma2d.LayerCfg[0].AlphaMode = DMA2D_NO_MODIF_ALPHA;
338 g_hdma2d.LayerCfg[0].InputAlpha = 255;
339 HAL_DMA2D_ConfigLayer(&g_hdma2d, 0);
342 HAL_DMA2D_DisableCLUT(&g_hdma2d, 1);
343 g_hdma2d.LayerCfg[1].InputOffset = srcStride - width;
344 g_hdma2d.LayerCfg[1].InputColorMode = format;
345 g_hdma2d.LayerCfg[1].AlphaMode = DMA2D_COMBINE_ALPHA;
346 g_hdma2d.LayerCfg[1].InputAlpha = alpha;
347 HAL_DMA2D_ConfigLayer(&g_hdma2d, 1);
350 g_hdma2d.Init.Mode = DMA2D_M2M_BLEND;
351 g_hdma2d.Init.OutputOffset = destStride - width;
352 HAL_DMA2D_Init(&g_hdma2d) ;
355 g_dma2d_running =
true;
356 g_callback_notification = &LLUI_DISPLAY_notifyAsynchronousDrawingEnd;
357 LLUI_DISPLAY_setDrawingLimits(gc, x_dest, y_dest, x_dest + width - 1, y_dest + height - 1);
360 HAL_DMA2D_BlendingStart_IT(&g_hdma2d, (uint32_t)srcAddr, (uint32_t)destAddr, (uint32_t)destAddr, width, height);
362 return DRAWING_RUNNING;
Use STM32 DMA2D (ChromART) for MicroEJ ui_drawing.h implementation.