You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
186 lines
4.7 KiB
186 lines
4.7 KiB
/*
|
|
* 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 "gdc_core.h"
|
|
#include "gdc_clip.h"
|
|
|
|
#include "dma2d.h"
|
|
|
|
void gdc_release(gdc_t* gdc) {
|
|
if (gdc != NULL) {
|
|
gdc_wait_for_pending_ops(gdc);
|
|
|
|
gdc_vmt_t* vmt = *(gdc_vmt_t**)gdc;
|
|
if (vmt != NULL && vmt->release != NULL) {
|
|
vmt->release(gdc);
|
|
}
|
|
}
|
|
}
|
|
|
|
gdc_size_t gdc_get_size(const gdc_t* gdc) {
|
|
if (gdc != NULL) {
|
|
gdc_vmt_t* vmt = *(gdc_vmt_t**)gdc;
|
|
if (vmt != NULL && vmt->get_bitmap != NULL) {
|
|
return vmt->get_bitmap((gdc_t*)gdc)->size;
|
|
}
|
|
}
|
|
|
|
return gdc_size(0, 0);
|
|
}
|
|
|
|
void gdc_wait_for_pending_ops(gdc_t* gdc) {
|
|
#if defined(USE_DMA2D) && !defined(TREZOR_EMULATOR)
|
|
if (gdc != NULL) {
|
|
dma2d_wait();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
bool gdc_fill_rect(gdc_t* gdc, gdc_rect_t rect, gdc_color_t color) {
|
|
if (gdc != NULL) {
|
|
gdc_vmt_t* vmt = *(gdc_vmt_t**)gdc;
|
|
|
|
gdc_bitmap_t* bitmap = (gdc_bitmap_t*)gdc;
|
|
|
|
gdc_clip_t clip = gdc_clip(rect, bitmap->size, NULL);
|
|
|
|
if (clip.width <= 0 || clip.height <= 0) {
|
|
return true;
|
|
}
|
|
|
|
dma2d_params_t dp = {
|
|
// Destination bitmap
|
|
.height = clip.height,
|
|
.width = clip.width,
|
|
.dst_row = (uint8_t*)bitmap->ptr + bitmap->stride * clip.dst_y,
|
|
.dst_x = clip.dst_x,
|
|
.dst_y = clip.dst_y,
|
|
.dst_stride = bitmap->stride,
|
|
|
|
// Source bitmap
|
|
.src_fg = color,
|
|
.src_alpha = 255,
|
|
};
|
|
|
|
gdc_wait_for_pending_ops(gdc);
|
|
|
|
if (vmt->fill != NULL) {
|
|
return vmt->fill(gdc, &dp);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool gdc_draw_bitmap(gdc_t* gdc, gdc_rect_t rect, const gdc_bitmap_ref_t* src) {
|
|
if (gdc != NULL) {
|
|
gdc_vmt_t* vmt = *(gdc_vmt_t**)gdc;
|
|
|
|
gdc_bitmap_t* bitmap = vmt->get_bitmap(gdc);
|
|
|
|
gdc_clip_t clip = gdc_clip(rect, bitmap->size, src);
|
|
|
|
if (clip.width <= 0 || clip.height <= 0) {
|
|
return true;
|
|
}
|
|
|
|
dma2d_params_t dp = {
|
|
// Destination bitmap
|
|
.height = clip.height,
|
|
.width = clip.width,
|
|
.dst_row = (uint8_t*)bitmap->ptr + bitmap->stride * clip.dst_y,
|
|
.dst_x = clip.dst_x,
|
|
.dst_y = clip.dst_y,
|
|
.dst_stride = bitmap->stride,
|
|
|
|
// Source bitmap
|
|
.src_row =
|
|
(uint8_t*)src->bitmap->ptr + src->bitmap->stride * clip.src_y,
|
|
.src_x = clip.src_x,
|
|
.src_y = clip.src_y,
|
|
.src_stride = src->bitmap->stride,
|
|
.src_fg = src->fg_color,
|
|
.src_bg = src->bg_color,
|
|
.src_alpha = 255,
|
|
};
|
|
|
|
gdc_wait_for_pending_ops(gdc);
|
|
|
|
if (src->bitmap->format == GDC_FORMAT_MONO4) {
|
|
if (vmt->copy_mono4 != NULL) {
|
|
return vmt->copy_mono4(gdc, &dp);
|
|
}
|
|
} else if (src->bitmap->format == GDC_FORMAT_RGB565) {
|
|
if (vmt->copy_rgb565 != NULL) {
|
|
return vmt->copy_rgb565(gdc, &dp);
|
|
}
|
|
} else if (src->bitmap->format == GDC_FORMAT_RGBA8888) {
|
|
if (vmt->copy_rgba8888 != NULL) {
|
|
return vmt->copy_rgba8888(gdc, &dp);
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool gdc_draw_blended(gdc_t* gdc, gdc_rect_t rect,
|
|
const gdc_bitmap_ref_t* src) {
|
|
if (gdc != NULL) {
|
|
gdc_vmt_t* vmt = *(gdc_vmt_t**)gdc;
|
|
|
|
gdc_bitmap_t* bitmap = vmt->get_bitmap(gdc);
|
|
|
|
gdc_clip_t clip = gdc_clip(rect, bitmap->size, src);
|
|
|
|
if (clip.width <= 0 || clip.height <= 0) {
|
|
return true;
|
|
}
|
|
|
|
dma2d_params_t dp = {
|
|
// Destination rectangle
|
|
.height = clip.height,
|
|
.width = clip.width,
|
|
.dst_row = (uint8_t*)bitmap->ptr + bitmap->stride * clip.dst_y,
|
|
.dst_x = clip.dst_x,
|
|
.dst_y = clip.dst_y,
|
|
.dst_stride = bitmap->stride,
|
|
|
|
// Source bitmap
|
|
.src_row =
|
|
(uint8_t*)src->bitmap->ptr + src->bitmap->stride * clip.src_y,
|
|
.src_x = clip.src_x,
|
|
.src_y = clip.src_y,
|
|
.src_stride = src->bitmap->stride,
|
|
.src_fg = src->fg_color,
|
|
.src_alpha = 255,
|
|
};
|
|
|
|
gdc_wait_for_pending_ops(gdc);
|
|
|
|
if (src->bitmap->format == GDC_FORMAT_MONO4) {
|
|
if (vmt->blend_mono4 != NULL) {
|
|
return vmt->blend_mono4(gdc, &dp);
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|