Announce: Framebuffer::GFX and FastLED_SPITFT::GFX

Ok, it’s a bit off topic, but since @Louis was interested, he probably won’t kick me out for posting this :slight_smile:
I’ve refactored my multi API setup in as base class

If you use GitHub - marcmerlin/SmartMatrix_GFX: SmartMatrix: Allow using Adafruit::GFX as well as FastLED_NeoMatrix code with SmartMatrix backend, , you’ll be talking to it.

In turn, you can then substitute your RGBPanel(s) for a small TFT and display your same code with pretty much 0 work:

More details:

Good work Marc, thanks for sharing!

Do you have a project in mind for this?

I’m in the early stages of a VJ controller for LED wearables, and eventually want to add a feature to Aurora so it can sync timing of Aurora patterns over RFM69 radios to nearby wearables also running Aurora. The VJ controller would be handheld, and using one of these tiny OLEDs. The VJ controller radio wouldn’t need to send a lot of data; it’s not sending the full frame buffer, just pattern and timing information, like this project for the PixelBlaze controller does: GitHub - simap/Firestorm: Pixelblaze Firestorm is a centralized control console for Pixelblaze WiFi LED controllers

Actually in this case, not really, I just ended up with some small TFTs and I figured I’d do this for fun, and also as an exercise to help factor our my framebuffer library into a base class.

That being said, it’s cool to be able to write code and test it easily on a trip without carrying big panels and wires.

yeah, it would work great for such an application.

Looking forward to seeing your work :slight_smile:

Hi Marc, SmartMatrix Library 4.0 is ready for release, and merged into master. It won’t work as is with your libraries, as SmartMatrix3.h is replaced with SmartMatrix.h or SmartMatrix4.h. There’s some new #defines to identify version, check out SmartMatrix.h. Hope you can get your libraries running with SmartMatrix Library 4.0, happy to help if you need it

Check out the updated Migration doc

Also I’m going to be requesting the Arduino Library Manager renames the library SmartMatrix, instead of SmartMatrix3, which might screw up Arduino Library Manager dependencies temporarily, but will be better in the long run

Thank you for the heads up @Louis , will have a look.
Remind me: you’ve actually made part of SmartMatrix::GFX redundant. I however offer further compatibility with FastLED and LEDMatrix, while you’ve integrated GFX support in 4.0. Is that correct?

Yes, I believe with some work, you could connect your Framebuffer::GFX directly to the Background_GFX Layer. Here’s where we were discussing that:

LMK if you need help with passing a pointer to a templated class or anything else if you want to take on this work.

Hi @Louis: first questions

  • Your new SmartMatrix is definitely a step up/different from the old 4.0 where all the stuff was in teensylc. Would it make sense to call this one 4.1 or even 5.0 given that it’s a pretty big merge and upgrade with the integrated GFX support?
    => mmmh, I think the old lib was actually smartmatrix3, but i was confused because of #include <SmartLEDShieldV4.h>. So, basically you did upgrade from 3 to 4, my bad.

  • I looked at your GFX support and I’m a bit confused as to why it’s not default and why one needs to use different define macros (SMARTMATRIX_ALLOCATE_BACKGROUND_GFX_LAYER) on top of defining SUPPORT_ADAFRUIT_GFX_LIBRARY
    a) shouldn’t defining SUPPORT_ADAFRUIT_GFX_LIBRARY be enough?
    b) if there are costs/drawbacks to enabling it, and that’s why you didn’t make it default, can you give more details on that?

  • Obviously adafruit::gfx is only 16bpp while you allow all the way to 36bpp. Does it mean that when you use GFX primitives, you have to use RGB565 even though the back buffer could be 36bpp?
    Is there a way to use the passthroughcolor trick?
    Actually, looking at your code, it looks like the line primitives go directly to our library (bypassing GFX and it’s 565 color limitation), but fonts go to GFX with the color limitation (which for my own use is really not an issue)?

Basically it’d be great to have a GFX section in your README.md, explaining some of the points above :slight_smile:

