diff --git a/core/embed/lib/gfx_color.h b/core/embed/lib/gfx_color.h index 9df362c852..5cbfd9f1ca 100644 --- a/core/embed/lib/gfx_color.h +++ b/core/embed/lib/gfx_color.h @@ -22,8 +22,11 @@ #include +#ifdef UI_COLOR_32BIT +#define GFX_COLOR_32BIT +#else #define GFX_COLOR_16BIT -// #define GFX_COLOR_32BIT +#endif // Color in RGB565 format // @@ -51,7 +54,7 @@ typedef uint32_t gfx_color32_t; #define gfx_color_to_color32(c) (gfx_color16_to_color32(c)) #define gfx_color32_to_color(c) (gfx_color32_to_color16(c)) #define gfx_color_lum(c) (gfx_color16_lum(c)) -#elif GFX_COLOR_32BIT +#elif defined GFX_COLOR_32BIT #define gfx_color_t gfx_color32_t #define gfx_color_to_color16(c) (gfx_color32_to_color16(c)) #define gfx_color16_to_color(c) (gfx_color16_to_color32(c)) @@ -132,7 +135,7 @@ static inline uint8_t gfx_color16_lum(gfx_color16_t color) { } // Converts 32-bit color into luminance (ranging from 0 to 255) -static inline uint8_t gfx_color32_lum(gfx_color16_t color) { +static inline uint8_t gfx_color32_lum(gfx_color32_t color) { uint32_t r = gfx_color32_to_r(color); uint32_t g = gfx_color32_to_g(color); uint32_t b = gfx_color32_to_b(color); @@ -237,7 +240,7 @@ static inline gfx_color32_t gfx_color32_blend_a8(gfx_color16_t fg, return gfx_color32_rgb(r, g, b); } -#elif GFX_COLOR_32BIT +#elif defined GFX_COLOR_32BIT // Blends foreground and background colors with 4-bit alpha // diff --git a/core/embed/rust/Cargo.toml b/core/embed/rust/Cargo.toml index 0cb686ea62..5b7607500c 100644 --- a/core/embed/rust/Cargo.toml +++ b/core/embed/rust/Cargo.toml @@ -27,6 +27,7 @@ ui_antialiasing = [] ui_blurring = [] ui_jpeg_decoder = ["jpeg"] ui_image_buffer = [] +ui_color_32bit = [] new_rendering = [] bootloader = [] button = [] diff --git a/core/embed/rust/src/ui/display/color.rs b/core/embed/rust/src/ui/display/color.rs index 4ad86389ca..0bf42bf15f 100644 --- a/core/embed/rust/src/ui/display/color.rs +++ b/core/embed/rust/src/ui/display/color.rs @@ -1,12 +1,31 @@ use crate::ui::lerp::Lerp; +#[cfg(not(feature = "ui_color_32bit"))] #[derive(Copy, Clone, PartialEq, Eq)] pub struct Color(u16); +#[cfg(feature = "ui_color_32bit")] +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct Color { + r: u8, + g: u8, + b: u8, +} impl Color { + #[cfg(not(feature = "ui_color_32bit"))] pub const fn from_u16(val: u16) -> Self { Self(val) } + + #[cfg(feature = "ui_color_32bit")] + pub const fn from_u16(val: u16) -> Self { + Self { + r: ((((val) & 0xF800) >> 8) | (((val) & 0xF800) >> 13)) as u8, + g: ((((val) & 0x07E0) >> 3) | (((val) & 0x07E0) >> 9)) as u8, + b: ((((val) & 0x001F) << 3) | (((val) & 0x001F) >> 2)) as u8, + } + } + pub const fn from_u32(val: u32) -> Self { Self::rgb( ((val >> 16) & 0xFF) as u8, @@ -15,12 +34,17 @@ impl Color { ) } + #[cfg(not(feature = "ui_color_32bit"))] pub const fn rgb(r: u8, g: u8, b: u8) -> Self { let r = (r as u16 & 0xF8) << 8; let g = (g as u16 & 0xFC) << 3; let b = (b as u16 & 0xF8) >> 3; Self(r | g | b) } + #[cfg(feature = "ui_color_32bit")] + pub const fn rgb(r: u8, g: u8, b: u8) -> Self { + Self { r, g, b } + } pub const fn luminance(self) -> u32 { (self.r() as u32 * 299) / 1000 @@ -33,36 +57,56 @@ impl Color { let g_u16 = g as u16; let b_u16 = b as u16; - let r = ((256 - alpha) * bg.r() as u16 + alpha * r_u16) >> 8; - let g = ((256 - alpha) * bg.g() as u16 + alpha * g_u16) >> 8; - let b = ((256 - alpha) * bg.b() as u16 + alpha * b_u16) >> 8; + let r = (((256 - alpha) * bg.r() as u16 + alpha * r_u16) >> 8) as u8; + let g = (((256 - alpha) * bg.g() as u16 + alpha * g_u16) >> 8) as u8; + let b = (((256 - alpha) * bg.b() as u16 + alpha * b_u16) >> 8) as u8; - let r = (r & 0xF8) << 8; - let g = (g & 0xFC) << 3; - let b = (b & 0xF8) >> 3; - Self(r | g | b) + Self::rgb(r, g, b) } pub const fn alpha(bg: Color, alpha: u16) -> Self { Self::rgba(bg, 0xFF, 0xFF, 0xFF, alpha) } + #[cfg(not(feature = "ui_color_32bit"))] pub const fn r(self) -> u8 { (self.0 >> 8) as u8 & 0xF8 } + #[cfg(not(feature = "ui_color_32bit"))] pub const fn g(self) -> u8 { (self.0 >> 3) as u8 & 0xFC } + #[cfg(not(feature = "ui_color_32bit"))] pub const fn b(self) -> u8 { (self.0 << 3) as u8 & 0xF8 } + #[cfg(feature = "ui_color_32bit")] + pub const fn r(self) -> u8 { + self.r + } + #[cfg(feature = "ui_color_32bit")] + pub const fn g(self) -> u8 { + self.g + } + #[cfg(feature = "ui_color_32bit")] + pub const fn b(self) -> u8 { + self.b + } + #[cfg(not(feature = "ui_color_32bit"))] pub fn to_u16(self) -> u16 { self.0 } + #[cfg(feature = "ui_color_32bit")] + pub fn to_u16(self) -> u16 { + (((self.r() & 0xF8) as u16) << 8) + | (((self.g() & 0xFC) as u16) << 3) + | ((self.b() & 0xF8) as u16 >> 3) + } + pub fn to_u32(self) -> u32 { ((self.r() as u32) << 16) | ((self.g() as u32) << 8) | (self.b() as u32) | 0xff000000 } @@ -75,10 +119,20 @@ impl Color { (self.to_u16() & 0xFF) as u8 } + #[cfg(not(feature = "ui_color_32bit"))] pub fn negate(self) -> Self { Self(!self.0) } + #[cfg(feature = "ui_color_32bit")] + pub fn negate(self) -> Self { + Self { + r: 255 - self.r, + g: 255 - self.g, + b: 255 - self.b, + } + } + pub const fn white() -> Self { Self::rgb(255, 255, 255) } @@ -113,7 +167,7 @@ impl Lerp for Color { impl From for Color { fn from(val: u16) -> Self { - Self(val) + Self::from_u16(val) } } diff --git a/core/site_scons/models/D002/discovery2.py b/core/site_scons/models/D002/discovery2.py index 94f16b7c65..6c73b7efbd 100644 --- a/core/site_scons/models/D002/discovery2.py +++ b/core/site_scons/models/D002/discovery2.py @@ -91,7 +91,7 @@ def configure( ] features_available.append("usb") - defines += ["USE_DMA2D", "FRAMEBUFFER", "FRAMEBUFFER32BIT"] + defines += ["USE_DMA2D", "FRAMEBUFFER", "FRAMEBUFFER32BIT", "UI_COLOR_32BIT"] sources += [ "embed/trezorhal/stm32u5/dma2d.c", "embed/trezorhal/stm32u5/dma2d_bitblt.c", @@ -99,6 +99,7 @@ def configure( features_available.append("dma2d") features_available.append("framebuffer") features_available.append("framebuffer32bit") + features_available.append("ui_color_32bit") if "new_rendering" in features_wanted: defines += ["XFRAMEBUFFER"]