WIP - drawlib - dma2d renamed to bitblt

cepetr/drawlib-integration
cepetr 1 month ago
parent 484394bb4d
commit bcb6673220

@ -67,9 +67,9 @@ SOURCE_MOD += [
'embed/lib/fonts/font_bitmap.c',
'embed/lib/fonts/fonts.c',
'embed/lib/gl_color.c',
'embed/lib/gl_dma2d_rgb565.c',
'embed/lib/gl_dma2d_rgba8888.c',
'embed/lib/gl_dma2d_mono8.c',
'embed/lib/gl_bitblt_rgb565.c',
'embed/lib/gl_bitblt_rgba8888.c',
'embed/lib/gl_bitblt_mono8.c',
'embed/lib/image.c',
'embed/lib/mini_printf.c',
'embed/lib/terminal.c',

@ -91,9 +91,9 @@ SOURCE_MOD += [
'embed/lib/fonts/font_bitmap.c',
'embed/lib/fonts/fonts.c',
'embed/lib/gl_color.c',
'embed/lib/gl_dma2d_mono8.c',
'embed/lib/gl_dma2d_rgb565.c',
'embed/lib/gl_dma2d_rgba8888.c',
'embed/lib/gl_bitblt_mono8.c',
'embed/lib/gl_bitblt_rgb565.c',
'embed/lib/gl_bitblt_rgba8888.c',
'embed/lib/image.c',
'embed/lib/mini_printf.c',
'embed/lib/terminal.c',

@ -88,9 +88,9 @@ SOURCE_MOD += [
'embed/lib/fonts/font_bitmap.c',
'embed/lib/fonts/fonts.c',
'embed/lib/gl_color.c',
'embed/lib/gl_dma2d_mono8.c',
'embed/lib/gl_dma2d_rgb565.c',
'embed/lib/gl_dma2d_rgba8888.c',
'embed/lib/gl_bitblt_mono8.c',
'embed/lib/gl_bitblt_rgb565.c',
'embed/lib/gl_bitblt_rgba8888.c',
'embed/lib/image.c',
'embed/lib/terminal.c',
'embed/lib/touch.c',

@ -209,9 +209,9 @@ SOURCE_MOD += [
'embed/lib/fonts/font_bitmap.c',
'embed/lib/fonts/fonts.c',
'embed/lib/gl_color.c',
'embed/lib/gl_dma2d_rgb565.c',
'embed/lib/gl_dma2d_rgba8888.c',
'embed/lib/gl_dma2d_mono8.c',
'embed/lib/gl_bitblt_rgb565.c',
'embed/lib/gl_bitblt_rgba8888.c',
'embed/lib/gl_bitblt_mono8.c',
'embed/lib/image.c',
'embed/lib/mini_printf.c',
'embed/lib/terminal.c',

@ -209,9 +209,9 @@ SOURCE_MOD += [
'embed/lib/fonts/font_bitmap.c',
'embed/lib/fonts/fonts.c',
'embed/lib/gl_color.c',
'embed/lib/gl_dma2d_rgb565.c',
'embed/lib/gl_dma2d_rgba8888.c',
'embed/lib/gl_dma2d_mono8.c',
'embed/lib/gl_bitblt_rgb565.c',
'embed/lib/gl_bitblt_rgba8888.c',
'embed/lib/gl_bitblt_mono8.c',
'embed/lib/image.c',
'embed/lib/terminal.c',
'embed/lib/translations.c',

@ -17,8 +17,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GL_DMA2D_H
#define GL_DMA2D_H
#ifndef GL_BITBLT_H
#define GL_BITBLT_H
#include <stdbool.h>
#include <stdint.h>
@ -46,23 +46,23 @@ typedef struct {
gl_color_t src_bg;
uint8_t src_alpha;
} dma2d_params_t;
} gl_bitblt_t;
bool rgb565_fill(const dma2d_params_t* dp);
bool rgb565_copy_mono4(const dma2d_params_t* dp);
bool rgb565_copy_rgb565(const dma2d_params_t* dp);
bool rgb565_blend_mono4(const dma2d_params_t* dp);
void gl_rgb565_fill(const gl_bitblt_t* bb);
void gl_rgb565_copy_mono4(const gl_bitblt_t* bb);
void gl_rgb565_copy_rgb565(const gl_bitblt_t* bb);
void gl_rgb565_blend_mono4(const gl_bitblt_t* bb);
bool rgba8888_fill(const dma2d_params_t* dp);
bool rgba8888_copy_mono4(const dma2d_params_t* dp);
bool rgba8888_copy_rgb565(const dma2d_params_t* dp);
bool rgba8888_copy_rgba8888(const dma2d_params_t* dp);
bool rgba8888_blend_mono4(const dma2d_params_t* dp);
void gl_rgba8888_fill(const gl_bitblt_t* bb);
void gl_rgba8888_copy_mono4(const gl_bitblt_t* bb);
void gl_rgba8888_copy_rgb565(const gl_bitblt_t* bb);
void gl_rgba8888_copy_rgba8888(const gl_bitblt_t* bb);
void gl_rgba8888_blend_mono4(const gl_bitblt_t* bb);
bool mono8_fill(const dma2d_params_t* dp);
bool mono8_copy_mono1p(const dma2d_params_t* dp);
bool mono8_copy_mono4(const dma2d_params_t* dp);
bool mono8_blend_mono1p(const dma2d_params_t* dp);
bool mono8_blend_mono4(const dma2d_params_t* dp);
void gl_mono8_fill(const gl_bitblt_t* bb);
void gl_mono8_copy_mono1p(const gl_bitblt_t* bb);
void gl_mono8_copy_mono4(const gl_bitblt_t* bb);
void gl_mono8_blend_mono1p(const gl_bitblt_t* bb);
void gl_mono8_blend_mono4(const gl_bitblt_t* bb);
#endif // GL_DMA2D_H
#endif // GL_BITBLT_H

@ -0,0 +1,110 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "gl_bitblt.h"
void gl_mono8_fill(const gl_bitblt_t* bb) {
uint8_t* dst_ptr = (uint8_t*)bb->dst_row + bb->dst_x;
uint16_t height = bb->height;
uint8_t fg = gl_color_lum(bb->src_fg);
while (height-- > 0) {
for (int x = 0; x < bb->width; x++) {
dst_ptr[x] = fg;
}
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
}
}
void gl_mono8_copy_mono1p(const gl_bitblt_t* bb) {
uint8_t* dst_ptr = (uint8_t*)bb->dst_row + bb->dst_x;
uint8_t* src = (uint8_t*)bb->src_row;
uint16_t src_ofs = bb->src_stride * bb->src_y + bb->src_x;
uint16_t height = bb->height;
uint8_t fg = gl_color_lum(bb->src_fg);
uint8_t bg = gl_color_lum(bb->src_bg);
while (height-- > 0) {
for (int x = 0; x < bb->width; x++) {
uint8_t mask = 1 << (7 - ((src_ofs + x) & 7));
uint8_t data = src[(src_ofs + x) / 8];
dst_ptr[x] = (data & mask) ? fg : bg;
}
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
src_ofs += bb->src_stride;
}
}
void gl_mono8_copy_mono4(const gl_bitblt_t* bb) {
uint8_t* dst_ptr = (uint8_t*)bb->dst_row + bb->dst_x;
uint8_t* src_row = (uint8_t*)bb->src_row;
uint16_t height = bb->height;
uint8_t fg = gl_color_lum(bb->src_fg);
uint8_t bg = gl_color_lum(bb->src_bg);
while (height-- > 0) {
for (int x = 0; x < bb->width; x++) {
uint8_t src_data = src_row[(x + bb->src_x) / 2];
uint8_t src_lum = (x + bb->src_x) & 1 ? src_data >> 4 : src_data & 0xF;
dst_ptr[x] = (fg * src_lum + bg * (15 - src_lum)) / 15;
}
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
src_row += bb->src_stride / sizeof(*src_row);
}
}
void gl_mono8_blend_mono1p(const gl_bitblt_t* bb) {
uint8_t* dst_ptr = (uint8_t*)bb->dst_row + bb->dst_x;
uint8_t* src = (uint8_t*)bb->src_row;
uint16_t src_ofs = bb->src_stride * bb->src_y + bb->src_x;
uint16_t height = bb->height;
uint8_t fg = gl_color_lum(bb->src_fg);
while (height-- > 0) {
for (int x = 0; x < bb->width; x++) {
uint8_t mask = 1 << (7 - ((src_ofs + x) & 7));
uint8_t data = src[(src_ofs + x) / 8];
dst_ptr[x] = (data & mask) ? fg : dst_ptr[x];
}
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
src_ofs += bb->src_stride;
}
}
void gl_mono8_blend_mono4(const gl_bitblt_t* bb) {
uint8_t* dst_ptr = (uint8_t*)bb->dst_row + bb->dst_x;
uint8_t* src_row = (uint8_t*)bb->src_row;
uint16_t height = bb->height;
uint8_t fg = gl_color_lum(bb->src_fg);
while (height-- > 0) {
for (int x = 0; x < bb->width; x++) {
uint8_t src_data = src_row[(x + bb->src_x) / 2];
uint8_t src_alpha = (x + bb->src_x) & 1 ? src_data >> 4 : src_data & 0x0F;
dst_ptr[x] = (fg * src_alpha + dst_ptr[x] * (15 - src_alpha)) / 15;
}
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
src_row += bb->src_stride / sizeof(*src_row);
}
}

@ -0,0 +1,124 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "gl_bitblt.h"
#if USE_DMA2D
#include "dma2d.h"
#endif
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
#endif
{
uint16_t* dst_ptr = (uint16_t*)bb->dst_row + bb->dst_x;
uint16_t height = bb->height;
if (bb->src_alpha == 255) {
while (height-- > 0) {
for (int x = 0; x < bb->width; x++) {
dst_ptr[x] = bb->src_fg;
}
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
}
} else {
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, dst_ptr[x], alpha);
}
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
}
}
}
}
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
#endif
{
const gl_color16_t* gradient =
gl_color16_gradient_a4(bb->src_fg, bb->src_bg);
uint16_t* dst_ptr = (uint16_t*)bb->dst_row + bb->dst_x;
uint8_t* src_row = (uint8_t*)bb->src_row;
uint16_t height = bb->height;
while (height-- > 0) {
for (int x = 0; x < bb->width; x++) {
uint8_t fg_data = src_row[(x + bb->src_x) / 2];
uint8_t fg_lum = (x + bb->src_x) & 1 ? fg_data >> 4 : fg_data & 0xF;
dst_ptr[x] = gradient[fg_lum];
}
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
src_row += bb->src_stride / sizeof(*src_row);
}
}
}
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
#endif
{
uint16_t* dst_ptr = (uint16_t*)bb->dst_row + bb->dst_x;
uint16_t* src_ptr = (uint16_t*)bb->src_row + bb->src_x;
uint16_t height = bb->height;
while (height-- > 0) {
for (int x = 0; x < bb->width; x++) {
dst_ptr[x] = src_ptr[x];
}
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
src_ptr += bb->src_stride / sizeof(*src_ptr);
}
}
}
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
#endif
{
uint16_t* dst_ptr = (uint16_t*)bb->dst_row + bb->dst_x;
uint8_t* src_row = (uint8_t*)bb->src_row;
uint16_t height = bb->height;
while (height-- > 0) {
for (int x = 0; x < bb->width; x++) {
uint8_t fg_data = src_row[(x + bb->src_x) / 2];
uint8_t fg_alpha = (x + bb->src_x) & 1 ? fg_data >> 4 : fg_data & 0x0F;
dst_ptr[x] = gl_color16_blend_a4(
bb->src_fg, gl_color16_to_color(dst_ptr[x]), fg_alpha);
}
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
src_row += bb->src_stride / sizeof(*src_row);
}
}
}