BTW, warning I see in the latest lib:

/home/merlin/Arduino/libraries/SmartMatrix/src/esp32_i2s_parallel.c:68:12: warning: 'calc_needed_dma_descs_for' defined but not used [-Wunused-function]
 static int calc_needed_dma_descs_for(i2s_parallel_buffer_desc_t *desc) {
            ^
/home/merlin/Arduino/libraries/SmartMatrix/src/esp32_i2s_parallel.c:76:13: warning: 'fill_dma_desc' defined but not used [-Wunused-function]
 static void fill_dma_desc(volatile lldesc_t *dmadesc, i2s_parallel_buffer_desc_t *bufdesc) {
             ^

a) shouldn’t defining SUPPORT_ADAFRUIT_GFX_LIBRARY be enough?

SUPPORT_ADAFRUIT_GFX_LIBRARY just tells SmartMatrix Library to include Adafruit_GFX. I suppose I could have made it so if you define SUPPORT_ADAFRUIT_GFX_LIBRARY the library switches BackgroundLayer to use BackgroundLayer_GFX, but I didn’t think of that, and don’t see a big reason to change that functionality now.

b) if there are costs/drawbacks to enabling it, and that’s why you didn’t make it default, can you give more details on that?

The main reasons I didn’t make it default was:

  1. backwards compatibility - at a minimum you need to change FastLED code to cast CRGB as rgb24
  2. I haven’t tested this new code enough and there are likely bugs
  3. It makes using SmartMatrix Library dependent on Adafruit_GFX, and I didn’t want a required dependency
  4. The scrolling text functionality requires a different amount of RAM allocated - it used to be just the pixels for the whole layer, now it’s the pixels to hold the string - which requires more RAM for larger fonts/longer strings.

Obviously adafruit::gfx is only 16bpp while you allow all the way to 36bpp.

I used the passthrough trick, so rgb24/rgb48 should be supported without downgrading to uint16_t:

Basically it’d be great to have a GFX section in your README.md, explaining some of the points above :slight_smile:

Yes, documentation has always been lacking. I’m trying to improve things by making the Wiki the documentation hub for SmartMatrix Library, as it’s easier to maintain than my separate docs site, and I can open it up for anyone to contribute. I need to document Layer functionality, and this will be part of that documentation.

How are you compiling? I don’t see that warning and my compiler uses -Wno-unused-function for compiling. I’m using Arduino 1.8.13 with esp32 1.0.4 Board package.

In the arduino IDE, preferences, compiler warnings: all

it runs:
/home/merlin/arduino/hardware/espressif/esp32/tools/xtensa-esp32-elf/bin/xtensa-esp32-elf-g++ -DESP_PLATFORM “-DMBEDTLS_CONFIG_FILE=“mbedtls/esp_config.h”” -DHAVE_CONFIG_H -I/home/merlin/arduino/hardware/espressif/esp32/tools/sdk/include/config (…) -I/home/merlin/arduino/hardware/espressif/esp32/tools/sdk/include/fb_gfx -std=gnu++11 -fno-exceptions -Os -g3 -Wpointer-arith -fexceptions -fstack-protector -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -mlongcalls -nostdlib -Wall -Werror=all -Wextra -Wno-error=unused-function -Wno-error=unused-but-set-variable -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -fno-rtti -MMD -c -DF_CPU=240000000L -DARDUINO=10812 -DARDUINO_ESP32_DEV -DARDUINO_ARCH_ESP32 “-DARDUINO_BOARD=“ESP32_DEV”” "-DARDUINO_VARIANT=“esp32"” -DESP32 -DCORE_DEBUG_LEVEL=4 -I/home/merlin/arduino/hardware/espressif/esp32/cores/esp32 -I/home/merlin/arduino/hardware/espressif/esp32/variants/esp32 -I/home/merlin/Arduino/libraries/Adafruit-GFX-Library -I/home/merlin/Arduino/libraries/FastLED -I/home/merlin/arduino/hardware/espressif/esp32/libraries/FFat/src -I/home/merlin/arduino/hardware/espressif/esp32/libraries/FS/src -I/home/merlin/Arduino/libraries/SmartMatrix/src -I/home/merlin/Arduino/libraries/SmartMatrix_GFX -I/home/merlin/Arduino/libraries/Framebuffer_GFX -I/home/merlin/arduino/hardware/espressif/esp32/libraries/SPI/src /home/merlin/arduino/hardware/espressif/esp32/libraries/FFat/src/FFat.cpp -o /tmp/arduino_build_307154/libraries/FFat/FFat.cpp.o

