ArduinoOnPc icon indicating copy to clipboard operation
ArduinoOnPc copied to clipboard

Is there a faster tft pixel draw?

Open marcmerlin opened this issue 5 years ago • 4 comments
trafficstars

Hi again,

I'm working on bringing a big library of APIs on top of your work (to allow developing on PCs for faster speed and debugging). I've already done the work with a fork of your lib that uses SDL, but it's an old fork of your work that is lacking serial support plus a lot of code you added, and I'd rather have is depend on X11 instead of SDL. The SDL version does work well and fast, though, it writes to an emulated neopixel 1D array that gets rendered into a 2D SDL matrix: https://github.com/MarcFork/FastLEDonPc

My concern at this point is that all my code relies on a framebuffer that is stored in memory and synced to the hardware backend when matrix->show() is called. The only way I knew how to implement this is by calling XWindow::drawPoint_RGB for every dot, in the matrix, but it is very slow (0.2sec for only 160x120 resolution). See: https://github.com/marcmerlin/FastLED_TFTWrapper_GFX/blob/2a2de242054f227f603156139b5bbeed6197193a/FastLED_TFTWrapper_GFX.cpp#L28

Is there a better way to give a precomputed square matrix in RGB888 to Xwindow without calling the slow draw pixel, pixel by pixel? Thanks.

marcmerlin avatar Dec 29 '19 17:12 marcmerlin

At the moment only

XDrawLine and drawPoint_RGB

fromt the XWindows driver is used here:

XWindowCpp

Of course using only the point and line functions is not the fastest way to write to the screen, but the simpliest.

A possibility to speed it up would be to add the XFillRectangle function: https://www.x.org/releases/current/doc/man/man3/XFillRectangle.3.xhtml

and afterwards to access it from the Adafruit-Driver or your Fastled-Driver.

ChrisMicro avatar Dec 30 '19 20:12 ChrisMicro

Thanks for the pointer. Thankfully pixel by pixel works for basic demos, but fails for bitmaps. See Adafruit_GFX::drawBitmap https://github.com/adafruit/Adafruit-GFX-Library/blob/c023885755d252123f7fe4ea65134cb28da930b0/Adafruit_GFX.cpp#L717 you can see a picture here: https://github.com/marcmerlin/IoTuz another example of things that wouldn't really work speed-wise: https://youtu.be/Kvcvpdip12A?t=74

It will work, but it will be so slow (and apparently somewhat locks for X server for each dot printed), that isn't very useable. I completely suck a XWindow programming, so sorry that my knowledge is 0 there.

You are right that I can get around it by XFillRectangle, and I may do that, but if the drawPixel primitive can't be faste, some adafruit::gfx code won't work well. That said, it may also be unavoidable given how things work. Feel free to close this if you don't find a good generic answer.

thanks for your answer.

marcmerlin avatar Dec 30 '19 22:12 marcmerlin

You are right, drawing a bitmap is quite slow. It is done with this example.

I think it should be possible to speed it up by using XCreateImage: https://stackoverflow.com/questions/6609281/how-to-draw-an-image-from-file-on-window-with-xlib

ChrisMicro avatar Dec 31 '19 03:12 ChrisMicro

As a quick update, for now I ended up using the already working (and fast) SDL support: http://marc.merlins.org/perso/arduino/post_2020-01-24_Running-Arduino-code-with-2D-FastLED_-Adafruit_GFX_-and-LEDMatrix-displays-on-Linux.html https://github.com/marcmerlin/ArduinoOnPc-FastLED-GFX-LEDMatrix

X11 output support is left just in case, but given that it's not scaled up (the SDL output is), the SDL support has been preferable anyway.

marcmerlin avatar Jan 28 '20 14:01 marcmerlin