mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-02-11 07:02:41 +00:00
feat(core): add simple downscaling for bitmap copy ops
[no changelog]
This commit is contained in:
parent
599b1ea9ea
commit
f3208bb950
@ -125,10 +125,10 @@ void gfx_rgba8888_copy_rgba8888(const gfx_bitblt_t* bb) {
|
|||||||
|
|
||||||
while (height-- > 0) {
|
while (height-- > 0) {
|
||||||
for (int x = 0; x < bb->width; x++) {
|
for (int x = 0; x < bb->width; x++) {
|
||||||
dst_ptr[x] = src_ptr[x];
|
dst_ptr[x] = src_ptr[x << bb->src_downscale];
|
||||||
}
|
}
|
||||||
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
|
dst_ptr += bb->dst_stride / sizeof(*dst_ptr);
|
||||||
src_ptr += bb->src_stride / sizeof(*src_ptr);
|
src_ptr += (bb->src_stride / sizeof(*src_ptr)) << bb->src_downscale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -771,6 +771,10 @@ bool dma2d_rgba8888_copy_rgba8888(const gfx_bitblt_t* bb) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bb->src_downscale > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
drv->handle.Init.ColorMode = DMA2D_OUTPUT_ARGB8888;
|
drv->handle.Init.ColorMode = DMA2D_OUTPUT_ARGB8888;
|
||||||
drv->handle.Init.Mode = DMA2D_M2M_PFC;
|
drv->handle.Init.Mode = DMA2D_M2M_PFC;
|
||||||
drv->handle.Init.OutputOffset = bb->dst_stride / sizeof(uint32_t) - bb->width;
|
drv->handle.Init.OutputOffset = bb->dst_stride / sizeof(uint32_t) - bb->width;
|
||||||
|
@ -72,6 +72,9 @@ typedef struct {
|
|||||||
gfx_color_t src_bg;
|
gfx_color_t src_bg;
|
||||||
// Alpha value for fill operation (255 => normal fill, 0 => noop)
|
// Alpha value for fill operation (255 => normal fill, 0 => noop)
|
||||||
uint8_t src_alpha;
|
uint8_t src_alpha;
|
||||||
|
// Downscaling for the source bitmap
|
||||||
|
// (0 => no downscaling, 1 => 1/2, 2 => 1/4, 3 => 1/8)
|
||||||
|
uint8_t src_downscale;
|
||||||
|
|
||||||
} gfx_bitblt_t;
|
} gfx_bitblt_t;
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ impl Default for ffi::gfx_bitblt_t {
|
|||||||
src_x: 0,
|
src_x: 0,
|
||||||
src_y: 0,
|
src_y: 0,
|
||||||
src_alpha: 255,
|
src_alpha: 255,
|
||||||
|
src_downscale: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,6 +129,15 @@ impl ffi::gfx_bitblt_t {
|
|||||||
..self
|
..self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the downscaling for the source bitmap.
|
||||||
|
/// (0 = no downscale, 1 = 1/2, 2 = 1/4, 3 = 1/8)
|
||||||
|
fn with_downscale(self, downscale: u8) -> Self {
|
||||||
|
Self {
|
||||||
|
src_downscale: downscale,
|
||||||
|
..self
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rectangle filling operation.
|
/// Rectangle filling operation.
|
||||||
@ -250,16 +260,18 @@ impl<'a> BitBltCopy<'a> {
|
|||||||
|
|
||||||
// Clip with the bitmap top-left
|
// Clip with the bitmap top-left
|
||||||
if r.x0 > r_dst.x0 {
|
if r.x0 > r_dst.x0 {
|
||||||
offset.x += r.x0 - r_dst.x0;
|
offset.x += (r.x0 - r_dst.x0) << src.downscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.y0 > r_dst.y0 {
|
if r.y0 > r_dst.y0 {
|
||||||
offset.y += r.y0 - r_dst.y0;
|
offset.y += (r.y0 - r_dst.y0) << src.downscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clip with the bitmap size
|
// Clip with the bitmap size
|
||||||
r.x1 = r.x1.min(r.x0 + src.size().x - offset.x);
|
r.x1 =
|
||||||
r.y1 = r.y1.min(r.y0 + src.size().y - offset.y);
|
r.x1.min(r.x0 + ((src.size().x - offset.x) >> src.downscale));
|
||||||
|
r.y1 =
|
||||||
|
r.y1.min(r.y0 + ((src.size().y - offset.y) >> src.downscale));
|
||||||
|
|
||||||
if !r.is_empty() {
|
if !r.is_empty() {
|
||||||
Some(Self {
|
Some(Self {
|
||||||
@ -280,6 +292,7 @@ impl<'a> BitBltCopy<'a> {
|
|||||||
.with_bg(src.bg_color)
|
.with_bg(src.bg_color)
|
||||||
.with_fg(src.fg_color)
|
.with_fg(src.fg_color)
|
||||||
.with_alpha(src.alpha)
|
.with_alpha(src.alpha)
|
||||||
|
.with_downscale(src.downscale)
|
||||||
},
|
},
|
||||||
src,
|
src,
|
||||||
})
|
})
|
||||||
|
@ -300,6 +300,7 @@ pub struct BitmapView<'a> {
|
|||||||
pub fg_color: Color,
|
pub fg_color: Color,
|
||||||
pub bg_color: Color,
|
pub bg_color: Color,
|
||||||
pub alpha: u8,
|
pub alpha: u8,
|
||||||
|
pub downscale: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> BitmapView<'a> {
|
impl<'a> BitmapView<'a> {
|
||||||
@ -311,6 +312,7 @@ impl<'a> BitmapView<'a> {
|
|||||||
fg_color: Color::black(),
|
fg_color: Color::black(),
|
||||||
bg_color: Color::black(),
|
bg_color: Color::black(),
|
||||||
alpha: 255,
|
alpha: 255,
|
||||||
|
downscale: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,6 +339,12 @@ impl<'a> BitmapView<'a> {
|
|||||||
Self { alpha, ..self }
|
Self { alpha, ..self }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Builds a new structure with downscale set to the specified value
|
||||||
|
/// (0 means no downscale, 1 means 1/2, 2 means 1/4, etc.)
|
||||||
|
pub fn with_downscale(self, downscale: u8) -> Self {
|
||||||
|
Self { downscale, ..self }
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the bitmap width and height in pixels
|
/// Returns the bitmap width and height in pixels
|
||||||
pub fn size(&self) -> Offset {
|
pub fn size(&self) -> Offset {
|
||||||
self.bitmap.size
|
self.bitmap.size
|
||||||
|
@ -108,8 +108,6 @@ impl<'a> Shape<'a> for JpegImage<'a> {
|
|||||||
let bounds = self.bounds();
|
let bounds = self.bounds();
|
||||||
let clip = canvas.viewport().relative_clip(bounds).clip;
|
let clip = canvas.viewport().relative_clip(bounds).clip;
|
||||||
|
|
||||||
let vp = canvas.set_clip(clip);
|
|
||||||
|
|
||||||
// Translate clip to JPEG relative coordinates
|
// Translate clip to JPEG relative coordinates
|
||||||
let clip = clip.translate(-canvas.viewport().origin);
|
let clip = clip.translate(-canvas.viewport().origin);
|
||||||
let clip = clip.translate((-bounds.top_left()).into());
|
let clip = clip.translate((-bounds.top_left()).into());
|
||||||
@ -119,6 +117,13 @@ impl<'a> Shape<'a> for JpegImage<'a> {
|
|||||||
|
|
||||||
let mut jpegdec = unwrap!(JpegDecoder::new(self.jpeg));
|
let mut jpegdec = unwrap!(JpegDecoder::new(self.jpeg));
|
||||||
let _ = jpegdec.decode(&mut buff[..], &mut |slice_r, slice| {
|
let _ = jpegdec.decode(&mut buff[..], &mut |slice_r, slice| {
|
||||||
|
let slice = slice.with_downscale(self.scale);
|
||||||
|
let slice_r = Rect {
|
||||||
|
x0: slice_r.x0 >> self.scale,
|
||||||
|
y0: slice_r.y0 >> self.scale,
|
||||||
|
x1: slice_r.x1 >> self.scale,
|
||||||
|
y1: slice_r.y1 >> self.scale,
|
||||||
|
};
|
||||||
// Draw single slice
|
// Draw single slice
|
||||||
canvas.draw_bitmap(slice_r.translate(bounds.top_left().into()), slice);
|
canvas.draw_bitmap(slice_r.translate(bounds.top_left().into()), slice);
|
||||||
// Return true if we are not done yet
|
// Return true if we are not done yet
|
||||||
@ -136,8 +141,6 @@ impl<'a> Shape<'a> for JpegImage<'a> {
|
|||||||
// Blur the image
|
// Blur the image
|
||||||
canvas.blur_rect(clip, self.blur_radius, cache);
|
canvas.blur_rect(clip, self.blur_radius, cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas.set_viewport(vp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a little bit slower implementation suitable for ProgressiveRenderer
|
// This is a little bit slower implementation suitable for ProgressiveRenderer
|
||||||
|
Loading…
Reference in New Issue
Block a user