Thanks for all the answers. I’m still going through the code to see what changed. Currently things break if I use PSRAM, and without PSRAM LEDMatrix code doesn’t work either. I need to do more reading to look into it.

As for SUPPORT_ADAFRUIT_GFX_LIBRARY, I get your points, makes sense to make it optional, however I’d deprecate your second set of macros to define GFX layers. From a user perspective, it looks weird and adds more ifdefs.
I didn’t realize you were using passthrough for all functions. Make sense.
Ok, need to go back to SmartMatrix::GFX to see what broke and why :slight_smile:

Thanks for the feedback. Maybe I’ll change it to USE_ADAFRUIT_GFX_LAYERS and make that the only change needed in the sketch.

SGTM. Sorry for having had the time to look at this earlier.

I was using compiler warnings: none (not what I wanted, I just didn’t realize that must have been the default), but even when I change to “all”, I don’t see the warning. I even restarted the IDE.

Mmmh, I’m not sure then. Did you try compiling for ESP32?

And putting aside not getting the warnings on your side, does it look correct that those 2 functions aren’t used (at least on ESP32)?

Yeah, those functions aren’t needed. I could comment them out or delete them.

#if 0 sounds like a good plan if you hope to re-use them later :slight_smile:

I haven’t tracked down why, but I’ve confirmed that PSRAM support stopped working in the new code.
(later…)
Ok, this was a weird issue. I’ve tracked it down to the code doing Serial.begin() twice. That was perfectly fine for 2 years with all libraries and code, until I swapped your new lib in, and then it caused a crash at start.
Obviously it’s not our code’s fault, but some weird compiler interaction I’m not really interested in tracking down.
At end of the day, it’s my fault, I shouldn’t call Serial.begin twice, so I fixed it:

@Louis ok, I’m done moving my code to your new library.
Basically I’m not really using any of the new functionality, but then again, I didn’t need it :slight_smile: the good news is that things continue to “just work”.
Yeah, I’m still using the callback with a function pointer, which I didn’t love when I wrote it, but it works, and I have little incentive to change it now, unless someone sends me a carefully tested patch. I guess I’m just not a fan of template syntax, and I’m happy to avoid it :slight_smile:

The last thing I was worried about was memory use, and I can confirm that I actually have 4 extra bytes of free RAM after switching to the new lib, so all is good.

 Allocating refresh buffer:
lsbMsbTransitionBit of 0 requires 49152 RAM, 64624 available, leaving 15472 free: 
lsbMsbTransitionBit of 1 requires 24576 RAM, 64624 available, leaving 40048 free: 
Raised lsbMsbTransitionBit to 1/7 to fit in RAM
lsbMsbTransitionBit of 1 gives 50 Hz refresh, 120 requested: 
lsbMsbTransitionBit of 2 gives 100 Hz refresh, 120 requested: 
lsbMsbTransitionBit of 3 gives 191 Hz refresh, 120 requested: 
Raised lsbMsbTransitionBit to 3/7 to meet minimum refresh rate
Descriptors for lsbMsbTransitionBit 3/7 with 16 rows require 6144 bytes of DMA RAM
SmartMatrix Mallocs Complete
Heap/32-bit Memory Available: 125172 bytes total,  64624 bytes largest free block
8-bit/DMA Memory Available  :  82624 bytes total,  64624 bytes largest free block
Total PSRAM used: 36864 bytes total, 4157356 PSRAM bytes free
Setting up parallel I2S bus at I2S1