Sender | Message | Time |
---|---|---|
10 Nov 2024 | ||
9names | * i assume it was intended for rfuest based on folks in the issue? | 08:39:07 |
almindor | Ah yes! Sorry! | 16:07:19 |
almindor | is there any reason why we didn't make RgbXXX colors #[repr(transparent)] ? | 18:19:54 |
almindor | 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 | 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 | 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 | 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 | * 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 | although I guess that can be workedarounded by implementing it for specific Rgbxxx combos | 19:05:26 |
almindor | it'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 combos | 19:09:23 |
dngrs | sounds cool! | 19:21:32 |
GrantM11235 | 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 | 19:37:33 |
GrantM11235 | Of course that also involves replacing display-interface with something custom, which is absolutely warranted IMO | 19:54:49 |
GrantM11235 | Something like this:
| 19:56:28 |
almindor | In reply to @grantm11235:matrix.orgno, 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 | 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 | note 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 example | 23:23:06 |
GrantM11235 | What if you add a IntoStorage bound? | 23:31:31 |
almindor | In reply to @grantm11235:matrix.orgYou can't, it's not part of the DrawTarget trait | 23:31:56 |
almindor | I 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 | 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 TBF: I think most displays are BE, so I'd just default to that | 23:34:16 |
GrantM11235 | 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 | 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 | not sure if that's possible to do though? | 23:42:09 |
almindor | 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 | but I agree that the abstraction is "badly placed" atm. | 23:47:58 |
GrantM11235 | Using DataFormat::U8 to send pixels doesn't work for 16 bit parallel interfaces | 23:49:45 |
almindor | I mean... it could if you'd just chunk it? but then we're back to iteratoring | 23:50:44 |
GrantM11235 | 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 | oh no I mean it could be fixed | 23:53:39 |