@ -0,0 +1,146 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "gl_bitblt.h"
#if USE_DMA2D
#include "dma2d.h"
#endif
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
#endif
{
uint32_t* dst_ptr = (uint32_t*)bb->dst_row + bb->dst_x;
uint16_t height = bb->height;
if (bb->src_alpha == 255) {
while (height-- > 0) {
for (int x = 0; x < bb->width; x++) {
dst_ptr[x] = gl_color_to_color32(bb->src_fg);
}
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
}
} else {
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);
}
}
}
}
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
#endif
{
const gl_color32_t* gradient =
gl_color32_gradient_a4(bb->src_fg, bb->src_bg);
uint32_t* dst_ptr = (uint32_t*)bb->dst_row + bb->dst_x;
uint8_t* src_row = (uint8_t*)bb->src_row;
uint16_t height = bb->height;
while (height-- > 0) {
for (int x = 0; x < bb->width; x++) {
uint8_t fg_data = src_row[(x + bb->src_x) / 2];
uint8_t fg_lum = (x + bb->src_x) & 1 ? fg_data >> 4 : fg_data & 0xF;
dst_ptr[x] = gradient[fg_lum];
}
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
src_row += bb->src_stride / sizeof(*src_row);
}
}
}
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
#endif
{
uint32_t* dst_ptr = (uint32_t*)bb->dst_row + bb->dst_x;
uint16_t* src_ptr = (uint16_t*)bb->src_row + bb->src_x;
uint16_t height = bb->height;
while (height-- > 0) {
for (int x = 0; x < bb->width; x++) {
dst_ptr[x] = gl_color16_to_color32(src_ptr[x]);
}
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
src_ptr += bb->src_stride / sizeof(*src_ptr);
}
}
}
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
#endif
{
uint32_t* dst_ptr = (uint32_t*)bb->dst_row + bb->dst_x;
uint32_t* src_ptr = (uint32_t*)bb->src_row + bb->src_x;
uint16_t height = bb->height;
while (height-- > 0) {
for (int x = 0; x < bb->width; x++) {
dst_ptr[x] = src_ptr[x];
}
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
src_ptr += bb->src_stride / sizeof(*src_ptr);
}
}
}
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
#endif
{
uint32_t* dst_ptr = (uint32_t*)bb->dst_row + bb->dst_x;
uint8_t* src_row = (uint8_t*)bb->src_row;
uint16_t height = bb->height;
while (height-- > 0) {
for (int x = 0; x < bb->width; x++) {
uint8_t fg_data = src_row[(x + bb->src_x) / 2];
uint8_t fg_alpha = (x + bb->src_x) & 1 ? fg_data >> 4 : fg_data & 0x0F;
dst_ptr[x] = gl_color32_blend_a4(
bb->src_fg, gl_color32_to_color(dst_ptr[x]), fg_alpha);
}
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
src_row += bb->src_stride / sizeof(*src_row);
}
}
}

@ -1,120 +0,0 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "gl_dma2d.h"
bool mono8_fill(const dma2d_params_t* dp) {
uint8_t* dst_ptr = (uint8_t*)dp->dst_row + dp->dst_x;
uint16_t height = dp->height;
uint8_t fg = gl_color_lum(dp->src_fg);
while (height-- > 0) {
for (int x = 0; x < dp->width; x++) {
dst_ptr[x] = fg;
}
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
}
return true;
}
bool mono8_copy_mono1p(const dma2d_params_t* dp) {
uint8_t* dst_ptr = (uint8_t*)dp->dst_row + dp->dst_x;
uint8_t* src = (uint8_t*)dp->src_row;
uint16_t src_ofs = dp->src_stride * dp->src_y + dp->src_x;
uint16_t height = dp->height;
uint8_t fg = gl_color_lum(dp->src_fg);
uint8_t bg = gl_color_lum(dp->src_bg);
while (height-- > 0) {
for (int x = 0; x < dp->width; x++) {
uint8_t mask = 1 << (7 - ((src_ofs + x) & 7));
uint8_t data = src[(src_ofs + x) / 8];
dst_ptr[x] = (data & mask) ? fg : bg;
}
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
src_ofs += dp->src_stride;
}
return true;
}
bool mono8_copy_mono4(const dma2d_params_t* dp) {
uint8_t* dst_ptr = (uint8_t*)dp->dst_row + dp->dst_x;
uint8_t* src_row = (uint8_t*)dp->src_row;
uint16_t height = dp->height;
uint8_t fg = gl_color_lum(dp->src_fg);
uint8_t bg = gl_color_lum(dp->src_bg);
while (height-- > 0) {
for (int x = 0; x < dp->width; x++) {
uint8_t src_data = src_row[(x + dp->src_x) / 2];
uint8_t src_lum = (x + dp->src_x) & 1 ? src_data >> 4 : src_data & 0xF;
dst_ptr[x] = (fg * src_lum + bg * (15 - src_lum)) / 15;
}
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
src_row += dp->src_stride / sizeof(*src_row);
}
return true;
}
bool mono8_blend_mono1p(const dma2d_params_t* dp) {
uint8_t* dst_ptr = (uint8_t*)dp->dst_row + dp->dst_x;
uint8_t* src = (uint8_t*)dp->src_row;
uint16_t src_ofs = dp->src_stride * dp->src_y + dp->src_x;
uint16_t height = dp->height;
uint8_t fg = gl_color_lum(dp->src_fg);
while (height-- > 0) {
for (int x = 0; x < dp->width; x++) {
uint8_t mask = 1 << (7 - ((src_ofs + x) & 7));
uint8_t data = src[(src_ofs + x) / 8];
dst_ptr[x] = (data & mask) ? fg : dst_ptr[x];
}
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
src_ofs += dp->src_stride;
}
return true;
}
bool mono8_blend_mono4(const dma2d_params_t* dp) {
uint8_t* dst_ptr = (uint8_t*)dp->dst_row + dp->dst_x;
uint8_t* src_row = (uint8_t*)dp->src_row;
uint16_t height = dp->height;
uint8_t fg = gl_color_lum(dp->src_fg);
while (height-- > 0) {
for (int x = 0; x < dp->width; x++) {
uint8_t src_data = src_row[(x + dp->src_x) / 2];
uint8_t src_alpha = (x + dp->src_x) & 1 ? src_data >> 4 : src_data & 0x0F;
dst_ptr[x] = (fg * src_alpha + dst_ptr[x] * (15 - src_alpha)) / 15;
}
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
src_row += dp->src_stride / sizeof(*src_row);
}
return true;
}

@ -1,131 +0,0 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "gl_dma2d.h"
#if USE_DMA2D
#include "dma2d.h"
#endif
bool rgb565_fill(const dma2d_params_t* dp) {
#if defined(USE_DMA2D) && !defined(TREZOR_EMULATOR)
if (dma2d_accessible(dp->dst_row)) {
return dma2d_rgb565_fill(dp);
} else
#endif
{
uint16_t* dst_ptr = (uint16_t*)dp->dst_row + dp->dst_x;
uint16_t height = dp->height;
if (dp->src_alpha == 255) {
while (height-- > 0) {
for (int x = 0; x < dp->width; x++) {
dst_ptr[x] = dp->src_fg;
}
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
}
} else {
uint8_t alpha = dp->src_alpha;
while (height-- > 0) {
for (int x = 0; x < dp->width; x++) {
dst_ptr[x] = gl_color16_blend_a8(dp->src_fg, dst_ptr[x], alpha);
}
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
}
}
return true;
}
}
bool rgb565_copy_mono4(const dma2d_params_t* dp) {
#if defined(USE_DMA2D) && !defined(TREZOR_EMULATOR)
if (dma2d_accessible(dp->dst_row) && dma2d_accessible(dp->src_row)) {
return dma2d_rgb565_copy_mono4(dp);
} else
#endif
{
const gl_color16_t* gradient =
gl_color16_gradient_a4(dp->src_fg, dp->src_bg);
uint16_t* dst_ptr = (uint16_t*)dp->dst_row + dp->dst_x;
uint8_t* src_row = (uint8_t*)dp->src_row;
uint16_t height = dp->height;
while (height-- > 0) {
for (int x = 0; x < dp->width; x++) {
uint8_t fg_data = src_row[(x + dp->src_x) / 2];
uint8_t fg_lum = (x + dp->src_x) & 1 ? fg_data >> 4 : fg_data & 0xF;
dst_ptr[x] = gradient[fg_lum];
}
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
src_row += dp->src_stride / sizeof(*src_row);
}
return true;
}
}
bool rgb565_copy_rgb565(const dma2d_params_t* dp) {
#if defined(USE_DMA2D) && !defined(TREZOR_EMULATOR)
if (dma2d_accessible(dp->dst_row) && dma2d_accessible(dp->src_row)) {
return dma2d_rgb565_copy_rgb565(dp);
} else
#endif
{
uint16_t* dst_ptr = (uint16_t*)dp->dst_row + dp->dst_x;
uint16_t* src_ptr = (uint16_t*)dp->src_row + dp->src_x;
uint16_t height = dp->height;
while (height-- > 0) {
for (int x = 0; x < dp->width; x++) {
dst_ptr[x] = src_ptr[x];
}
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
src_ptr += dp->src_stride / sizeof(*src_ptr);
}
return true;
}
}
bool rgb565_blend_mono4(const dma2d_params_t* dp) {
#if defined(USE_DMA2D) && !defined(TREZOR_EMULATOR)
if (dma2d_accessible(dp->dst_row) && dma2d_accessible(dp->src_row)) {
return dma2d_rgb565_blend_mono4(dp);
} else
#endif
{
uint16_t* dst_ptr = (uint16_t*)dp->dst_row + dp->dst_x;
uint8_t* src_row = (uint8_t*)dp->src_row;
uint16_t height = dp->height;
while (height-- > 0) {
for (int x = 0; x < dp->width; x++) {
uint8_t fg_data = src_row[(x + dp->src_x) / 2];
uint8_t fg_alpha = (x + dp->src_x) & 1 ? fg_data >> 4 : fg_data & 0x0F;
dst_ptr[x] = gl_color16_blend_a4(
dp->src_fg, gl_color16_to_color(dst_ptr[x]), fg_alpha);
}
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
src_row += dp->src_stride / sizeof(*src_row);
}
return true;
}
}

