Skip to content

extmod/modframebuf: add 24bit RGB support (RGB888) #3551

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

hoihu
Copy link
Contributor

@hoihu hoihu commented Jan 6, 2018

This adds support for 24bit RGB to the framebuf module, called RGB888 (following the naming convention of RGB565). This may be useful for neopixel based displays.

On the ESP8266 port it adds 340 Bytes of flash which is a lot.

Streamlining rgb888, rgb565 and gs8 support into generic functions would actually save flash. I've done this as an exercise on a separate branch and it reduced the size by 20 Bytes or 360 Bytes compared to this version.

But I believe the performance penalty for rgb565 and gs8 was probably too high so I stayed with the existing design pattern.

@hoihu hoihu force-pushed the feat-framebuf-rgb24-opt1 branch from 770fa54 to 64cd93e Compare January 15, 2018 21:10
@dpgeorge
Copy link
Member

Thanks for the contribution. I think that such a format is a useful addition to have.

This may be useful for neopixel based displays.

Did you have this in mind when writing the code, or was the main use of RGB888 for an LCD/OLED display?

But I believe the performance penalty for rgb565 and gs8 was probably too high so I stayed with the existing design pattern.

Yes I agree it's best to keep these simple and common formats as fast as possible.

One thing to discuss: RGB888 will introduce a similar issue re endianess as pointed out in #3536. The patch here has it as little endian, which at the very least should be documented. Is there a case for bigendian? Note that it would be equivalent to a little endian BGR888, and then what about all the other cases: RBG, GRB, GBR, BRG?

@robert-hh
Copy link
Contributor

robert-hh commented Jan 31, 2018

As for the comment of the endianess of the 565 format: the framebuffer module should support one format, and re-ordering of the bytes can be done beforehand, if needed. If done in Python, performance may be bad however. At least, on ESP8266 and STM32 viper code can be used for that.

@hoihu
Copy link
Contributor Author

hoihu commented Feb 3, 2018

Did you have this in mind when writing the code, or was the main use of RGB888 for an LCD/OLED display?

The main use I saw was for neopixel based displays, such as the Pimoroni Unicorn HAT. But since I've done some work on the SenseHAT - that would be a good fit too. I haven't looked into LCD/OLED type displays.

Now as for the Pimoroni HAT I've concluded that Neopixel based display may need in fact another framebuffer mapping - they are likely wired in a "meander" way instead of a grid:

Row 1:     --  Pixel1     ---  Pixel 2  ... Pixel N-1 --  Pixel N      --
                                                                         |
Row 2:     -- Pixel 2N   --- ..         ... Pixel N+2 -- Pixel N+1     --
          |
Row 3:     --  Pixel 2*N+1

So the odd number of rows are in reversed order then the even ones. This wiring makes also sense if someone decides to make a display out of neopixel strips (it avoids cabling running from the end-of row to the beginning of the next row).

The SenseHAT is wired differently - the framebuffers contents can be transferred using I2C to a memory mapped address. That should be ok.

RGB888 will introduce a similar issue re endianess as pointed out in #3536

Note that it would be equivalent to a little endian BGR888, and then what about all the other cases: RBG, GRB, GBR, BRG?

Since the framebuffer does not know about colours, "RGB" is meaningless. The WS2812B ("neopixel") based LEDs for example are GRB mapped.

From that point of view a naming like "two-byte-per-pixel" and "three-byte-per-pixel" might be cleaner than RGB888, RGB565, and independant of the endianess. It wouldn't imply a color mapping. RBG, GRB, BRG mappings essentially lead to the same C-code (with the existing framebuffer approach - all are 3 byte mapping).

Endianess can be handled by several means, depending on the application:

  • Bitmaps: Using pre-calculated bitmaps with the correct mapping
  • Dynamic stuff / fonts: Do the correct color mapping within Python (as @robert-hh mentioned).
  • Using HW options (display controller chip configurations).

In the long term I'd very much like to see a standardized way of displaying text/color on different uPy applications, independant of the HW. But I see that this is a big challenge.

Is there a case for bigendian

I can't see one - but of course I may have overlooked something.

BTW i can provide a PR for the mapping for the "meander" type wiring - if anyone is interested in it :)

@dpgeorge
Copy link
Member

dpgeorge commented Feb 7, 2018

Thanks @hoihu for the reply. It would be good to see some use-case for this for an LCD/OLED, but displays made of many RGB pixels would already justify to have such a format.

As for the meandering pixel order: I think supporting that is out of scope because it's too niche, and it opens the door to needing to support heaps of other, similar formats. It could be supported by some fast conversion code written in assembler.

@hoihu
Copy link
Contributor Author

hoihu commented Feb 9, 2018

As for the meandering pixel order: I think supporting that is out of scope because it's too niche, and it opens the door to needing to support heaps of other, similar formats.

ok no problem. Makes sense to set the number of variants as low as possible

It could be supported by some fast conversion code written in assembler.

that would be interesting to implement - however bound to a specific platform...

It would be good to see some use-case for this for an LCD/OLED

I'll try to check some of the display driver chips (SSDxxxx) for this.

FYI reagarding neopixel displays & wiring: Adafruit mentions this "meandering" problem in their "neopixel Uberguide" https://cdn-learn.adafruit.com/downloads/pdf/adafruit-neopixel-uberguide.pdf p47 and ff.

They call the wiring options "zickzack" (for meandering) and "progressive".

I checked some of their products and it seems that newer products like the feather 4x8 neopixel shield https://www.adafruit.com/product/2945 are "progressive" style, e.g. would work with the current implementation. Whereas some of big flex matrix style displays are "zickzack" style, like https://www.adafruit.com/product/2294

Regarding colors: They mention that color rendering is sufficient with 16bit (565 mapping). As far as I understood, their GFX library is fixed to 16 bit, 565 color mapping. They then do a conversion to lift those values to a 888 mapping for 24 bit neopixels https://github.com/adafruit/Adafruit_NeoMatrix/blob/master/Adafruit_NeoMatrix.cpp#L64 . Probably not very efficient but seems to do the job.

@hoihu
Copy link
Contributor Author

hoihu commented Mar 10, 2018

Here is a gist that demonstrates mirroring of framebuffer row data in viper notation:
https://gist.github.com/hoihu/b9ef8fcd24a54f3899dd6e92aa6ac77b

it works on a pimoroni unicorn HAT (which is wired in "zickzack" manner as described above).

One thing to consider: Relative framebuf operations such as framebuf.scroll do not work with zickzack wired neopixels. You'd need to scroll each line individually in either positive or negative direction.. It does generate an interesting optical effect since rows are moving in opposite directions :)

@hoihu hoihu force-pushed the feat-framebuf-rgb24-opt1 branch 2 times, most recently from ec7165b to 4b92136 Compare March 12, 2018 19:15
@hoihu hoihu force-pushed the feat-framebuf-rgb24-opt1 branch from 4b92136 to b6fd0a0 Compare March 12, 2018 19:17
@hoihu
Copy link
Contributor Author

hoihu commented Mar 12, 2018

sorry for the noise on the build server.. it's not my git day it seems :)

I've rebased to the current master and added a small note on endianness used. If anything is missing please let me know.

@dpgeorge dpgeorge added the extmod Relates to extmod/ directory in source label May 11, 2021
@jimmo
Copy link
Member

jimmo commented May 11, 2021

I think this is a worthwhile feature for, e.g. APA102 and RGBW WS2812 LED strips. See #7253 for discussion about adding more modes to modframebuf.

@jimmo jimmo closed this May 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
extmod Relates to extmod/ directory in source
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy