From 050e85ad101b78ff86ef093fe5f03f50c3e105dd Mon Sep 17 00:00:00 2001 From: cepetr Date: Wed, 24 Apr 2024 09:52:13 +0200 Subject: [PATCH] fixup! feat(core): refactor display drivers --- core/embed/lib/gl_bitblt_rgb565.c | 16 +--- core/embed/lib/gl_bitblt_rgba8888.c | 20 ++--- core/embed/trezorhal/dma2d_bitblt.h | 25 +++--- core/embed/trezorhal/stm32f4/dma2d_bitblt.c | 92 ++++++++++++++------- 4 files changed, 83 insertions(+), 70 deletions(-) diff --git a/core/embed/lib/gl_bitblt_rgb565.c b/core/embed/lib/gl_bitblt_rgb565.c index ddf548901..15c929c28 100644 --- a/core/embed/lib/gl_bitblt_rgb565.c +++ b/core/embed/lib/gl_bitblt_rgb565.c @@ -25,9 +25,7 @@ void gl_rgb565_fill(const gl_bitblt_t* bb) { #if defined(USE_DMA2D) && !defined(TREZOR_EMULATOR) - if (dma2d_accessible(bb->dst_row)) { - dma2d_rgb565_fill(bb); - } else + if (!dma2d_rgb565_fill(bb)) #endif { uint16_t* dst_ptr = (uint16_t*)bb->dst_row + bb->dst_x; @@ -74,9 +72,7 @@ void gl_rgb565_copy_mono1p(const gl_bitblt_t* bb) { void gl_rgb565_copy_mono4(const gl_bitblt_t* bb) { #if defined(USE_DMA2D) && !defined(TREZOR_EMULATOR) - if (dma2d_accessible(bb->dst_row) && dma2d_accessible(bb->src_row)) { - dma2d_rgb565_copy_mono4(bb); - } else + if (!dma2d_rgb565_copy_mono4(bb)) #endif { const gl_color16_t* gradient = @@ -100,9 +96,7 @@ void gl_rgb565_copy_mono4(const gl_bitblt_t* bb) { void gl_rgb565_copy_rgb565(const gl_bitblt_t* bb) { #if defined(USE_DMA2D) && !defined(TREZOR_EMULATOR) - if (dma2d_accessible(bb->dst_row) && dma2d_accessible(bb->src_row)) { - dma2d_rgb565_copy_rgb565(bb); - } else + if (!dma2d_rgb565_copy_rgb565(bb)) #endif { uint16_t* dst_ptr = (uint16_t*)bb->dst_row + bb->dst_x; @@ -121,9 +115,7 @@ void gl_rgb565_copy_rgb565(const gl_bitblt_t* bb) { void gl_rgb565_blend_mono4(const gl_bitblt_t* bb) { #if defined(USE_DMA2D) && !defined(TREZOR_EMULATOR) - if (dma2d_accessible(bb->dst_row) && dma2d_accessible(bb->src_row)) { - dma2d_rgb565_blend_mono4(bb); - } else + if (!dma2d_rgb565_blend_mono4(bb)) #endif { uint16_t* dst_ptr = (uint16_t*)bb->dst_row + bb->dst_x; diff --git a/core/embed/lib/gl_bitblt_rgba8888.c b/core/embed/lib/gl_bitblt_rgba8888.c index c1dfb5578..6c709d120 100644 --- a/core/embed/lib/gl_bitblt_rgba8888.c +++ b/core/embed/lib/gl_bitblt_rgba8888.c @@ -25,9 +25,7 @@ void gl_rgba8888_fill(const gl_bitblt_t* bb) { #if defined(USE_DMA2D) && !defined(TREZOR_EMULATOR) - if (dma2d_accessible(bb->dst_row)) { - dma2d_rgba8888_fill(bb); - } else + if (!dma2d_rgba8888_fill(bb)) #endif { uint32_t* dst_ptr = (uint32_t*)bb->dst_row + bb->dst_x; @@ -75,9 +73,7 @@ void gl_rgba8888_copy_mono1p(const gl_bitblt_t* bb) { void gl_rgba8888_copy_mono4(const gl_bitblt_t* bb) { #if defined(USE_DMA2D) && !defined(TREZOR_EMULATOR) - if (dma2d_accessible(bb->dst_row) && dma2d_accessible(bb->src_row)) { - dma2d_rgba8888_copy_mono4(bb); - } else + if (!dma2d_rgba8888_copy_mono4(bb)) #endif { const gl_color32_t* gradient = @@ -101,9 +97,7 @@ void gl_rgba8888_copy_mono4(const gl_bitblt_t* bb) { void gl_rgba8888_copy_rgb565(const gl_bitblt_t* bb) { #if defined(USE_DMA2D) && !defined(TREZOR_EMULATOR) - if (dma2d_accessible(bb->dst_row) && dma2d_accessible(bb->src_row)) { - dma2d_rgba8888_copy_rgb565(bb); - } else + if (!dma2d_rgba8888_copy_rgb565(bb)) #endif { uint32_t* dst_ptr = (uint32_t*)bb->dst_row + bb->dst_x; @@ -122,9 +116,7 @@ void gl_rgba8888_copy_rgb565(const gl_bitblt_t* bb) { void gl_rgba8888_copy_rgba8888(const gl_bitblt_t* bb) { #if defined(USE_DMA2D) && !defined(TREZOR_EMULATOR) - if (dma2d_accessible(bb->dst_row) && dma2d_accessible(bb->src_row)) { - dma2d_rgba8888_copy_rgba8888(bb); - } else + if (!dma2d_rgba8888_copy_rgba8888(bb)) #endif { uint32_t* dst_ptr = (uint32_t*)bb->dst_row + bb->dst_x; @@ -143,9 +135,7 @@ void gl_rgba8888_copy_rgba8888(const gl_bitblt_t* bb) { void gl_rgba8888_blend_mono4(const gl_bitblt_t* bb) { #if defined(USE_DMA2D) && !defined(TREZOR_EMULATOR) - if (dma2d_accessible(bb->dst_row) && dma2d_accessible(bb->src_row)) { - dma2d_rgba8888_blend_mono4(bb); - } else + if (!dma2d_rgba8888_blend_mono4(bb)) #endif { uint32_t* dst_ptr = (uint32_t*)bb->dst_row + bb->dst_x; diff --git a/core/embed/trezorhal/dma2d_bitblt.h b/core/embed/trezorhal/dma2d_bitblt.h index 26c8f3bfe..fc327de6e 100644 --- a/core/embed/trezorhal/dma2d_bitblt.h +++ b/core/embed/trezorhal/dma2d_bitblt.h @@ -22,25 +22,24 @@ #include "gl_bitblt.h" -// Returns `true` if the specified address is accessible by DMA2D -// and can be used by any of the following functions -bool dma2d_accessible(const void* ptr); - // Waits until any pending DMA2D operation is finished void dma2d_wait(void); // Following functions are hardware (DMA2D) accelerated versions // of `gl_rgb565_xxx()` and `gl_rgba8888_xxx()` function from `gl_bitblt.h` -void dma2d_rgb565_fill(const gl_bitblt_t* bb); -void dma2d_rgb565_copy_mono4(const gl_bitblt_t* bb); -void dma2d_rgb565_copy_rgb565(const gl_bitblt_t* bb); -void dma2d_rgb565_blend_mono4(const gl_bitblt_t* bb); +// These functions may return `false`, indicating that the accelerated +// operation cannot be performed and must be implemented in software + +bool dma2d_rgb565_fill(const gl_bitblt_t* bb); +bool dma2d_rgb565_copy_mono4(const gl_bitblt_t* bb); +bool dma2d_rgb565_copy_rgb565(const gl_bitblt_t* bb); +bool dma2d_rgb565_blend_mono4(const gl_bitblt_t* bb); -void dma2d_rgba8888_fill(const gl_bitblt_t* bb); -void dma2d_rgba8888_copy_mono4(const gl_bitblt_t* bb); -void dma2d_rgba8888_copy_rgb565(const gl_bitblt_t* bb); -void dma2d_rgba8888_copy_rgba8888(const gl_bitblt_t* bb); -void dma2d_rgba8888_blend_mono4(const gl_bitblt_t* bb); +bool dma2d_rgba8888_fill(const gl_bitblt_t* bb); +bool dma2d_rgba8888_copy_mono4(const gl_bitblt_t* bb); +bool dma2d_rgba8888_copy_rgb565(const gl_bitblt_t* bb); +bool dma2d_rgba8888_copy_rgba8888(const gl_bitblt_t* bb); +bool dma2d_rgba8888_blend_mono4(const gl_bitblt_t* bb); #endif // TREZORHAL_DMA2D_BITBLT_H diff --git a/core/embed/trezorhal/stm32f4/dma2d_bitblt.c b/core/embed/trezorhal/stm32f4/dma2d_bitblt.c index ae2d809a0..f478d7d07 100644 --- a/core/embed/trezorhal/stm32f4/dma2d_bitblt.c +++ b/core/embed/trezorhal/stm32f4/dma2d_bitblt.c @@ -28,7 +28,9 @@ static DMA2D_HandleTypeDef dma2d_handle = { .Instance = (DMA2D_TypeDef*)DMA2D_BASE, }; -bool dma2d_accessible(const void* ptr) { +// Returns `true` if the specified address is accessible by DMA2D +// and can be used by any of the following functions +static inline bool dma2d_accessible(const void* ptr) { #ifdef STM32F4 const void* ccm_start = (const void*)0x10000000; const void* ccm_end = (const void*)0x1000FFFF; @@ -43,9 +45,13 @@ void dma2d_wait(void) { ; } -void dma2d_rgb565_fill(const gl_bitblt_t* bb) { +bool dma2d_rgb565_fill(const gl_bitblt_t* bb) { dma2d_wait(); + if (!dma2d_accessible(bb->dst_row)) { + return false; + } + if (bb->src_alpha == 255) { dma2d_handle.Init.ColorMode = DMA2D_OUTPUT_RGB565; dma2d_handle.Init.Mode = DMA2D_R2M; @@ -84,18 +90,11 @@ void dma2d_rgb565_fill(const gl_bitblt_t* bb) { bb->height); #else // STM32F4 can not accelerate blending with the fixed color - uint16_t* dst_ptr = (uint16_t*)bb->dst_row + bb->dst_x; - uint16_t height = bb->height; - uint8_t alpha = bb->src_alpha; - while (height-- > 0) { - for (int x = 0; x < bb->width; x++) { - dst_ptr[x] = gl_color16_blend_a8( - bb->src_fg, gl_color16_to_color(dst_ptr[x]), alpha); - } - dst_ptr += bb->dst_stride / sizeof(*dst_ptr); - } + return false; #endif } + + return true; } static void dma2d_config_clut(uint32_t layer, gl_color_t fg, gl_color_t bg) { @@ -161,7 +160,7 @@ static void dma2d_rgb565_copy_mono4_last_col(gl_bitblt_t* bb, } } -void dma2d_rgb565_copy_mono4(const gl_bitblt_t* params) { +bool dma2d_rgb565_copy_mono4(const gl_bitblt_t* params) { const gl_color16_t* src_gradient = NULL; gl_bitblt_t bb_copy = *params; @@ -169,6 +168,10 @@ void dma2d_rgb565_copy_mono4(const gl_bitblt_t* params) { dma2d_wait(); + if (!dma2d_accessible(bb->dst_row) || !dma2d_accessible(bb->src_row)) { + return false; + } + if (bb->src_x & 1) { // First column of mono4 bitmap is odd // Use the CPU to draw the first column @@ -206,11 +209,16 @@ void dma2d_rgb565_copy_mono4(const gl_bitblt_t* params) { HAL_DMA2D_Start(&dma2d_handle, (uint32_t)bb->src_row + bb->src_x / 2, (uint32_t)bb->dst_row + bb->dst_x * sizeof(uint16_t), bb->width, bb->height); + return true; } -void dma2d_rgb565_copy_rgb565(const gl_bitblt_t* bb) { +bool dma2d_rgb565_copy_rgb565(const gl_bitblt_t* bb) { dma2d_wait(); + if (!dma2d_accessible(bb->dst_row) || !dma2d_accessible(bb->src_row)) { + return false; + } + dma2d_handle.Init.ColorMode = DMA2D_OUTPUT_RGB565; dma2d_handle.Init.Mode = DMA2D_M2M_PFC; dma2d_handle.Init.OutputOffset = @@ -228,6 +236,7 @@ void dma2d_rgb565_copy_rgb565(const gl_bitblt_t* bb) { (uint32_t)bb->src_row + bb->src_x * sizeof(uint16_t), (uint32_t)bb->dst_row + bb->dst_x * sizeof(uint16_t), bb->width, bb->height); + return true; } static void dma2d_rgb565_blend_mono4_first_col(const gl_bitblt_t* bb) { @@ -260,12 +269,16 @@ static void dma2d_rgb565_blend_mono4_last_col(const gl_bitblt_t* bb) { } } -void dma2d_rgb565_blend_mono4(const gl_bitblt_t* params) { +bool dma2d_rgb565_blend_mono4(const gl_bitblt_t* params) { dma2d_wait(); gl_bitblt_t bb_copy = *params; gl_bitblt_t* bb = &bb_copy; + if (!dma2d_accessible(bb->dst_row) || !dma2d_accessible(bb->src_row)) { + return false; + } + if (bb->src_x & 1) { // First column of mono4 bitmap is odd // Use the CPU to draw the first column @@ -308,11 +321,17 @@ void dma2d_rgb565_blend_mono4(const gl_bitblt_t* params) { (uint32_t)bb->dst_row + bb->dst_x * sizeof(uint16_t), bb->width, bb->height); } + + return true; } -void dma2d_rgba8888_fill(const gl_bitblt_t* bb) { +bool dma2d_rgba8888_fill(const gl_bitblt_t* bb) { dma2d_wait(); + if (!dma2d_accessible(bb->dst_row)) { + return false; + } + if (bb->src_alpha == 255) { dma2d_handle.Init.ColorMode = DMA2D_OUTPUT_ARGB8888; dma2d_handle.Init.Mode = DMA2D_R2M; @@ -351,18 +370,10 @@ void dma2d_rgba8888_fill(const gl_bitblt_t* bb) { bb->height); #else // STM32F4 can not accelerate blending with the fixed color - uint32_t* dst_ptr = (uint32_t*)bb->dst_row + bb->dst_x; - uint16_t height = bb->height; - uint8_t alpha = bb->src_alpha; - while (height-- > 0) { - for (int x = 0; x < bb->width; x++) { - dst_ptr[x] = gl_color32_blend_a8( - bb->src_fg, gl_color32_to_color(dst_ptr[x]), alpha); - } - dst_ptr += bb->dst_stride / sizeof(*dst_ptr); - } + return false; #endif } + return true; } static void dma2d_rgba8888_copy_mono4_first_col(gl_bitblt_t* bb, @@ -395,7 +406,7 @@ static void dma2d_rgba8888_copy_mono4_last_col(gl_bitblt_t* bb, } } -void dma2d_rgba8888_copy_mono4(const gl_bitblt_t* params) { +bool dma2d_rgba8888_copy_mono4(const gl_bitblt_t* params) { const gl_color32_t* src_gradient = NULL; gl_bitblt_t bb_copy = *params; @@ -403,6 +414,10 @@ void dma2d_rgba8888_copy_mono4(const gl_bitblt_t* params) { dma2d_wait(); + if (!dma2d_accessible(bb->dst_row) || !dma2d_accessible(bb->src_row)) { + return false; + } + if (bb->src_x & 1) { // First column of mono4 bitmap is odd // Use the CPU to draw the first column @@ -440,11 +455,16 @@ void dma2d_rgba8888_copy_mono4(const gl_bitblt_t* params) { HAL_DMA2D_Start(&dma2d_handle, (uint32_t)bb->src_row + bb->src_x / 2, (uint32_t)bb->dst_row + bb->dst_x * sizeof(uint32_t), bb->width, bb->height); + return true; } -void dma2d_rgba8888_copy_rgb565(const gl_bitblt_t* bb) { +bool dma2d_rgba8888_copy_rgb565(const gl_bitblt_t* bb) { dma2d_wait(); + if (!dma2d_accessible(bb->dst_row) || !dma2d_accessible(bb->src_row)) { + return false; + } + dma2d_handle.Init.ColorMode = DMA2D_OUTPUT_ARGB8888; dma2d_handle.Init.Mode = DMA2D_M2M_PFC; dma2d_handle.Init.OutputOffset = @@ -462,6 +482,7 @@ void dma2d_rgba8888_copy_rgb565(const gl_bitblt_t* bb) { (uint32_t)bb->src_row + bb->src_x * sizeof(uint16_t), (uint32_t)bb->dst_row + bb->dst_x * sizeof(uint32_t), bb->width, bb->height); + return true; } static void dma2d_rgba8888_blend_mono4_first_col(const gl_bitblt_t* bb) { @@ -494,12 +515,16 @@ static void dma2d_rgba8888_blend_mono4_last_col(const gl_bitblt_t* bb) { } } -void dma2d_rgba8888_blend_mono4(const gl_bitblt_t* params) { +bool dma2d_rgba8888_blend_mono4(const gl_bitblt_t* params) { dma2d_wait(); gl_bitblt_t bb_copy = *params; gl_bitblt_t* bb = &bb_copy; + if (!dma2d_accessible(bb->dst_row) || !dma2d_accessible(bb->src_row)) { + return false; + } + if (bb->src_x & 1) { // First column of mono4 bitmap is odd // Use the CPU to draw the first column @@ -542,11 +567,17 @@ void dma2d_rgba8888_blend_mono4(const gl_bitblt_t* params) { (uint32_t)bb->dst_row + bb->dst_x * sizeof(uint32_t), bb->width, bb->height); } + + return true; } -void dma2d_rgba8888_copy_rgba8888(const gl_bitblt_t* bb) { +bool dma2d_rgba8888_copy_rgba8888(const gl_bitblt_t* bb) { dma2d_wait(); + if (!dma2d_accessible(bb->dst_row) || !dma2d_accessible(bb->src_row)) { + return false; + } + dma2d_handle.Init.ColorMode = DMA2D_OUTPUT_ARGB8888; dma2d_handle.Init.Mode = DMA2D_M2M_PFC; dma2d_handle.Init.OutputOffset = @@ -564,4 +595,5 @@ void dma2d_rgba8888_copy_rgba8888(const gl_bitblt_t* bb) { (uint32_t)bb->src_row + bb->src_x * sizeof(uint32_t), (uint32_t)bb->dst_row + bb->dst_x * sizeof(uint32_t), bb->width, bb->height); + return true; }