@ -1,155 +0,0 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "gl_dma2d.h"
#if USE_DMA2D
#include "dma2d.h"
#endif
bool rgba8888_fill(const dma2d_params_t* dp) {
#if defined(USE_DMA2D) && !defined(TREZOR_EMULATOR)
if (dma2d_accessible(dp->dst_row)) {
return dma2d_rgba8888_fill(dp);
} else
#endif
{
uint32_t* dst_ptr = (uint32_t*)dp->dst_row + dp->dst_x;
uint16_t height = dp->height;
if (dp->src_alpha == 255) {
while (height-- > 0) {
for (int x = 0; x < dp->width; x++) {
dst_ptr[x] = gl_color_to_color32(dp->src_fg);
}
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
}
} else {
uint8_t alpha = dp->src_alpha;
while (height-- > 0) {
for (int x = 0; x < dp->width; x++) {
dst_ptr[x] = gl_color32_blend_a8(
dp->src_fg, gl_color32_to_color(dst_ptr[x]), alpha);
}
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
}
}
return true;
}
}
bool rgba8888_copy_mono4(const dma2d_params_t* dp) {
#if defined(USE_DMA2D) && !defined(TREZOR_EMULATOR)
if (dma2d_accessible(dp->dst_row) && dma2d_accessible(dp->src_row)) {
return dma2d_rgba8888_copy_mono4(dp);
} else
#endif
{
const gl_color32_t* gradient =
gl_color32_gradient_a4(dp->src_fg, dp->src_bg);
uint32_t* dst_ptr = (uint32_t*)dp->dst_row + dp->dst_x;
uint8_t* src_row = (uint8_t*)dp->src_row;
uint16_t height = dp->height;
while (height-- > 0) {
for (int x = 0; x < dp->width; x++) {
uint8_t fg_data = src_row[(x + dp->src_x) / 2];
uint8_t fg_lum = (x + dp->src_x) & 1 ? fg_data >> 4 : fg_data & 0xF;
dst_ptr[x] = gradient[fg_lum];
}
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
src_row += dp->src_stride / sizeof(*src_row);
}
return true;
}
}
bool rgba8888_copy_rgb565(const dma2d_params_t* dp) {
#if defined(USE_DMA2D) && !defined(TREZOR_EMULATOR)
if (dma2d_accessible(dp->dst_row) && dma2d_accessible(dp->src_row)) {
return dma2d_rgba8888_copy_rgb565(dp);
} else
#endif
{
uint32_t* dst_ptr = (uint32_t*)dp->dst_row + dp->dst_x;
uint16_t* src_ptr = (uint16_t*)dp->src_row + dp->src_x;
uint16_t height = dp->height;
while (height-- > 0) {
for (int x = 0; x < dp->width; x++) {
dst_ptr[x] = gl_color16_to_color32(src_ptr[x]);
}
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
src_ptr += dp->src_stride / sizeof(*src_ptr);
}
return true;
}
}
bool rgba8888_copy_rgba8888(const dma2d_params_t* dp) {
#if defined(USE_DMA2D) && !defined(TREZOR_EMULATOR)
if (dma2d_accessible(dp->dst_row) && dma2d_accessible(dp->src_row)) {
return dma2d_rgba8888_copy_rgba8888(dp);
} else
#endif
{
uint32_t* dst_ptr = (uint32_t*)dp->dst_row + dp->dst_x;
uint32_t* src_ptr = (uint32_t*)dp->src_row + dp->src_x;
uint16_t height = dp->height;
while (height-- > 0) {
for (int x = 0; x < dp->width; x++) {
dst_ptr[x] = src_ptr[x];
}
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
src_ptr += dp->src_stride / sizeof(*src_ptr);
}
return true;
}
}
bool rgba8888_blend_mono4(const dma2d_params_t* dp) {
#if defined(USE_DMA2D) && !defined(TREZOR_EMULATOR)
if (dma2d_accessible(dp->dst_row) && dma2d_accessible(dp->src_row)) {
return dma2d_rgba8888_blend_mono4(dp);
} else
#endif
{
uint32_t* dst_ptr = (uint32_t*)dp->dst_row + dp->dst_x;
uint8_t* src_row = (uint8_t*)dp->src_row;
uint16_t height = dp->height;
while (height-- > 0) {
for (int x = 0; x < dp->width; x++) {
uint8_t fg_data = src_row[(x + dp->src_x) / 2];
uint8_t fg_alpha = (x + dp->src_x) & 1 ? fg_data >> 4 : fg_data & 0x0F;
dst_ptr[x] = gl_color32_blend_a4(
dp->src_fg, gl_color32_to_color(dst_ptr[x]), fg_alpha);
}
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
src_row += dp->src_stride / sizeof(*src_row);
}
return true;
}
}

