1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-03-03 08:46:05 +00:00

feat(core): introduce mono8 bitmap blending

[no changelog]
This commit is contained in:
cepetr 2024-05-11 11:10:26 +02:00 committed by cepetr
parent 269adf4868
commit e3a383526b
7 changed files with 122 additions and 0 deletions

View File

@ -89,6 +89,9 @@ void gfx_rgb565_copy_rgb565(const gfx_bitblt_t* bb);
// Blends a mono bitmap (with 4-bit alpha channel)
// with the destination bitmap
void gfx_rgb565_blend_mono4(const gfx_bitblt_t* bb);
// Blends a mono bitmap (with 8-bit alpha channel)
// with the destination bitmap
void gfx_rgb565_blend_mono8(const gfx_bitblt_t* bb);
// Functions for RGBA8888 bitmap/framebuffer
void gfx_rgba8888_fill(const gfx_bitblt_t* bb);
@ -103,6 +106,9 @@ void gfx_rgba8888_copy_rgba8888(const gfx_bitblt_t* bb);
// Blends a mono bitmap (with 4-bit alpha channel)
// with the destination bitmap
void gfx_rgba8888_blend_mono4(const gfx_bitblt_t* bb);
// Blends a mono bitmap (with 8-bit alpha channel)
// with the destination bitmap
void gfx_rgba8888_blend_mono8(const gfx_bitblt_t* bb);
// Functions for Mono8 bitmap/framebuffer
void gfx_mono8_fill(const gfx_bitblt_t* bb);

View File

@ -135,3 +135,24 @@ void gfx_rgb565_blend_mono4(const gfx_bitblt_t* bb) {
}
}
}
void gfx_rgb565_blend_mono8(const gfx_bitblt_t* bb) {
#if defined(USE_DMA2D) && !defined(TREZOR_EMULATOR)
if (!dma2d_rgb565_blend_mono8(bb))
#endif
{
uint16_t* dst_ptr = (uint16_t*)bb->dst_row + bb->dst_x;
uint8_t* src_ptr = (uint8_t*)bb->src_row + bb->src_x;
uint16_t height = bb->height;
while (height-- > 0) {
for (int x = 0; x < bb->width; x++) {
uint8_t fg_alpha = src_ptr[x];
dst_ptr[x] = gfx_color16_blend_a8(
bb->src_fg, gfx_color16_to_color(dst_ptr[x]), fg_alpha);
}
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
src_ptr += bb->src_stride / sizeof(*src_ptr);
}
}
}

View File

@ -155,3 +155,24 @@ void gfx_rgba8888_blend_mono4(const gfx_bitblt_t* bb) {
}
}
}
void gfx_rgba8888_blend_mono8(const gfx_bitblt_t* bb) {
#if defined(USE_DMA2D) && !defined(TREZOR_EMULATOR)
if (!dma2d_rgba8888_blend_mono8(bb))
#endif
{
uint32_t* dst_ptr = (uint32_t*)bb->dst_row + bb->dst_x;
uint8_t* src_ptr = (uint8_t*)bb->src_row + bb->src_x;
uint16_t height = bb->height;
while (height-- > 0) {
for (int x = 0; x < bb->width; x++) {
uint8_t fg_alpha = src_ptr[x];
dst_ptr[x] = gfx_color32_blend_a8(
bb->src_fg, gfx_color32_to_color(dst_ptr[x]), fg_alpha);
}
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
src_ptr += bb->src_stride / sizeof(*src_ptr);
}
}
}

View File

