|
|
|
@ -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;
|
|
|
|
|
}
|
|
|
|
|