@ -89,7 +89,7 @@ static inline gl_clip_t gl_clip(gl_rect_t dst, const gl_bitmap_t* bitmap) {
}
void gl_clear(void) {
dma2d_params_t dp = {
gl_bitblt_t bb = {
// Destination bitmap
.height = DISPLAY_RESX,
.width = DISPLAY_RESY,
@ -103,7 +103,7 @@ void gl_clear(void) {
.src_alpha = 255,
};
display_fill(&dp);
display_fill(&bb);
}
void gl_draw_bar(gl_rect_t rect, gl_color_t color) {
@ -113,7 +113,7 @@ void gl_draw_bar(gl_rect_t rect, gl_color_t color) {
return;
}
dma2d_params_t dp = {
gl_bitblt_t bb = {
// Destination bitmap
.height = clip.height,
.width = clip.width,
@ -127,7 +127,7 @@ void gl_draw_bar(gl_rect_t rect, gl_color_t color) {
.src_alpha = 255,
};
display_fill(&dp);
display_fill(&bb);
}
void gl_draw_bitmap(gl_rect_t rect, const gl_bitmap_t* bitmap) {
@ -137,7 +137,7 @@ void gl_draw_bitmap(gl_rect_t rect, const gl_bitmap_t* bitmap) {
return;
}
dma2d_params_t dp = {
gl_bitblt_t bb = {
// Destination bitmap
.height = clip.height,
.width = clip.width,
@ -158,12 +158,12 @@ void gl_draw_bitmap(gl_rect_t rect, const gl_bitmap_t* bitmap) {
#if TREZOR_FONT_BPP == 1
if (bitmap->format == GL_FORMAT_MONO1P) {
display_copy_mono1p(&dp);
display_copy_mono1p(&bb);
}
#endif
#if TREZOR_FONT_BPP == 4
if (bitmap->format == GL_FORMAT_MONO4) {
display_copy_mono4(&dp);
display_copy_mono4(&bb);
}
#endif
}

@ -69,7 +69,7 @@ static uint64_t term_glyph_bits(char ch) {
// Redraws specified rows to the display
static void term_redraw_rows(int start_row, int row_count) {
uint64_t glyph_bits = 0;
dma2d_params_t dp = {
gl_bitblt_t bb = {
.height = 8,
.width = 6,
.dst_row = NULL,
@ -86,11 +86,11 @@ static void term_redraw_rows(int start_row, int row_count) {
};
for (int y = start_row; y < start_row + row_count; y++) {
dp.dst_y = y * 8;
bb.dst_y = y * 8;
for (int x = 0; x < TERMINAL_COLS; x++) {
glyph_bits = term_glyph_bits(terminal_fb[y][x]);
dp.dst_x = x * 6;
display_copy_mono1p(&dp);
bb.dst_x = x * 6;
display_copy_mono1p(&bb);
}
}
}

@ -353,21 +353,21 @@ fn generate_trezorhal_bindings() {
.allowlist_function("display_fill")
.allowlist_function("display_copy_rgb565")
// dma2d
.allowlist_type("dma2d_params_t")
.allowlist_function("rgb565_fill")
.allowlist_function("rgb565_copy_mono4")
.allowlist_function("rgb565_copy_rgb565")
.allowlist_function("rgb565_blend_mono4")
.allowlist_function("rgba8888_fill")
.allowlist_function("rgba8888_copy_mono4")
.allowlist_function("rgba8888_copy_rgb565")
.allowlist_function("rgba8888_copy_rgba8888")
.allowlist_function("rgba8888_blend_mono4")
.allowlist_function("mono8_fill")
.allowlist_function("mono8_copy_mono1p")
.allowlist_function("mono8_copy_mono4")
.allowlist_function("mono8_blend_mono1p")
.allowlist_function("mono8_blend_mono4")
.allowlist_type("gl_bitblt_t")
.allowlist_function("gl_rgb565_fill")
.allowlist_function("gl_rgb565_copy_mono4")
.allowlist_function("gl_rgb565_copy_rgb565")
.allowlist_function("gl_rgb565_blend_mono4")
.allowlist_function("gl_rgba8888_fill")
.allowlist_function("gl_rgba8888_copy_mono4")
.allowlist_function("gl_rgba8888_copy_rgb565")
.allowlist_function("gl_rgba8888_copy_rgba8888")
.allowlist_function("gl_rgba8888_blend_mono4")
.allowlist_function("gl_mono8_fill")
.allowlist_function("gl_mono8_copy_mono1p")
.allowlist_function("gl_mono8_copy_mono4")
.allowlist_function("gl_mono8_blend_mono1p")
.allowlist_function("gl_mono8_blend_mono4")
// fonts
.allowlist_function("font_height")
.allowlist_function("font_max_height")

@ -6,9 +6,9 @@ use crate::ui::{
shape::{Bitmap, BitmapFormat, BitmapView},
};
pub type Dma2d = ffi::dma2d_params_t;
pub type BitBlt = ffi::gl_bitblt_t;
impl Default for Dma2d {
impl Default for BitBlt {
fn default() -> Self {
Self {
width: 0,
@ -28,7 +28,7 @@ impl Default for Dma2d {
}
}
impl Dma2d {
impl BitBlt {
pub fn new_fill(r: Rect, clip: Rect, color: Color, alpha: u8) -> Option<Self> {
let r = r.clamp(clip);
if !r.is_empty() {
@ -76,7 +76,7 @@ impl Dma2d {
if !r.is_empty() {
Some(
Dma2d::default()
BitBlt::default()
.with_rect(r)
.with_src(src.bitmap, offset.x, offset.y)
.with_bg(src.bg_color)
@ -149,59 +149,59 @@ impl Dma2d {
}
pub unsafe fn rgb565_fill(&self) {
unsafe { ffi::rgb565_fill(self) };
unsafe { ffi::gl_rgb565_fill(self) };
}
pub unsafe fn rgb565_copy_mono4(&self) {
unsafe { ffi::rgb565_copy_mono4(self) };
unsafe { ffi::gl_rgb565_copy_mono4(self) };
}
pub unsafe fn rgb565_copy_rgb565(&self) {
unsafe { ffi::rgb565_copy_rgb565(self) };
unsafe { ffi::gl_rgb565_copy_rgb565(self) };
}
pub unsafe fn rgb565_blend_mono4(&self) {
unsafe { ffi::rgb565_blend_mono4(self) };
unsafe { ffi::gl_rgb565_blend_mono4(self) };
}
pub unsafe fn rgba8888_fill(&self) {
unsafe { ffi::rgba8888_fill(self) };
unsafe { ffi::gl_rgba8888_fill(self) };
}
pub unsafe fn rgba8888_copy_mono4(&self) {
unsafe { ffi::rgba8888_copy_mono4(self) };
unsafe { ffi::gl_rgba8888_copy_mono4(self) };
}
pub unsafe fn rgba8888_copy_rgb565(&self) {
unsafe { ffi::rgba8888_copy_rgb565(self) };
unsafe { ffi::gl_rgba8888_copy_rgb565(self) };
}
pub unsafe fn rgba8888_copy_rgba8888(&self) {
unsafe { ffi::rgba8888_copy_rgba8888(self) };
unsafe { ffi::gl_rgba8888_copy_rgba8888(self) };
}
pub unsafe fn rgba8888_blend_mono4(&self) {
unsafe { ffi::rgba8888_blend_mono4(self) };
unsafe { ffi::gl_rgba8888_blend_mono4(self) };
}
pub unsafe fn mono8_fill(&self) {
unsafe { ffi::mono8_fill(self) };
unsafe { ffi::gl_mono8_fill(self) };
}
pub unsafe fn mono8_copy_mono1p(&self) {
unsafe { ffi::mono8_copy_mono1p(self) };
unsafe { ffi::gl_mono8_copy_mono1p(self) };
}
pub unsafe fn mono8_copy_mono4(&self) {
unsafe { ffi::mono8_copy_mono4(self) };
unsafe { ffi::gl_mono8_copy_mono4(self) };
}
pub unsafe fn mono8_blend_mono1p(&self) {
unsafe { ffi::mono8_blend_mono1p(self) };
unsafe { ffi::gl_mono8_blend_mono1p(self) };
}
pub unsafe fn mono8_blend_mono4(&self) {
unsafe { ffi::mono8_blend_mono4(self) };
unsafe { ffi::gl_mono8_blend_mono4(self) };
}
#[cfg(feature = "new_rendering")]

@ -2,11 +2,11 @@ pub mod bip39;
#[macro_use]
#[allow(unused_macros)]
pub mod fatal_error;
pub mod bitblt;
#[cfg(feature = "ui")]
pub mod display;
#[cfg(feature = "dma2d")]
pub mod dma2d;
pub mod dma2d_new;
mod ffi;
#[cfg(feature = "haptic")]
pub mod haptic;

@ -184,9 +184,9 @@ impl Homescreen {
notification.map(|c| {
shape::Text::new(baseline, c)
.with_align(Alignment::Center)
.with_font(NOTIFICATION_FONT)
.render(target)
.with_align(Alignment::Center)
.with_font(NOTIFICATION_FONT)
.render(target)
});
// Painting warning icons in top corners when the text is short enough not to

@ -1,4 +1,4 @@
use crate::trezorhal::dma2d_new::Dma2d;
use crate::trezorhal::bitblt::BitBlt;
use crate::ui::{display::Color, geometry::Offset};
@ -231,7 +231,7 @@ impl<'a> Bitmap<'a> {
/// Waits until DMA operation is finished
fn wait_for_dma(&self) {
if self.dma_pending.get() {
Dma2d::wait_for_transfer();
BitBlt::wait_for_transfer();
self.dma_pending.set(false);
}
}

@ -1,6 +1,6 @@
use super::{Bitmap, BitmapFormat, BitmapView};
use crate::{
trezorhal::dma2d_new::Dma2d,
trezorhal::bitblt::BitBlt,
ui::{display::Color, geometry::Rect},
};
@ -10,9 +10,9 @@ impl<'a> Bitmap<'a> {
/// The function is aplicable only on bitmaps with RGB565 format.
pub fn mono8_fill(&mut self, r: Rect, clip: Rect, color: Color, alpha: u8) {
assert!(self.format() == BitmapFormat::MONO8);
if let Some(dma2d) = Dma2d::new_fill(r, clip, color, alpha) {
let dma2d = dma2d.with_dst(self);
unsafe { dma2d.mono8_fill() };
if let Some(bitblt) = BitBlt::new_fill(r, clip, color, alpha) {
let bitblt = bitblt.with_dst(self);
unsafe { bitblt.mono8_fill() };
self.mark_dma_pending();
}
}
@ -20,11 +20,11 @@ impl<'a> Bitmap<'a> {
//
pub fn mono8_copy(&mut self, r: Rect, clip: Rect, src: &BitmapView) {
assert!(self.format() == BitmapFormat::MONO8);
if let Some(dma2d) = Dma2d::new_copy(r, clip, src) {
let dma2d = dma2d.with_dst(self);
if let Some(bitblt) = BitBlt::new_copy(r, clip, src) {
let bitblt = bitblt.with_dst(self);
match src.format() {
BitmapFormat::MONO1P => unsafe { dma2d.mono8_copy_mono1p() },
BitmapFormat::MONO4 => unsafe { dma2d.mono8_copy_mono4() },
BitmapFormat::MONO1P => unsafe { bitblt.mono8_copy_mono1p() },
BitmapFormat::MONO4 => unsafe { bitblt.mono8_copy_mono4() },
_ => panic!("Unsupported DMA operation"),
}
self.mark_dma_pending();
@ -34,11 +34,11 @@ impl<'a> Bitmap<'a> {
pub fn mono8_blend(&mut self, r: Rect, clip: Rect, src: &BitmapView) {
assert!(self.format() == BitmapFormat::MONO8);
if let Some(dma2d) = Dma2d::new_copy(r, clip, src) {
let dma2d = dma2d.with_dst(self);
if let Some(bitblt) = BitBlt::new_copy(r, clip, src) {
let bitblt = bitblt.with_dst(self);
match src.format() {
BitmapFormat::MONO1P => unsafe { dma2d.mono8_blend_mono1p() },
BitmapFormat::MONO4 => unsafe { dma2d.mono8_blend_mono4() },
BitmapFormat::MONO1P => unsafe { bitblt.mono8_blend_mono1p() },
BitmapFormat::MONO4 => unsafe { bitblt.mono8_blend_mono4() },
_ => panic!("Unsupported DMA operation"),
}
self.mark_dma_pending();

@ -1,6 +1,6 @@
use super::{Bitmap, BitmapFormat, BitmapView};
use crate::{
trezorhal::dma2d_new::Dma2d,
trezorhal::bitblt::BitBlt,
ui::{display::Color, geometry::Rect},
};
@ -10,9 +10,9 @@ impl<'a> Bitmap<'a> {
/// The function is aplicable only on bitmaps with RGB565 format.
pub fn rgb565_fill(&mut self, r: Rect, clip: Rect, color: Color, alpha: u8) {
assert!(self.format() == BitmapFormat::RGB565);
if let Some(dma2d) = Dma2d::new_fill(r, clip, color, alpha) {
let dma2d = dma2d.with_dst(self);
unsafe { dma2d.rgb565_fill() };
if let Some(bitblt) = BitBlt::new_fill(r, clip, color, alpha) {
let bitblt = bitblt.with_dst(self);
unsafe { bitblt.rgb565_fill() };
self.mark_dma_pending();
}
}
@ -20,11 +20,11 @@ impl<'a> Bitmap<'a> {
//
pub fn rgb565_copy(&mut self, r: Rect, clip: Rect, src: &BitmapView) {
assert!(self.format() == BitmapFormat::RGB565);
if let Some(dma2d) = Dma2d::new_copy(r, clip, src) {
let dma2d = dma2d.with_dst(self);
if let Some(bitblt) = BitBlt::new_copy(r, clip, src) {
let bitblt = bitblt.with_dst(self);
match src.format() {
BitmapFormat::MONO4 => unsafe { dma2d.rgb565_copy_mono4() },
BitmapFormat::RGB565 => unsafe { dma2d.rgb565_copy_rgb565() },
BitmapFormat::MONO4 => unsafe { bitblt.rgb565_copy_mono4() },
BitmapFormat::RGB565 => unsafe { bitblt.rgb565_copy_rgb565() },
_ => panic!("Unsupported DMA operation"),
}
self.mark_dma_pending();
@ -34,10 +34,10 @@ impl<'a> Bitmap<'a> {
pub fn rgb565_blend(&mut self, r: Rect, clip: Rect, src: &BitmapView) {
assert!(self.format() == BitmapFormat::RGB565);
if let Some(dma2d) = Dma2d::new_copy(r, clip, src) {
let dma2d = dma2d.with_dst(self);
if let Some(bitblt) = BitBlt::new_copy(r, clip, src) {
let bitblt = bitblt.with_dst(self);
match src.format() {
BitmapFormat::MONO4 => unsafe { dma2d.rgb565_blend_mono4() },
BitmapFormat::MONO4 => unsafe { bitblt.rgb565_blend_mono4() },
_ => panic!("Unsupported DMA operation"),
}
self.mark_dma_pending();

@ -1,6 +1,6 @@
use super::{Bitmap, BitmapFormat, BitmapView};
use crate::{
trezorhal::dma2d_new::Dma2d,
trezorhal::bitblt::BitBlt,
ui::{display::Color, geometry::Rect},
};
@ -10,21 +10,21 @@ impl<'a> Bitmap<'a> {
/// The function is aplicable only on bitmaps with RGBA888 format.
pub fn rgba8888_fill(&mut self, r: Rect, clip: Rect, color: Color, alpha: u8) {
assert!(self.format() == BitmapFormat::RGBA8888);
if let Some(dma2d) = Dma2d::new_fill(r, clip, color, alpha) {
let dma2d = dma2d.with_dst(self);
unsafe { dma2d.rgba8888_fill() };
if let Some(bitblt) = BitBlt::new_fill(r, clip, color, alpha) {
let bitblt = bitblt.with_dst(self);
unsafe { bitblt.rgba8888_fill() };
self.mark_dma_pending();
}
}
pub fn rgba8888_copy(&mut self, r: Rect, clip: Rect, src: &BitmapView) {
assert!(self.format() == BitmapFormat::RGBA8888);
if let Some(dma2d) = Dma2d::new_copy(r, clip, src) {
let dma2d = dma2d.with_dst(self);
if let Some(bitblt) = BitBlt::new_copy(r, clip, src) {
let bitblt = bitblt.with_dst(self);
match src.format() {
BitmapFormat::MONO4 => unsafe { dma2d.rgba8888_copy_mono4() },
BitmapFormat::RGB565 => unsafe { dma2d.rgba8888_copy_rgb565() },
BitmapFormat::RGBA8888 => unsafe { dma2d.rgba8888_copy_rgba8888() },
BitmapFormat::MONO4 => unsafe { bitblt.rgba8888_copy_mono4() },
BitmapFormat::RGB565 => unsafe { bitblt.rgba8888_copy_rgb565() },
BitmapFormat::RGBA8888 => unsafe { bitblt.rgba8888_copy_rgba8888() },
_ => panic!("Unsupported DMA operation"),
}
self.mark_dma_pending();
@ -34,10 +34,10 @@ impl<'a> Bitmap<'a> {
pub fn rgba8888_blend(&mut self, r: Rect, clip: Rect, src: &BitmapView) {
assert!(self.format() == BitmapFormat::RGBA8888);
if let Some(dma2d) = Dma2d::new_copy(r, clip, src) {
let dma2d = dma2d.with_dst(self);
if let Some(bitblt) = BitBlt::new_copy(r, clip, src) {
let bitblt = bitblt.with_dst(self);
match src.format() {
BitmapFormat::MONO4 => unsafe { dma2d.rgba8888_blend_mono4() },
BitmapFormat::MONO4 => unsafe { bitblt.rgba8888_blend_mono4() },
_ => panic!("Unsupported DMA operation"),
}
self.mark_dma_pending();

@ -1,4 +1,4 @@
use crate::trezorhal::{display, dma2d_new::Dma2d};
use crate::trezorhal::{display, bitblt::BitBlt};
use crate::ui::{
display::Color,
@ -76,16 +76,16 @@ impl BasicCanvas for DisplayCanvas {
fn fill_rect(&mut self, r: Rect, color: Color, _alpha: u8) {
let r = r.translate(self.viewport.origin);
if let Some(dma2d) = Dma2d::new_fill(r, self.viewport.clip, color, 255) {
unsafe { dma2d.display_fill() };
if let Some(bitblt) = BitBlt::new_fill(r, self.viewport.clip, color, 255) {
unsafe { bitblt.display_fill() };
}
}
fn draw_bitmap(&mut self, r: Rect, bitmap: BitmapView) {
let r = r.translate(self.viewport.origin);
if let Some(dma2d) = Dma2d::new_copy(r, self.viewport.clip, &bitmap) {
if let Some(bitblt) = BitBlt::new_copy(r, self.viewport.clip, &bitmap) {
match bitmap.format() {
BitmapFormat::RGB565 => unsafe { dma2d.display_copy_rgb565() },
BitmapFormat::RGB565 => unsafe { bitblt.display_copy_rgb565() },
_ => panic!("Unsupported DMA operation"),
}
bitmap.bitmap.mark_dma_pending();

@ -8,7 +8,7 @@
#include "dma2d.h"
#include "flash.h"
#include "fonts/fonts.h"
#include "gl_dma2d.h"
#include "gl_bitblt.h"
#include "haptic.h"
#include "model.h"
#include "rgb_led.h"

@ -24,7 +24,7 @@
#include <stdint.h>
#include "common.h"
#include "gl_dma2d.h"
#include "gl_bitblt.h"
void dma2d_init(void);
@ -45,16 +45,16 @@ void dma2d_start_blend(uint8_t* overlay_addr, uint8_t* bg_addr,
void dma2d_wait_for_transfer(void);
void dma2d_wait(void);
bool dma2d_rgb565_fill(const dma2d_params_t* dp);
bool dma2d_rgb565_copy_mono4(const dma2d_params_t* dp);
bool dma2d_rgb565_copy_rgb565(const dma2d_params_t* dp);
bool dma2d_rgb565_blend_mono4(const dma2d_params_t* dp);
bool dma2d_rgba8888_fill(const dma2d_params_t* dp);
bool dma2d_rgba8888_copy_mono4(const dma2d_params_t* dp);
bool dma2d_rgba8888_copy_rgb565(const dma2d_params_t* dp);
bool dma2d_rgba8888_copy_rgba8888(const dma2d_params_t* dp);
bool dma2d_rgba8888_blend_mono4(const dma2d_params_t* dp);
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);
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_accessible(const void* ptr);

@ -152,68 +152,68 @@ void display_wait_for_sync(void) {
void display_set_compatible_settings(void) { display_panel_set_big_endian(); }
static inline void set_window(const dma2d_params_t* dp) {
display_panel_set_window(dp->dst_x, dp->dst_y, dp->dst_x + dp->width - 1,
dp->dst_y + dp->height + 1);
static inline void set_window(const gl_bitblt_t* bb) {
display_panel_set_window(bb->dst_x, bb->dst_y, bb->dst_x + bb->width - 1,
bb->dst_y + bb->height + 1);
}
void display_fill(const dma2d_params_t* dp) {
set_window(dp);
void display_fill(const gl_bitblt_t* bb) {
set_window(bb);
uint16_t height = dp->height;
uint16_t height = bb->height;
while (height-- > 0) {
for (int x = 0; x < dp->width; x++) {
ISSUE_PIXEL_DATA(dp->src_fg);
for (int x = 0; x < bb->width; x++) {
ISSUE_PIXEL_DATA(bb->src_fg);
}
}
}
void display_copy_rgb565(const dma2d_params_t* dp) {
set_window(dp);
void display_copy_rgb565(const gl_bitblt_t* bb) {
set_window(bb);
uint16_t* src_ptr = (uint16_t*)dp->src_row + dp->src_x;
uint16_t height = dp->height;
uint16_t* src_ptr = (uint16_t*)bb->src_row + bb->src_x;
uint16_t height = bb->height;
while (height-- > 0) {
for (int x = 0; x < dp->width; x++) {
for (int x = 0; x < bb->width; x++) {
ISSUE_PIXEL_DATA(src_ptr[x]);
}
src_ptr += dp->src_stride / sizeof(*src_ptr);
src_ptr += bb->src_stride / sizeof(*src_ptr);
}
}
void display_copy_mono1p(const dma2d_params_t* dp) {
set_window(dp);
void display_copy_mono1p(const gl_bitblt_t* bb) {
set_window(bb);
uint8_t* src = (uint8_t*)dp->src_row;
uint16_t src_ofs = dp->src_stride * dp->src_y + dp->src_x;
uint16_t height = dp->height;
uint8_t* src = (uint8_t*)bb->src_row;
uint16_t src_ofs = bb->src_stride * bb->src_y + bb->src_x;
uint16_t height = bb->height;
while (height-- > 0) {
for (int x = 0; x < dp->width; x++) {
for (int x = 0; x < bb->width; x++) {
uint8_t mask = 1 << (7 - ((src_ofs + x) & 7));
uint8_t data = src[(src_ofs + x) / 8];
ISSUE_PIXEL_DATA((data & mask) ? dp->src_fg : dp->src_bg);
ISSUE_PIXEL_DATA((data & mask) ? bb->src_fg : bb->src_bg);
}
src_ofs += dp->src_stride;
src_ofs += bb->src_stride;
}
}
void display_copy_mono4(const dma2d_params_t* dp) {
set_window(dp);
void display_copy_mono4(const gl_bitblt_t* bb) {
set_window(bb);
const gl_color16_t* gradient = gl_color16_gradient_a4(dp->src_fg, dp->src_bg);
const gl_color16_t* gradient = gl_color16_gradient_a4(bb->src_fg, bb->src_bg);
uint8_t* src_row = (uint8_t*)dp->src_row;
uint16_t height = dp->height;
uint8_t* src_row = (uint8_t*)bb->src_row;
uint16_t height = bb->height;
while (height-- > 0) {
for (int x = 0; x < dp->width; x++) {
uint8_t fg_data = src_row[(x + dp->src_x) / 2];
uint8_t fg_lum = (x + dp->src_x) & 1 ? fg_data >> 4 : fg_data & 0xF;
for (int x = 0; x < bb->width; x++) {
uint8_t fg_data = src_row[(x + bb->src_x) / 2];
uint8_t fg_lum = (x + bb->src_x) & 1 ? fg_data >> 4 : fg_data & 0xF;
ISSUE_PIXEL_DATA(gradient[fg_lum]);
}
src_row += dp->src_stride / sizeof(*src_row);
src_row += bb->src_stride / sizeof(*src_row);
}
}

@ -24,10 +24,10 @@
#include TREZOR_BOARD
#include STM32_HAL_H
#include "xdisplay.h"
#include "display_fb.h"
#include "display_io.h"
#include "display_panel.h"
#include "xdisplay.h"
#include "irq.h"
#include "supervise.h"

@ -113,32 +113,32 @@ void display_refresh(void) {
void display_set_compatible_settings() {}
void display_fill(const dma2d_params_t *dp) {
void display_fill(const gl_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver;
dma2d_params_t dp_new = *dp;
dp_new.dst_row = drv->framebuf + (DISPLAY_RESX * dp_new.dst_y);
dp_new.dst_stride = DISPLAY_RESX * sizeof(uint16_t);
gl_bitblt_t bb_new = *bb;
bb_new.dst_row = drv->framebuf + (DISPLAY_RESX * bb_new.dst_y);
bb_new.dst_stride = DISPLAY_RESX * sizeof(uint16_t);
rgb565_fill(&dp_new);
rgb565_fill(&bb_new);
}
void display_copy_rgb565(const dma2d_params_t *dp) {
void display_copy_rgb565(const gl_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver;
dma2d_params_t dp_new = *dp;
dp_new.dst_row = drv->framebuf + (DISPLAY_RESX * dp_new.dst_y);
dp_new.dst_stride = DISPLAY_RESX * sizeof(uint16_t);
gl_bitblt_t bb_new = *bb;
bb_new.dst_row = drv->framebuf + (DISPLAY_RESX * bb_new.dst_y);
bb_new.dst_stride = DISPLAY_RESX * sizeof(uint16_t);
rgb565_copy_rgb565(&dp_new);
rgb565_copy_rgb565(&bb_new);
}
void display_copy_mono4(const dma2d_params_t *dp) {
void display_copy_mono4(const gl_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver;
dma2d_params_t dp_new = *dp;
dp_new.dst_row = drv->framebuf + (DISPLAY_RESX * dp_new.dst_y);
dp_new.dst_stride = DISPLAY_RESX * sizeof(uint16_t);
gl_bitblt_t bb_new = *bb;
bb_new.dst_row = drv->framebuf + (DISPLAY_RESX * bb_new.dst_y);
bb_new.dst_stride = DISPLAY_RESX * sizeof(uint16_t);
rgb565_copy_mono4(&dp_new);
rgb565_copy_mono4(&bb_new);
}

@ -377,22 +377,22 @@ void display_refresh(void) { display_sync_with_fb(); }
void display_set_compatible_settings() {}
void display_fill(const dma2d_params_t *dp) {
void display_fill(const gl_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver;
dma2d_params_t dp_new = *dp;
dp_new.dst_row = &drv->framebuf[DISPLAY_RESX * dp_new.dst_y];
dp_new.dst_stride = DISPLAY_RESX;
gl_bitblt_t bb_new = *bb;
bb_new.dst_row = &drv->framebuf[DISPLAY_RESX * bb_new.dst_y];
bb_new.dst_stride = DISPLAY_RESX;
mono8_fill(&dp_new);
mono8_fill(&bb_new);
}
void display_copy_mono1p(const dma2d_params_t *dp) {
void display_copy_mono1p(const gl_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver;
dma2d_params_t dp_new = *dp;
dp_new.dst_row = &drv->framebuf[DISPLAY_RESX * dp_new.dst_y];
dp_new.dst_stride = DISPLAY_RESX;
gl_bitblt_t bb_new = *bb;
bb_new.dst_row = &drv->framebuf[DISPLAY_RESX * bb_new.dst_y];
bb_new.dst_stride = DISPLAY_RESX;
mono8_copy_mono1p(&dp_new);
mono8_copy_mono1p(&bb_new);
}

@ -337,22 +337,22 @@ void display_refresh(void) {
void display_set_compatible_settings() {}
void display_fill(const dma2d_params_t *dp) {
void display_fill(const gl_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver;
dma2d_params_t dp_new = *dp;
dp_new.dst_row = &drv->framebuf[DISPLAY_RESX * dp_new.dst_y];
dp_new.dst_stride = DISPLAY_RESX;
gl_bitblt_t bb_new = *bb;
bb_new.dst_row = &drv->framebuf[DISPLAY_RESX * bb_new.dst_y];
bb_new.dst_stride = DISPLAY_RESX;
mono8_fill(&dp_new);
gl_mono8_fill(&bb_new);
}
void display_copy_mono1p(const dma2d_params_t *dp) {
void display_copy_mono1p(const gl_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver;
dma2d_params_t dp_new = *dp;
dp_new.dst_row = &drv->framebuf[DISPLAY_RESX * dp_new.dst_y];
dp_new.dst_stride = DISPLAY_RESX;
gl_bitblt_t bb_new = *bb;
bb_new.dst_row = &drv->framebuf[DISPLAY_RESX * bb_new.dst_y];
bb_new.dst_stride = DISPLAY_RESX;
mono8_copy_mono1p(&dp_new);
gl_mono8_copy_mono1p(&bb_new);
}

@ -21,8 +21,8 @@
#include <stddef.h>
#include "gl_bitblt.h"
#include "gl_color.h"
#include "gl_dma2d.h"
static DMA2D_HandleTypeDef dma2d_handle = {
.Instance = (DMA2D_TypeDef*)DMA2D_BASE,
@ -43,30 +43,30 @@ void dma2d_wait(void) {
;
}
bool dma2d_rgb565_fill(const dma2d_params_t* dp) {
void dma2d_rgb565_fill(const gl_bitblt_t* bb) {
dma2d_wait();
if (dp->src_alpha == 255) {
if (bb->src_alpha == 255) {
dma2d_handle.Init.ColorMode = DMA2D_OUTPUT_RGB565;
dma2d_handle.Init.Mode = DMA2D_R2M;
dma2d_handle.Init.OutputOffset =
dp->dst_stride / sizeof(uint16_t) - dp->width;
bb->dst_stride / sizeof(uint16_t) - bb->width;
HAL_DMA2D_Init(&dma2d_handle);
HAL_DMA2D_Start(&dma2d_handle, gl_color_to_color32(dp->src_fg),
(uint32_t)dp->dst_row + dp->dst_x * sizeof(uint16_t),
dp->width, dp->height);
HAL_DMA2D_Start(&dma2d_handle, gl_color_to_color32(bb->src_fg),
(uint32_t)bb->dst_row + bb->dst_x * sizeof(uint16_t),
bb->width, bb->height);
/*
MODIFY_REG(dma2d_handle.Instance->CR, DMA2D_CR_MODE, DMA2D_R2M);
MODIFY_REG(dma2d_handle.Instance->OPFCCR, DMA2D_OPFCCR_CM,
DMA2D_OUTPUT_RGB565); MODIFY_REG(dma2d_handle.Instance->OOR,
DMA2D_OOR_LO, dp->dst_stride / sizeof(uint16_t) - dp->width);
DMA2D_OOR_LO, bb->dst_stride / sizeof(uint16_t) - bb->width);
MODIFY_REG(dma2d_handle.Instance->NLR, (DMA2D_NLR_NL|DMA2D_NLR_PL),
(dp->height| (dp->width << 16))); WRITE_REG(dma2d_handle.Instance->OMAR,
(uint32_t)dp->dst_row + dp->dst_x * sizeof(uint16_t));
(bb->height| (bb->width << 16))); WRITE_REG(dma2d_handle.Instance->OMAR,
(uint32_t)bb->dst_row + bb->dst_x * sizeof(uint16_t));
WRITE_REG(dma2d_handle.Instance->OCOLR,
gl_color_to_color32(dp->src_fg));
gl_color_to_color32(bb->src_fg));
((dma2d_handle).Instance->CR |= DMA2D_CR_START);
*/
} else {
@ -74,43 +74,41 @@ bool dma2d_rgb565_fill(const dma2d_params_t* dp) {
dma2d_handle.Init.ColorMode = DMA2D_OUTPUT_RGB565;
dma2d_handle.Init.Mode = DMA2D_M2M_BLEND_FG;
dma2d_handle.Init.OutputOffset =
dp->dst_stride / sizeof(uint16_t) - dp->width;
bb->dst_stride / sizeof(uint16_t) - bb->width;
HAL_DMA2D_Init(&dma2d_handle);
dma2d_handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565;
dma2d_handle.LayerCfg[1].InputOffset = 0;
dma2d_handle.LayerCfg[1].AlphaMode = DMA2D_REPLACE_ALPHA;
dma2d_handle.LayerCfg[1].InputAlpha = dp->src_alpha;
dma2d_handle.LayerCfg[1].InputAlpha = bb->src_alpha;
HAL_DMA2D_ConfigLayer(&dma2d_handle, 1);
dma2d_handle.LayerCfg[0].InputColorMode = DMA2D_INPUT_RGB565;
dma2d_handle.LayerCfg[0].InputOffset =
dp->dst_stride / sizeof(uint16_t) - dp->width;
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, gl_color_to_color32(dp->src_fg),
(uint32_t)dp->dst_row + dp->dst_x * sizeof(uint16_t),
(uint32_t)dp->dst_row + dp->dst_x * sizeof(uint16_t), dp->width,
dp->height);
&dma2d_handle, gl_color_to_color32(bb->src_fg),
(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);
#else
// STM32F4 can not accelerate blending with the fixed color
uint16_t* dst_ptr = (uint16_t*)dp->dst_row + dp->dst_x;
uint16_t height = dp->height;
uint8_t alpha = dp->src_alpha;
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 < dp->width; x++) {
for (int x = 0; x < bb->width; x++) {
dst_ptr[x] = gl_color16_blend_a8(
dp->src_fg, gl_color16_to_color(dst_ptr[x]), alpha);
bb->src_fg, gl_color16_to_color(dst_ptr[x]), alpha);
}
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
}
#endif
}
return true;
}
/*
@ -182,453 +180,437 @@ static void dma2d_config_clut(uint32_t layer, gl_color_t fg, gl_color_t bg) {
}
}
static void dma2d_rgb565_copy_mono4_first_col(dma2d_params_t* dp,
static void dma2d_rgb565_copy_mono4_first_col(gl_bitblt_t* bb,
const gl_color16_t* gradient) {
uint16_t* dst_ptr = (uint16_t*)dp->dst_row + dp->dst_x;
uint8_t* src_ptr = (uint8_t*)dp->src_row + dp->src_x / 2;
uint16_t* dst_ptr = (uint16_t*)bb->dst_row + bb->dst_x;
uint8_t* src_ptr = (uint8_t*)bb->src_row + bb->src_x / 2;
int height = dp->height;
int height = bb->height;
while (height-- > 0) {
uint8_t fg_lum = src_ptr[0] >> 4;
dst_ptr[0] = gradient[fg_lum];
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
src_ptr += dp->src_stride / sizeof(*src_ptr);
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
src_ptr += bb->src_stride / sizeof(*src_ptr);
}
}
static void dma2d_rgb565_copy_mono4_last_col(dma2d_params_t* dp,
static void dma2d_rgb565_copy_mono4_last_col(gl_bitblt_t* bb,
const gl_color16_t* gradient) {
uint16_t* dst_ptr = (uint16_t*)dp->dst_row + (dp->dst_x + dp->width - 1);
uint8_t* src_ptr = (uint8_t*)dp->src_row + (dp->src_x + dp->width - 1) / 2;
uint16_t* dst_ptr = (uint16_t*)bb->dst_row + (bb->dst_x + bb->width - 1);
uint8_t* src_ptr = (uint8_t*)bb->src_row + (bb->src_x + bb->width - 1) / 2;
int height = dp->height;
int height = bb->height;
while (height-- > 0) {
uint8_t fg_lum = src_ptr[0] & 0x0F;
dst_ptr[0] = gradient[fg_lum];
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
src_ptr += dp->src_stride / sizeof(*src_ptr);
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
src_ptr += bb->src_stride / sizeof(*src_ptr);
}
}
bool dma2d_rgb565_copy_mono4(const dma2d_params_t* params) {
void dma2d_rgb565_copy_mono4(const gl_bitblt_t* params) {
const gl_color16_t* src_gradient = NULL;
dma2d_params_t dp_copy = *params;
dma2d_params_t* dp = &dp_copy;
gl_bitblt_t bb_copy = *params;
gl_bitblt_t* bb = &bb_copy;
dma2d_wait();
if (dp->src_x & 1) {
if (bb->src_x & 1) {
// First column of mono4 bitmap is odd
// Use the CPU to draw the first column
src_gradient = gl_color16_gradient_a4(dp->src_fg, dp->src_bg);
dma2d_rgb565_copy_mono4_first_col(dp, src_gradient);
dp->dst_x += 1;
dp->src_x += 1;
dp->width -= 1;
src_gradient = gl_color16_gradient_a4(bb->src_fg, bb->src_bg);
dma2d_rgb565_copy_mono4_first_col(bb, src_gradient);
bb->dst_x += 1;
bb->src_x += 1;
bb->width -= 1;
}
if (dp->width > 0 && dp->width & 1) {
if (bb->width > 0 && bb->width & 1) {
// The width is odd
// Use the CPU to draw the last column
if (src_gradient == NULL) {
src_gradient = gl_color16_gradient_a4(dp->src_fg, dp->src_bg);
src_gradient = gl_color16_gradient_a4(bb->src_fg, bb->src_bg);
}
dma2d_rgb565_copy_mono4_last_col(dp, src_gradient);
dp->width -= 1;
dma2d_rgb565_copy_mono4_last_col(bb, src_gradient);
bb->width -= 1;
}
dma2d_handle.Init.ColorMode = DMA2D_OUTPUT_RGB565;
dma2d_handle.Init.Mode = DMA2D_M2M_PFC;
dma2d_handle.Init.OutputOffset =
dp->dst_stride / sizeof(uint16_t) - dp->width;
bb->dst_stride / sizeof(uint16_t) - bb->width;
HAL_DMA2D_Init(&dma2d_handle);
dma2d_handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_L4;
dma2d_handle.LayerCfg[1].InputOffset = dp->src_stride * 2 - dp->width;
dma2d_handle.LayerCfg[1].InputOffset = bb->src_stride * 2 - bb->width;
dma2d_handle.LayerCfg[1].AlphaMode = 0;
dma2d_handle.LayerCfg[1].InputAlpha = 0;
HAL_DMA2D_ConfigLayer(&dma2d_handle, 1);
dma2d_config_clut(1, dp->src_fg, dp->src_bg);
HAL_DMA2D_Start(&dma2d_handle, (uint32_t)dp->src_row + dp->src_x / 2,
(uint32_t)dp->dst_row + dp->dst_x * sizeof(uint16_t),
dp->width, dp->height);
dma2d_config_clut(1, bb->src_fg, bb->src_bg);
return true;
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);
}
bool dma2d_rgb565_copy_rgb565(const dma2d_params_t* dp) {
void dma2d_rgb565_copy_rgb565(const gl_bitblt_t* bb) {
dma2d_wait();
dma2d_handle.Init.ColorMode = DMA2D_OUTPUT_RGB565;
dma2d_handle.Init.Mode = DMA2D_M2M_PFC;
dma2d_handle.Init.OutputOffset =
dp->dst_stride / sizeof(uint16_t) - dp->width;
bb->dst_stride / sizeof(uint16_t) - bb->width;
HAL_DMA2D_Init(&dma2d_handle);
dma2d_handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565;
dma2d_handle.LayerCfg[1].InputOffset =
dp->src_stride / sizeof(uint16_t) - dp->width;
bb->src_stride / sizeof(uint16_t) - bb->width;
dma2d_handle.LayerCfg[1].AlphaMode = 0;
dma2d_handle.LayerCfg[1].InputAlpha = 0;
HAL_DMA2D_ConfigLayer(&dma2d_handle, 1);
HAL_DMA2D_Start(&dma2d_handle,
(uint32_t)dp->src_row + dp->src_x * sizeof(uint16_t),
(uint32_t)dp->dst_row + dp->dst_x * sizeof(uint16_t),
dp->width, dp->height);
return true;
(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);
}
static void dma2d_rgb565_blend_mono4_first_col(const dma2d_params_t* dp) {
uint16_t* dst_ptr = (uint16_t*)dp->dst_row + dp->dst_x;
uint8_t* src_ptr = (uint8_t*)dp->src_row + dp->src_x / 2;
static void dma2d_rgb565_blend_mono4_first_col(const gl_bitblt_t* bb) {
uint16_t* dst_ptr = (uint16_t*)bb->dst_row + bb->dst_x;
uint8_t* src_ptr = (uint8_t*)bb->src_row + bb->src_x / 2;
int height = dp->height;
int height = bb->height;
while (height-- > 0) {
uint8_t fg_alpha = src_ptr[0] >> 4;
dst_ptr[0] = gl_color16_blend_a4(dp->src_fg,
dst_ptr[0] = gl_color16_blend_a4(bb->src_fg,
gl_color16_to_color(dst_ptr[0]), fg_alpha);
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
src_ptr += dp->src_stride / sizeof(*src_ptr);
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
src_ptr += bb->src_stride / sizeof(*src_ptr);
}
}
static void dma2d_rgb565_blend_mono4_last_col(const dma2d_params_t* dp) {
uint16_t* dst_ptr = (uint16_t*)dp->dst_row + (dp->dst_x + dp->width - 1);
uint8_t* src_ptr = (uint8_t*)dp->src_row + (dp->src_x + dp->width - 1) / 2;
static void dma2d_rgb565_blend_mono4_last_col(const gl_bitblt_t* bb) {
uint16_t* dst_ptr = (uint16_t*)bb->dst_row + (bb->dst_x + bb->width - 1);
uint8_t* src_ptr = (uint8_t*)bb->src_row + (bb->src_x + bb->width - 1) / 2;
int height = dp->height;
int height = bb->height;
while (height-- > 0) {
uint8_t fg_alpha = src_ptr[0] & 0x0F;
dst_ptr[0] = gl_color16_blend_a4(dp->src_fg,
dst_ptr[0] = gl_color16_blend_a4(bb->src_fg,
gl_color16_to_color(dst_ptr[0]), fg_alpha);
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
src_ptr += dp->src_stride / sizeof(*src_ptr);
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
src_ptr += bb->src_stride / sizeof(*src_ptr);
}
}
bool dma2d_rgb565_blend_mono4(const dma2d_params_t* params) {
void dma2d_rgb565_blend_mono4(const gl_bitblt_t* params) {
dma2d_wait();
dma2d_params_t dp_copy = *params;
dma2d_params_t* dp = &dp_copy;
gl_bitblt_t bb_copy = *params;
gl_bitblt_t* bb = &bb_copy;
if (dp->src_x & 1) {
if (bb->src_x & 1) {
// First column of mono4 bitmap is odd
// Use the CPU to draw the first column
dma2d_rgb565_blend_mono4_first_col(dp);
dp->dst_x += 1;
dp->src_x += 1;
dp->width -= 1;
dma2d_rgb565_blend_mono4_first_col(bb);
bb->dst_x += 1;
bb->src_x += 1;
bb->width -= 1;
}
if (dp->width > 0 && dp->width & 1) {
if (bb->width > 0 && bb->width & 1) {
// The width is odd
// Use the CPU to draw the last column
dma2d_rgb565_blend_mono4_last_col(dp);
dp->width -= 1;
dma2d_rgb565_blend_mono4_last_col(bb);
bb->width -= 1;
}
if (dp->width > 0) {
if (bb->width > 0) {
dma2d_handle.Init.ColorMode = DMA2D_OUTPUT_RGB565;
dma2d_handle.Init.Mode = DMA2D_M2M_BLEND;
dma2d_handle.Init.OutputOffset =
dp->dst_stride / sizeof(uint16_t) - dp->width;
bb->dst_stride / sizeof(uint16_t) - bb->width;
HAL_DMA2D_Init(&dma2d_handle);
dma2d_handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_A4;
dma2d_handle.LayerCfg[1].InputOffset = dp->src_stride * 2 - dp->width;
dma2d_handle.LayerCfg[1].InputOffset = bb->src_stride * 2 - bb->width;
dma2d_handle.LayerCfg[1].AlphaMode = 0;
dma2d_handle.LayerCfg[1].InputAlpha = gl_color_to_color32(dp->src_fg);
dma2d_handle.LayerCfg[1].InputAlpha = gl_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 =
dp->dst_stride / sizeof(uint16_t) - dp->width;
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)dp->src_row + dp->src_x / 2,
(uint32_t)dp->dst_row + dp->dst_x * sizeof(uint16_t),
(uint32_t)dp->dst_row + dp->dst_x * sizeof(uint16_t), dp->width,
dp->height);
&dma2d_handle, (uint32_t)bb->src_row + bb->src_x / 2,
(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 dma2d_params_t* dp) {
void dma2d_rgba8888_fill(const gl_bitblt_t* bb) {
dma2d_wait();
if (dp->src_alpha == 255) {
if (bb->src_alpha == 255) {
dma2d_handle.Init.ColorMode = DMA2D_OUTPUT_ARGB8888;
dma2d_handle.Init.Mode = DMA2D_R2M;
dma2d_handle.Init.OutputOffset =
dp->dst_stride / sizeof(uint32_t) - dp->width;
bb->dst_stride / sizeof(uint32_t) - bb->width;
HAL_DMA2D_Init(&dma2d_handle);
HAL_DMA2D_Start(&dma2d_handle, gl_color_to_color32(dp->src_fg),
(uint32_t)dp->dst_row + dp->dst_x * sizeof(uint32_t),
dp->width, dp->height);
HAL_DMA2D_Start(&dma2d_handle, gl_color_to_color32(bb->src_fg),
(uint32_t)bb->dst_row + bb->dst_x * sizeof(uint32_t),
bb->width, bb->height);
} else {
#ifdef STM32U5
dma2d_handle.Init.ColorMode = DMA2D_OUTPUT_ARGB8888;
dma2d_handle.Init.Mode = DMA2D_M2M_BLEND_FG;
dma2d_handle.Init.OutputOffset =
dp->dst_stride / sizeof(uint32_t) - dp->width;
bb->dst_stride / sizeof(uint32_t) - bb->width;
HAL_DMA2D_Init(&dma2d_handle);
dma2d_handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_ARGB8888;
dma2d_handle.LayerCfg[1].InputOffset = 0;
dma2d_handle.LayerCfg[1].AlphaMode = DMA2D_REPLACE_ALPHA;
dma2d_handle.LayerCfg[1].InputAlpha = dp->src_alpha;
dma2d_handle.LayerCfg[1].InputAlpha = bb->src_alpha;
HAL_DMA2D_ConfigLayer(&dma2d_handle, 1);
dma2d_handle.LayerCfg[0].InputColorMode = DMA2D_INPUT_ARGB8888;
dma2d_handle.LayerCfg[0].InputOffset =
dp->dst_stride / sizeof(uint32_t) - dp->width;
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, gl_color_to_color32(dp->src_fg),
(uint32_t)dp->dst_row + dp->dst_x * sizeof(uint32_t),
(uint32_t)dp->dst_row + dp->dst_x * sizeof(uint32_t), dp->width,
dp->height);
&dma2d_handle, gl_color_to_color32(bb->src_fg),
(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);
#else
// STM32F4 can not accelerate blending with the fixed color
uint32_t* dst_ptr = (uint32_t*)dp->dst_row + dp->dst_x;
uint16_t height = dp->height;
uint8_t alpha = dp->src_alpha;
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 < dp->width; x++) {
for (int x = 0; x < bb->width; x++) {
dst_ptr[x] = gl_color32_blend_a8(
dp->src_fg, gl_color32_to_color(dst_ptr[x]), alpha);
bb->src_fg, gl_color32_to_color(dst_ptr[x]), alpha);
}
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
}
#endif
}
return true;
}
static void dma2d_rgba8888_copy_mono4_first_col(dma2d_params_t* dp,
static void dma2d_rgba8888_copy_mono4_first_col(gl_bitblt_t* bb,
const gl_color32_t* gradient) {
uint32_t* dst_ptr = (uint32_t*)dp->dst_row + dp->dst_x;
uint8_t* src_ptr = (uint8_t*)dp->src_row + dp->src_x / 2;
uint32_t* dst_ptr = (uint32_t*)bb->dst_row + bb->dst_x;
uint8_t* src_ptr = (uint8_t*)bb->src_row + bb->src_x / 2;
int height = dp->height;
int height = bb->height;
while (height-- > 0) {
uint8_t fg_lum = src_ptr[0] >> 4;
dst_ptr[0] = gradient[fg_lum];
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
src_ptr += dp->src_stride / sizeof(*src_ptr);
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
src_ptr += bb->src_stride / sizeof(*src_ptr);
}
}
static void dma2d_rgba8888_copy_mono4_last_col(dma2d_params_t* dp,
static void dma2d_rgba8888_copy_mono4_last_col(gl_bitblt_t* bb,
const gl_color32_t* gradient) {
uint32_t* dst_ptr = (uint32_t*)dp->dst_row + (dp->dst_x + dp->width - 1);
uint8_t* src_ptr = (uint8_t*)dp->src_row + (dp->src_x + dp->width - 1) / 2;
uint32_t* dst_ptr = (uint32_t*)bb->dst_row + (bb->dst_x + bb->width - 1);
uint8_t* src_ptr = (uint8_t*)bb->src_row + (bb->src_x + bb->width - 1) / 2;
int height = dp->height;
int height = bb->height;
while (height-- > 0) {
uint8_t fg_lum = src_ptr[0] & 0x0F;
dst_ptr[0] = gradient[fg_lum];
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
src_ptr += dp->src_stride / sizeof(*src_ptr);
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
src_ptr += bb->src_stride / sizeof(*src_ptr);
}
}
bool dma2d_rgba8888_copy_mono4(const dma2d_params_t* params) {
void dma2d_rgba8888_copy_mono4(const gl_bitblt_t* params) {
const gl_color32_t* src_gradient = NULL;
dma2d_params_t dp_copy = *params;
dma2d_params_t* dp = &dp_copy;
gl_bitblt_t bb_copy = *params;
gl_bitblt_t* bb = &bb_copy;
dma2d_wait();
if (dp->src_x & 1) {
if (bb->src_x & 1) {
// First column of mono4 bitmap is odd
// Use the CPU to draw the first column
src_gradient = gl_color32_gradient_a4(dp->src_fg, dp->src_bg);
dma2d_rgba8888_copy_mono4_first_col(dp, src_gradient);
dp->dst_x += 1;
dp->src_x += 1;
dp->width -= 1;
src_gradient = gl_color32_gradient_a4(bb->src_fg, bb->src_bg);
dma2d_rgba8888_copy_mono4_first_col(bb, src_gradient);
bb->dst_x += 1;
bb->src_x += 1;
bb->width -= 1;
}
if (dp->width > 0 && dp->width & 1) {
if (bb->width > 0 && bb->width & 1) {
// The width is odd
// Use the CPU to draw the last column
if (src_gradient == NULL) {
src_gradient = gl_color32_gradient_a4(dp->src_fg, dp->src_bg);
src_gradient = gl_color32_gradient_a4(bb->src_fg, bb->src_bg);
}
dma2d_rgba8888_copy_mono4_last_col(dp, src_gradient);
dp->width -= 1;
dma2d_rgba8888_copy_mono4_last_col(bb, src_gradient);
bb->width -= 1;
}
dma2d_handle.Init.ColorMode = DMA2D_OUTPUT_ARGB8888;
dma2d_handle.Init.Mode = DMA2D_M2M_PFC;
dma2d_handle.Init.OutputOffset =
dp->dst_stride / sizeof(uint32_t) - dp->width;
bb->dst_stride / sizeof(uint32_t) - bb->width;
HAL_DMA2D_Init(&dma2d_handle);
dma2d_handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_L4;
dma2d_handle.LayerCfg[1].InputOffset = dp->src_stride * 2 - dp->width;
dma2d_handle.LayerCfg[1].InputOffset = bb->src_stride * 2 - bb->width;
dma2d_handle.LayerCfg[1].AlphaMode = 0;
dma2d_handle.LayerCfg[1].InputAlpha = 0;
HAL_DMA2D_ConfigLayer(&dma2d_handle, 1);
dma2d_config_clut(1, dp->src_fg, dp->src_bg);
HAL_DMA2D_Start(&dma2d_handle, (uint32_t)dp->src_row + dp->src_x / 2,
(uint32_t)dp->dst_row + dp->dst_x * sizeof(uint32_t),
dp->width, dp->height);
dma2d_config_clut(1, bb->src_fg, bb->src_bg);
return true;
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);
}
bool dma2d_rgba8888_copy_rgb565(const dma2d_params_t* dp) {
void dma2d_rgba8888_copy_rgb565(const gl_bitblt_t* bb) {
dma2d_wait();
dma2d_handle.Init.ColorMode = DMA2D_OUTPUT_ARGB8888;
dma2d_handle.Init.Mode = DMA2D_M2M_PFC;
dma2d_handle.Init.OutputOffset =
dp->dst_stride / sizeof(uint32_t) - dp->width;
bb->dst_stride / sizeof(uint32_t) - bb->width;
HAL_DMA2D_Init(&dma2d_handle);
dma2d_handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565;
dma2d_handle.LayerCfg[1].InputOffset =
dp->src_stride / sizeof(uint16_t) - dp->width;
bb->src_stride / sizeof(uint16_t) - bb->width;
dma2d_handle.LayerCfg[1].AlphaMode = 0;
dma2d_handle.LayerCfg[1].InputAlpha = 0;
HAL_DMA2D_ConfigLayer(&dma2d_handle, 1);
HAL_DMA2D_Start(&dma2d_handle,
(uint32_t)dp->src_row + dp->src_x * sizeof(uint16_t),
(uint32_t)dp->dst_row + dp->dst_x * sizeof(uint32_t),
dp->width, dp->height);
return true;
(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);
}
static void dma2d_rgba8888_blend_mono4_first_col(const dma2d_params_t* dp) {
uint32_t* dst_ptr = (uint32_t*)dp->dst_row + dp->dst_x;
uint8_t* src_ptr = (uint8_t*)dp->src_row + dp->src_x / 2;
static void dma2d_rgba8888_blend_mono4_first_col(const gl_bitblt_t* bb) {
uint32_t* dst_ptr = (uint32_t*)bb->dst_row + bb->dst_x;
uint8_t* src_ptr = (uint8_t*)bb->src_row + bb->src_x / 2;
int height = dp->height;
int height = bb->height;
while (height-- > 0) {
uint8_t fg_alpha = src_ptr[0] >> 4;
dst_ptr[0] = gl_color32_blend_a4(dp->src_fg,
dst_ptr[0] = gl_color32_blend_a4(bb->src_fg,
gl_color32_to_color(dst_ptr[0]), fg_alpha);
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
src_ptr += dp->src_stride / sizeof(*src_ptr);
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
src_ptr += bb->src_stride / sizeof(*src_ptr);
}
}
static void dma2d_rgba8888_blend_mono4_last_col(const dma2d_params_t* dp) {
uint32_t* dst_ptr = (uint32_t*)dp->dst_row + (dp->dst_x + dp->width - 1);
uint8_t* src_ptr = (uint8_t*)dp->src_row + (dp->src_x + dp->width - 1) / 2;
static void dma2d_rgba8888_blend_mono4_last_col(const gl_bitblt_t* bb) {
uint32_t* dst_ptr = (uint32_t*)bb->dst_row + (bb->dst_x + bb->width - 1);
uint8_t* src_ptr = (uint8_t*)bb->src_row + (bb->src_x + bb->width - 1) / 2;
int height = dp->height;
int height = bb->height;
while (height-- > 0) {
uint8_t fg_alpha = src_ptr[0] & 0x0F;
dst_ptr[0] = gl_color32_blend_a4(dp->src_fg,
dst_ptr[0] = gl_color32_blend_a4(bb->src_fg,
gl_color32_to_color(dst_ptr[0]), fg_alpha);
dst_ptr += dp->dst_stride / sizeof(*dst_ptr);
src_ptr += dp->src_stride / sizeof(*src_ptr);
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
src_ptr += bb->src_stride / sizeof(*src_ptr);
}
}
bool dma2d_rgba8888_blend_mono4(const dma2d_params_t* params) {
void dma2d_rgba8888_blend_mono4(const gl_bitblt_t* params) {
dma2d_wait();
dma2d_params_t dp_copy = *params;
dma2d_params_t* dp = &dp_copy;
gl_bitblt_t bb_copy = *params;
gl_bitblt_t* bb = &bb_copy;
if (dp->src_x & 1) {
if (bb->src_x & 1) {
// First column of mono4 bitmap is odd
// Use the CPU to draw the first column
dma2d_rgba8888_blend_mono4_first_col(dp);
dp->dst_x += 1;
dp->src_x += 1;
dp->width -= 1;
dma2d_rgba8888_blend_mono4_first_col(bb);
bb->dst_x += 1;
bb->src_x += 1;
bb->width -= 1;
}
if (dp->width > 0 && dp->width & 1) {
if (bb->width > 0 && bb->width & 1) {
// The width is odd
// Use the CPU to draw the last column
dma2d_rgba8888_blend_mono4_last_col(dp);
dp->width -= 1;
dma2d_rgba8888_blend_mono4_last_col(bb);
bb->width -= 1;
}
if (dp->width > 0) {
if (bb->width > 0) {
dma2d_handle.Init.ColorMode = DMA2D_OUTPUT_ARGB8888;
dma2d_handle.Init.Mode = DMA2D_M2M_BLEND;
dma2d_handle.Init.OutputOffset =
dp->dst_stride / sizeof(uint32_t) - dp->width;
bb->dst_stride / sizeof(uint32_t) - bb->width;
HAL_DMA2D_Init(&dma2d_handle);
dma2d_handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_A4;
dma2d_handle.LayerCfg[1].InputOffset = dp->src_stride * 2 - dp->width;
dma2d_handle.LayerCfg[1].InputOffset = bb->src_stride * 2 - bb->width;
dma2d_handle.LayerCfg[1].AlphaMode = 0;
dma2d_handle.LayerCfg[1].InputAlpha = gl_color_to_color32(dp->src_fg);
dma2d_handle.LayerCfg[1].InputAlpha = gl_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 =
dp->dst_stride / sizeof(uint32_t) - dp->width;
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)dp->src_row + dp->src_x / 2,
(uint32_t)dp->dst_row + dp->dst_x * sizeof(uint32_t),
(uint32_t)dp->dst_row + dp->dst_x * sizeof(uint32_t), dp->width,
dp->height);
&dma2d_handle, (uint32_t)bb->src_row + bb->src_x / 2,
(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 dma2d_params_t* dp) {
void dma2d_rgba8888_copy_rgba8888(const gl_bitblt_t* bb) {
dma2d_wait();
dma2d_handle.Init.ColorMode = DMA2D_OUTPUT_ARGB8888;
dma2d_handle.Init.Mode = DMA2D_M2M_PFC;
dma2d_handle.Init.OutputOffset =
dp->dst_stride / sizeof(uint32_t) - dp->width;
bb->dst_stride / sizeof(uint32_t) - bb->width;
HAL_DMA2D_Init(&dma2d_handle);
dma2d_handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_ARGB8888;
dma2d_handle.LayerCfg[1].InputOffset =
dp->src_stride / sizeof(uint32_t) - dp->width;
bb->src_stride / sizeof(uint32_t) - bb->width;
dma2d_handle.LayerCfg[1].AlphaMode = 0;
dma2d_handle.LayerCfg[1].InputAlpha = 0;
HAL_DMA2D_ConfigLayer(&dma2d_handle, 1);
HAL_DMA2D_Start(&dma2d_handle,
(uint32_t)dp->src_row + dp->src_x * sizeof(uint32_t),
(uint32_t)dp->dst_row + dp->dst_x * sizeof(uint32_t),
dp->width, dp->height);
return true;
(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);
}

@ -114,32 +114,32 @@ int display_get_orientation(void) {
void display_set_compatible_settings() {}
void display_fill(const dma2d_params_t *dp) {
void display_fill(const gl_bitblt_t *bb) {
display_fb_info_t fb = display_get_frame_buffer();
dma2d_params_t dp_new = *dp;
dp_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * dp_new.dst_y);
dp_new.dst_stride = fb.stride;
gl_bitblt_t bb_new = *bb;
bb_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * bb_new.dst_y);
bb_new.dst_stride = fb.stride;
rgba8888_fill(&dp_new);
rgba8888_fill(&bb_new);
}
void display_copy_rgb565(const dma2d_params_t *dp) {
void display_copy_rgb565(const gl_bitblt_t *bb) {
display_fb_info_t fb = display_get_frame_buffer();
dma2d_params_t dp_new = *dp;
dp_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * dp_new.dst_y);
dp_new.dst_stride = fb.stride;
gl_bitblt_t bb_new = *bb;
bb_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * bb_new.dst_y);
bb_new.dst_stride = fb.stride;
rgba8888_copy_rgb565(&dp_new);
rgba8888_copy_rgb565(&bb_new);
}
void display_copy_mono4(const dma2d_params_t *dp) {
void display_copy_mono4(const gl_bitblt_t *bb) {
display_fb_info_t fb = display_get_frame_buffer();
dma2d_params_t dp_new = *dp;
dp_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * dp_new.dst_y);
dp_new.dst_stride = fb.stride;
gl_bitblt_t bb_new = *bb;
bb_new.dst_row = (uint8_t *)fb.ptr + (fb.stride * bb_new.dst_y);
bb_new.dst_stride = fb.stride;
rgba8888_copy_mono4(&dp_new);
rgba8888_copy_mono4(&bb_new);
}

@ -0,0 +1 @@
../stm32f4/dma2d_bitblt.c

@ -349,63 +349,64 @@ void display_set_compatible_settings(void) {
#ifndef DISPLAY_MONO
void display_fill(const dma2d_params_t *dp) {
void display_fill(const gl_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver;
dma2d_params_t dp_new = *dp;
dp_new.dst_row =
(uint8_t *)drv->buffer->pixels + (drv->buffer->pitch * dp_new.dst_y);
dp_new.dst_stride = drv->buffer->pitch;
gl_bitblt_t bb_new = *bb;
bb_new.dst_row =
(uint8_t *)drv->buffer->pixels + (drv->buffer->pitch * bb_new.dst_y);
bb_new.dst_stride = drv->buffer->pitch;
rgb565_fill(&dp_new);
gl_rgb565_fill(&bb_new);
}
void display_copy_rgb565(const dma2d_params_t *dp) {
void display_copy_rgb565(const gl_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver;
dma2d_params_t dp_new = *dp;
dp_new.dst_row =
(uint8_t *)drv->buffer->pixels + (drv->buffer->pitch * dp_new.dst_y);
dp_new.dst_stride = drv->buffer->pitch;
gl_bitblt_t bb_new = *bb;
bb_new.dst_row =
(uint8_t *)drv->buffer->pixels + (drv->buffer->pitch * bb_new.dst_y);
bb_new.dst_stride = drv->buffer->pitch;
rgb565_copy_rgb565(&dp_new);
gl_rgb565_copy_rgb565(&bb_new);
}
void display_copy_mono4(const dma2d_params_t *dp) {
void display_copy_mono4(const gl_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver;
dma2d_params_t dp_new = *dp;
dp_new.dst_row =
(uint8_t *)drv->buffer->pixels + (drv->buffer->pitch * dp_new.dst_y);
dp_new.dst_stride = drv->buffer->pitch;
gl_bitblt_t bb_new = *bb;
bb_new.dst_row =
(uint8_t *)drv->buffer->pixels + (drv->buffer->pitch * bb_new.dst_y);
bb_new.dst_stride = drv->buffer->pitch;
rgb565_copy_mono4(&dp_new);
gl_rgb565_copy_mono4(&bb_new);
}
void display_copy_mono1p(const dma2d_params_t *dp) {
// !@# proc to tu musi byt?????
void display_copy_mono1p(const gl_bitblt_t *bb) {
// this function should be removed
// !@# why is it linked?
}
#else // DISPLAY_MONO
void display_fill(const dma2d_params_t *dp) {
void display_fill(const gl_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver;
dma2d_params_t dp_new = *dp;
dp_new.dst_row = drv->mono_framebuf + (DISPLAY_RESX * dp_new.dst_y);
dp_new.dst_stride = DISPLAY_RESX;
gl_bitblt_t bb_new = *bb;
bb_new.dst_row = drv->mono_framebuf + (DISPLAY_RESX * bb_new.dst_y);
bb_new.dst_stride = DISPLAY_RESX;
mono8_fill(&dp_new);
gl_mono8_fill(&bb_new);
}
void display_copy_mono1p(const dma2d_params_t *dp) {
void display_copy_mono1p(const gl_bitblt_t *bb) {
display_driver_t *drv = &g_display_driver;
dma2d_params_t dp_new = *dp;
dp_new.dst_row = drv->mono_framebuf + (DISPLAY_RESX * dp_new.dst_y);
dp_new.dst_stride = DISPLAY_RESX;
gl_bitblt_t bb_new = *bb;
bb_new.dst_row = drv->mono_framebuf + (DISPLAY_RESX * bb_new.dst_y);
bb_new.dst_stride = DISPLAY_RESX;
mono8_copy_mono1p(&dp_new);
gl_mono8_copy_mono1p(&bb_new);
}
#endif

@ -22,7 +22,7 @@
#include <stddef.h>
#include <stdint.h>
#include "gl_dma2d.h"
#include "gl_bitblt.h"
#include TREZOR_BOARD
@ -122,16 +122,16 @@ void display_refresh(void);
void display_set_compatible_settings(void);
// Fills a rectangle with a specified color
void display_fill(const dma2d_params_t *dp);
void display_fill(const gl_bitblt_t *bb);
// Copies an RGB565 bitmap to a specified rectangle
void display_copy_rgb565(const dma2d_params_t *dp);
void display_copy_rgb565(const gl_bitblt_t *bb);
// Copies a MONO4 bitmap to a specified rectangle
void display_copy_mono4(const dma2d_params_t *dp);
void display_copy_mono4(const gl_bitblt_t *bb);
// Copies a MONO1P bitmap to a specified rectangle
void display_copy_mono1p(const dma2d_params_t *dp);
void display_copy_mono1p(const gl_bitblt_t *bb);
#ifdef TREZOR_EMULATOR
// Save the screen content to a file.

@ -49,7 +49,7 @@ def configure(
sources += ["embed/trezorhal/stm32f4/displays/ili9341_spi.c"]
sources += ["embed/trezorhal/stm32f4/dma2d.c"]
sources += ["embed/trezorhal/stm32f4/dma2d_gl.c"]
sources += ["embed/trezorhal/stm32f4/dma2d_bitblt.c"]
sources += [
"vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma2d.c"
]

@ -94,7 +94,7 @@ def configure(
defines += ["USE_DMA2D", "FRAMEBUFFER", "FRAMEBUFFER32BIT"]
sources += [
"embed/trezorhal/stm32u5/dma2d.c",
"embed/trezorhal/stm32u5/dma2d_gl.c",
"embed/trezorhal/stm32u5/dma2d_bitblt.c",
]
features_available.append("dma2d")
features_available.append("framebuffer")

@ -111,7 +111,7 @@ def configure(
if "dma2d" in features_wanted:
defines += ["USE_DMA2D"]
sources += ["embed/trezorhal/stm32f4/dma2d.c"]
sources += ["embed/trezorhal/stm32f4/dma2d_gl.c"]
sources += ["embed/trezorhal/stm32f4/dma2d_bitblt.c"]
sources += [
"vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma2d.c"
]

@ -111,7 +111,7 @@ def configure(
if "dma2d" in features_wanted:
defines += ["USE_DMA2D"]
sources += ["embed/trezorhal/stm32u5/dma2d.c"]
sources += ["embed/trezorhal/stm32u5/dma2d_gl.c"]
sources += ["embed/trezorhal/stm32u5/dma2d_bitblt.c"]
features_available.append("dma2d")
if "optiga" in features_wanted:

@ -113,7 +113,7 @@ def configure(
if "dma2d" in features_wanted:
defines += ["USE_DMA2D"]
sources += ["embed/trezorhal/stm32u5/dma2d.c"]
sources += ["embed/trezorhal/stm32u5/dma2d_gl.c"]
sources += ["embed/trezorhal/stm32u5/dma2d_bitblt.c"]
features_available.append("dma2d")
if "optiga" in features_wanted:

Loading…
Cancel
Save