-
Notifications
You must be signed in to change notification settings - Fork 1.4k
framebufferdisplay: Allow implementation of framebuffers in Python #3233
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
Conversation
|
Displays that may not have
I'm a bit interested in the is31fl3731 except that I have a 2x2 array of them so that won't exactly use standard code. |
|
Alternately, |
If set_brightness was implemented but get_brightness wasn't, this would hard fault
This avoids the message "Too many displays in use" when they are released directly, rather than via release_displays().
This allows the device interface part of a framebuffer to be implemented
in pure Python. A minimal and non-functional example:
class UFrame:
def __init__(self, width=64, height=32, bpp=8):
if bpp not in (8, 16):
raise ValueError("only supports 8 or 16 bit depth")
dtype = ulab.uint16 if bpp == 16 else ulab.uint8
self.buffer = ulab.zeros((width, height), dtype=dtype)
self.height = height
self.width = width
def get_buffer(self):
return self.buffer
def get_height(self):
return self.height
def get_width(self):
return self.width
def swapbuffers(self):
pass
A bit of cheating; we need to add a protocol getter for reverse_bytes_in_word
|
@tannewt I'd appreciate your feedback on this approach before I go further. The main trade-off I perceive is that these new displays implemented in Python cannot survive soft-reset. |
|
I'm not a huge fan of this approach for sharp memory. I was originally thinking it'd be added as a new native display type because if the different protocol for which line needs refresh. Here are a few concerns I have with this implementation. Using a Python object as the transmitter leads to two weird things:
I think I'd be ok with python vm only displays if it was able to show the error output once before the heap disappears. It still doesn't help the default case though. Using framebuffer also makes me worry about the memory overhead. How many bytes does the largest display take? The display retains the state so we don't need to keep it ourselves. (For larger RGB24 displays we'll have no choice.) That's my initial read on this. Want to chat this week about it? |
|
The largest display is 400x240 @ 1bpp. With some extra bookkeeping info to make updating fast, it's 12721 bytes. Limor recommended keeping the whole framebuffer in RAM. |
|
We are going to:
|
|
I'm going to close this up and leave this branch, because not much of it is applicable to the new direction for the memory displays. If we do decide someday to enable non-core displayio displays, we might want to revive this. |
This comes in several parts. Everything but the hypothetical
adafruit_displayio_sharpmemoryis in this PR:Shim framebuffer protocol
Allows pure Python objects to implement the framebuffer protocol. However, because these displays are Python objects, they do not survive soft-reset.
A do-nothing implementation might read as follows:
Supporting 1 (and probably 2 and 4) bpp displays
There was a COULDDO about this. It is handled by rounding the X coordinates to be computed to byte boundaries.
Bug fixing
I noticed or encountered bugs along the way.
One I did NOT fix is that an 8x8 display causes an infinite loop. If 8x8 displays become interesting for displayio we can look at it again.
Shortcomings
I hard-coded the fact that the Sharp Memory Display needs pixels in the "reverse_pixels_in_byte" direction. This is subject to change, depending whether we merge the LSBfirst SPI feature branch. Ultimately, it might not be necessary for this PR, but all the "knobs" provided by displayio_display_core_construct should be turnable from C and Python implementations of framebuffers
adafruit_displayio_sharpmemory.pyThis was a SUPER EASY conversion from the old framebuf version! I don't know what other kinds of displays haven't been converted yet, but this might make them all "pretty easy". Once we commit to this approcah, it needs to be librarified, added to bundle, etc.
go.pyImport this in your program or repl to get the display going.