@ -352,11 +352,13 @@ fn generate_trezorhal_bindings() {
.allowlist_function("gfx_rgb565_copy_mono4")
.allowlist_function("gfx_rgb565_copy_rgb565")
.allowlist_function("gfx_rgb565_blend_mono4")
.allowlist_function("gfx_rgb565_blend_mono8")
.allowlist_function("gfx_rgba8888_fill")
.allowlist_function("gfx_rgba8888_copy_mono4")
.allowlist_function("gfx_rgba8888_copy_rgb565")
.allowlist_function("gfx_rgba8888_copy_rgba8888")
.allowlist_function("gfx_rgba8888_blend_mono4")
.allowlist_function("gfx_rgba8888_blend_mono8")
.allowlist_function("gfx_mono8_fill")
.allowlist_function("gfx_mono8_copy_mono1p")
.allowlist_function("gfx_mono8_copy_mono4")

View File

@ -325,6 +325,7 @@ impl<'a> BitBltCopy<'a> {
let bitblt = self.bitblt.with_dst(dst);
match self.src.format() {
BitmapFormat::MONO4 => ffi::gfx_rgb565_blend_mono4(&bitblt),
BitmapFormat::MONO8 => ffi::gfx_rgb565_blend_mono8(&bitblt),
_ => unimplemented!(),
}
}
@ -369,6 +370,7 @@ impl<'a> BitBltCopy<'a> {
let bitblt = self.bitblt.with_dst(dst);
match self.src.format() {
BitmapFormat::MONO4 => ffi::gfx_rgba8888_blend_mono4(&bitblt),
BitmapFormat::MONO8 => ffi::gfx_rgba8888_blend_mono8(&bitblt),
_ => unimplemented!(),
}
}

View File

@ -35,11 +35,13 @@ bool dma2d_rgb565_fill(const gfx_bitblt_t* bb);
bool dma2d_rgb565_copy_mono4(const gfx_bitblt_t* bb);
bool dma2d_rgb565_copy_rgb565(const gfx_bitblt_t* bb);
bool dma2d_rgb565_blend_mono4(const gfx_bitblt_t* bb);
bool dma2d_rgb565_blend_mono8(const gfx_bitblt_t* bb);
bool dma2d_rgba8888_fill(const gfx_bitblt_t* bb);
bool dma2d_rgba8888_copy_mono4(const gfx_bitblt_t* bb);
bool dma2d_rgba8888_copy_rgb565(const gfx_bitblt_t* bb);
bool dma2d_rgba8888_copy_rgba8888(const gfx_bitblt_t* bb);
bool dma2d_rgba8888_blend_mono4(const gfx_bitblt_t* bb);
bool dma2d_rgba8888_blend_mono8(const gfx_bitblt_t* bb);
#endif // TREZORHAL_DMA2D_BITBLT_H

View File

@ -337,6 +337,40 @@ bool dma2d_rgb565_blend_mono4(const gfx_bitblt_t* params) {
return true;
}
bool dma2d_rgb565_blend_mono8(const gfx_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_BLEND;
dma2d_handle.Init.OutputOffset =
bb->dst_stride / sizeof(uint16_t) - bb->width;
HAL_DMA2D_Init(&dma2d_handle);
dma2d_handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_A8;
dma2d_handle.LayerCfg[1].InputOffset = bb->src_stride - bb->width;
dma2d_handle.LayerCfg[1].AlphaMode = 0;
dma2d_handle.LayerCfg[1].InputAlpha = gfx_color_to_color32(bb->src_fg);
HAL_DMA2D_ConfigLayer(&dma2d_handle, 1);
dma2d_handle.LayerCfg[0].InputColorMode = DMA2D_INPUT_RGB565;
dma2d_handle.LayerCfg[0].InputOffset =
bb->dst_stride / sizeof(uint16_t) - bb->width;
dma2d_handle.LayerCfg[0].AlphaMode = 0;
dma2d_handle.LayerCfg[0].InputAlpha = 0;
HAL_DMA2D_ConfigLayer(&dma2d_handle, 0);
HAL_DMA2D_BlendingStart(&dma2d_handle, (uint32_t)bb->src_row + bb->src_x,
(uint32_t)bb->dst_row + bb->dst_x * sizeof(uint16_t),
(uint32_t)bb->dst_row + bb->dst_x * sizeof(uint16_t),
bb->width, bb->height);
return true;
}
bool dma2d_rgba8888_fill(const gfx_bitblt_t* bb) {
dma2d_wait();
@ -590,6 +624,40 @@ bool dma2d_rgba8888_blend_mono4(const gfx_bitblt_t* params) {
return true;
}
bool dma2d_rgb8888_blend_mono8(const gfx_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_BLEND;
dma2d_handle.Init.OutputOffset =
bb->dst_stride / sizeof(uint32_t) - bb->width;
HAL_DMA2D_Init(&dma2d_handle);
dma2d_handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_A8;
dma2d_handle.LayerCfg[1].InputOffset = bb->src_stride - bb->width;
dma2d_handle.LayerCfg[1].AlphaMode = 0;
dma2d_handle.LayerCfg[1].InputAlpha = gfx_color_to_color32(bb->src_fg);
HAL_DMA2D_ConfigLayer(&dma2d_handle, 1);
dma2d_handle.LayerCfg[0].InputColorMode = DMA2D_INPUT_ARGB8888;
dma2d_handle.LayerCfg[0].InputOffset =
bb->dst_stride / sizeof(uint32_t) - bb->width;
dma2d_handle.LayerCfg[0].AlphaMode = 0;
dma2d_handle.LayerCfg[0].InputAlpha = 0;
HAL_DMA2D_ConfigLayer(&dma2d_handle, 0);
HAL_DMA2D_BlendingStart(&dma2d_handle, (uint32_t)bb->src_row + bb->src_x,
(uint32_t)bb->dst_row + bb->dst_x * sizeof(uint32_t),
(uint32_t)bb->dst_row + bb->dst_x * sizeof(uint32_t),
bb->width, bb->height);
return true;
}
bool dma2d_rgba8888_copy_rgba8888(const gfx_bitblt_t* bb) {
dma2d_wait();