mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-02-10 14:42:44 +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) {
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
if (bb->src_downscale > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
drv->handle.Init.ColorMode = DMA2D_OUTPUT_ARGB8888;
|
||||
drv->handle.Init.Mode = DMA2D_M2M_PFC;
|
||||
drv->handle.Init.OutputOffset = bb->dst_stride / sizeof(uint32_t) - bb->width;
|
||||
|
@ -72,6 +72,9 @@ typedef struct {
|
||||
gfx_color_t src_bg;
|
||||
// Alpha value for fill operation (255 => normal fill, 0 => noop)
|
||||
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;
|
||||
|
||||
|
@ -31,6 +31,7 @@ impl Default for ffi::gfx_bitblt_t {
|
||||
src_x: 0,
|
||||
src_y: 0,
|
||||
src_alpha: 255,
|
||||
src_downscale: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -128,6 +129,15 @@ impl ffi::gfx_bitblt_t {
|
||||
..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.
|
||||
@ -250,16 +260,18 @@ impl<'a> BitBltCopy<'a> {
|
||||
|
||||
// Clip with the bitmap top-left
|
||||
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 {
|
||||
offset.y += r.y0 - r_dst.y0;
|
||||
offset.y += (r.y0 - r_dst.y0) << src.downscale;
|
||||
}
|
||||
|
||||
// Clip with the bitmap size
|
||||
r.x1 = r.x1.min(r.x0 + src.size().x - offset.x);
|
||||
r.y1 = r.y1.min(r.y0 + src.size().y - offset.y);
|
||||
r.x1 =
|
||||
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() {
|
||||
Some(Self {
|
||||
@ -280,6 +292,7 @@ impl<'a> BitBltCopy<'a> {
|
||||
.with_bg(src.bg_color)
|
||||
.with_fg(src.fg_color)
|
||||
.with_alpha(src.alpha)
|
||||
.with_downscale(src.downscale)
|
||||
},
|
||||
src,
|
||||
})
|
||||
|
@ -300,6 +300,7 @@ pub struct BitmapView<'a> {
|
||||
pub fg_color: Color,
|
||||
pub bg_color: Color,
|
||||
pub alpha: u8,
|
||||
pub downscale: u8,
|
||||
}
|
||||
|
||||
impl<'a> BitmapView<'a> {
|
||||
@ -311,6 +312,7 @@ impl<'a> BitmapView<'a> {
|
||||
fg_color: Color::black(),
|
||||
bg_color: Color::black(),
|
||||
alpha: 255,
|
||||
downscale: 0,
|
||||
}
|
||||
}
|
||||
|
||||
@ -337,6 +339,12 @@ impl<'a> BitmapView<'a> {
|
||||
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
|
||||
pub fn size(&self) -> Offset {
|
||||
self.bitmap.size
|
||||
|
@ -108,8 +108,6 @@ impl<'a> Shape<'a> for JpegImage<'a> {
|
||||
let bounds = self.bounds();
|
||||
let clip = canvas.viewport().relative_clip(bounds).clip;
|
||||
|
||||
let vp = canvas.set_clip(clip);
|
||||
|
||||
// Translate clip to JPEG relative coordinates
|
||||
let clip = clip.translate(-canvas.viewport().origin);
|
||||
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 _ = 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
|
||||
canvas.draw_bitmap(slice_r.translate(bounds.top_left().into()), slice);
|
||||
// Return true if we are not done yet
|
||||
@ -136,8 +141,6 @@ impl<'a> Shape<'a> for JpegImage<'a> {
|
||||
// Blur the image
|
||||
canvas.blur_rect(clip, self.blur_radius, cache);
|
||||
}
|
||||
|
||||
canvas.set_viewport(vp);
|
||||
}
|
||||
|
||||
// This is a little bit slower implementation suitable for ProgressiveRenderer
|
||||
|
Loading…
Reference in New Issue
Block a user