Understanding Canvas

Hello, I have been using the library for several years now and am wondering about the Canvas functionality. I thought several times I understood it, only to come away confused.

I’ll explain the problem I am having:

I am drawing multiple layers of backgrounds to a “canvas” and when I am finished I want to display the “canvas”.

(python pseudo code)

 - create new canvas
Canvas = TheMatrix.CreateFrameCanvas()
  
**LOOP**
  - clear canvas  
  Canvas.Fill(0,0,0)

  - draw a bunch of pixels (multiple passes for multiple layers)
  Canvas.SetPixel(x,y,r,g,b)
  Canvas.SetPixel(x,y,r,g,b)

  - display the results
  TheMatrix.SwapOnVSync(Canvas)


The problem I am having is a noticeable flicker when I execute Canvas.Fill(0,0,0). I THOUGHT this would only draw on the canvas (i.e. it was drawing on a buffer off screen) and the main display would not be affected until the SwapOnVSync.

Have I mis-understood how the Canvas object works?

Thanks for any insights…

I am also a pretty new user of this library. My understanding is that you are operating off screen and that it isn’t until you do the SwapOnVSync() that the updated canvas takes effect. However I have noticed that any cpu intensive activity on my pi can cause the panels to flicker. Perhaps that is the issue?
You might want to try canvas.Clear() instead of canvas.Fill(), I haven’t tested/measured the relative cost of this api, but I use canvas.Clear() on my pi zero w and haven’t had an issue with it causing flicker.

Thank you for the suggestion. I will definitely try clear.

The clear function still causes the screen to blank, almost as if the “canvas” I am workign with is the actual live display. I am going through the python docs to see where my mis-understanding is coming from.

And I finally understand my mis-understanding.

I was thinking I had a “canvas” and by swapping, I was just swapping the information in it onto the display. Nope. There are TWO canvases. One being drawn from, one that I am painting on. I need to swap them and keep writing.

Canvas.DrawStuff()
Canvas = LED.TheMatrix.SwapOnVSync(Canvas)
Canvas.DrawMoreStuff()

I was not capturing the returned canvas. Anyway, this is amazing now. I can finally get to do the things I want.

2 Likes

interesting, thanks for sharing this. BTW I verified through code inspection that clear() is more efficient than fill(). see: rpi-rgb-led-matrix/framebuffer.cc at a56338db0f003d5236f2ce98c73a591d64a70852 · hzeller/rpi-rgb-led-matrix · GitHub

1 Like

You can see my latest work here:

2 Likes

That looks really great! The stars are cool. Can you share a pointer to your code (if its on github)?

1 Like

Defender.py is the latest one with the scrolling stars and landscape.

1 Like

Sorry, wrong link given.