!SfJCDXZbMHXkPovtKL:matrix.org

Rust Embedded Graphics

328 Members
Help and chat for embedded-graphics and the wider embedded Rust graphics ecosystem | https://github.com/embedded-graphics/embedded-graphics | https://crates.io/crates/embedded-graphics28 Servers

Load older messages


SenderMessageTime
10 Nov 2024
@9names:matrix.org9names * i assume it was intended for rfuest based on folks in the issue? 08:39:07
@almindor:matrix.orgalmindorAh yes! Sorry!16:07:19
@almindor:matrix.orgalmindor is there any reason why we didn't make RgbXXX colors #[repr(transparent)]? 18:19:54
@almindor:matrix.orgalmindor I'm trying to get fill_solid to at least approach the speed of pure u8 buffer SPI sends on a display and basically it seems that the combination of LE/BE transform with Color.into_inner is the biggest remaining slowdown. 18:22:31
@almindor:matrix.orgalmindor If we introduced endianness-awareness into e-g color types and provided transparency of the inner type to outer types, we could probably end up with a major performance boost at least for cases such as core::iter::repeat_n(Rgb565::RED) used for fills for example 18:23:31
@almindor:matrix.orgalmindor you could then just prep an intermediate buffer from given iterator, have the colors be BE (if needed), and just unsafe {} cast the whole thing into a uXX slice instead of manual one by one conversion 18:24:35
@almindor:matrix.orgalmindor another issue I see is that DrawTarget does not expose it's type Color: PixelColor as IntoStorage as well, which means you can't get the raw version of the color inside fill_solid (for e.g. doing let buf = [raw; BUFSIZE]; kind of thing) 19:03:15
@almindor:matrix.orgalmindor * another issue I see is that DrawTarget does not expose its type Color: PixelColor as IntoStorage as well, which means you can't get the raw version of the color inside fill_solid (for e.g. doing let buf = [raw; BUFSIZE]; kind of thing) 19:03:23
@almindor:matrix.orgalmindoralthough I guess that can be workedarounded by implementing it for specific Rgbxxx combos19:05:26
@almindor:matrix.orgalmindorit'd be nice if there was a way to just do something like 3 implementations instead though, e.g. per-storage types instead of individual RgbXXX combos19:09:23
@dngrs:matrix.orgdngrssounds cool!19:21:32
@grantm11235:matrix.orgGrantM11235fill_solid can be optimized without any changes to e-g. You just need to have a medium-sized buffer, fill it with the endian-corrected color, then send/reuse the buffer as many times as you need to in order to complete the fill19:37:33
@grantm11235:matrix.orgGrantM11235Of course that also involves replacing display-interface with something custom, which is absolutely warranted IMO19:54:49
@grantm11235:matrix.orgGrantM11235

Something like this:

pub trait Interface<P: Copy> {
    type Error: core::fmt::Debug;

    fn send_command(&mut self, command: u8, args: &[u8]) -> Result<(), Self::Error>;

    fn send_pixels(&mut self, pixels: impl Iterator<Item = P>) -> Result<(), Self::Error>;
    
    fn send_repeated_pixel(&mut self, pixel: P, count: u32) -> Result<(), Self::Error> {
        self.send_pixels((0..count).map(|_| pixel))
    }

    fn flush(&mut self) -> Result<(), Self::Error>;
}
19:56:28
@almindor:matrix.orgalmindor
In reply to @grantm11235:matrix.org
fill_solid can be optimized without any changes to e-g. You just need to have a medium-sized buffer, fill it with the endian-corrected color, then send/reuse the buffer as many times as you need to in order to complete the fill
no, I cannot because I cannot get the raw color directly out of the Self::Color unless I implement fill_solid for each RgbXXX separately.
23:18:25
@almindor:matrix.orgalmindor the main slowdown is actually using iter::repeat_n though as it turns out. Hence my comment about being able to do sort of let buf = [RawColorValue; count]; directly to avoid being forced into iterators 23:19:47
@almindor:matrix.orgalmindornote that this is mostly SPI specific, I guess with parallel gpio things are sort of the other way around where you want to keep u16s for example23:23:06
@grantm11235:matrix.orgGrantM11235 What if you add a IntoStorage bound? 23:31:31
@almindor:matrix.orgalmindor
In reply to @grantm11235:matrix.org
What if you add a IntoStorage bound?
You can't, it's not part of the DrawTarget trait
23:31:56
@almindor:matrix.orgalmindorI mean in the end I'd still have to implement all raw storage cases, but I believe it's 3? (u8, u16 and u32) vs the big matrix of all colors atm.23:32:26
@almindor:matrix.orgalmindor

but technically, if we wanted to be correct, endianness would also have to be "known" as well. Hence my comment on the "color with endianness" types. This will also help in non fill_solid cases beacuse the data from things like Triangle etc. would be prepared for the display, removing the need for to_be().

TBF: I think most displays are BE, so I'd just default to that

23:34:16
@grantm11235:matrix.orgGrantM11235 Your talking about implementing the DrawTarget trait, right? In that case, you control DrawTarget::Color. If you are implementing it on a generic struct, you can put the bound on the struct or on the trait impl 23:36:00
@almindor:matrix.orgalmindor Yeah, I can do it on the struct, issue is it's still a matrix, only now it becomes a matrix of Models hehe, which I think is even worse. What'd I really like is a way to tell the compiler this implementation is for fill_solid with colors of raw type represented by RawU16 for example. That way I could get away with just 3 I think and they can all use the raw buffer approach 23:42:01
@almindor:matrix.orgalmindornot sure if that's possible to do though?23:42:09
@almindor:matrix.orgalmindor display-interface isn't actually a major issue in all this, coz you just end up doing the DataFormat::U8. Dynamic dispatch does not seem to slow things down much coz it's not really called often 23:47:40
@almindor:matrix.orgalmindorbut I agree that the abstraction is "badly placed" atm.23:47:58
@grantm11235:matrix.orgGrantM11235 Using DataFormat::U8 to send pixels doesn't work for 16 bit parallel interfaces 23:49:45
@almindor:matrix.orgalmindorI mean... it could if you'd just chunk it? but then we're back to iteratoring23:50:44
@grantm11235:matrix.orgGrantM11235 The only way to send pixels with d-i on a 16 bit parallel interface is to use one of the U16* variants, if you use U8 it will turn each pixel into two "pixels" with the high byte padded with zero 23:53:12
@almindor:matrix.orgalmindoroh no I mean it could be fixed23:53:39

Show newer messages


Back to Room ListRoom Version: 5