QuantumBadger / Speedy2D

Rust library for hardware accelerated drawing of 2D shapes, images, and text, with an easy to use API.
Apache License 2.0
386 stars 42 forks source link

Raspberry Pi performance #83

Closed superlou closed 1 year ago

superlou commented 1 year ago

This my own limited misunderstanding, but on a Raspberry Pi 3, does the follow glxinfo output meet what Speedy2D needs? I think this is OpenGL and not OpenGLES, but maybe that explains why I have slow performance:

OpenGL vendor string: Broadcom
OpenGL renderer string: VC4 V3D 2.1
OpenGL version string: 2.1 Mesa 20.3.5
OpenGL shading language version string: 1.20

Running at low resolutions (640x480) is very performant (60 FPS), but as I expand the window frame, it slows down dramatically. Is there a way to scale more cheaply than expand the resolution?

QuantumBadger commented 1 year ago

Thanks for reporting this! Could you give me a full log please?

Also, which functions are you calling in your on_draw() callback? You should call clear_screen() at the start of every frame for best performance, particularly on embedded GPUs.

superlou commented 1 year ago

Is there a logging function I should enable in the API? I can try to run that and get a log tonight.

In on_draw(...), I'm calling clear_screen, DrawRectangle, DrawText, DrawImage, and DrawRectangleImageTinted (https://github.com/superlou/signrs/blob/main/src/window_handler.rs#L45). The first thing done is clear_screen (I apologize that this is in a script rather than Rust with the Speedy2D API, though the script calls are a very thin layer over Speedy2D):

https://github.com/superlou/signrs/blob/be259915b630551e4b9e5273c2b38f40a9af4141/examples/display1/main.rhai#L15-L38

I don't think it's the scripting layer causing the performance issue since it runs at 60 FPS when the window is small, and it's only slow when the window frame is enlarged.

Edit: I wonder if it's something related to using the compositor or having it enabled: https://forums.raspberrypi.com/viewtopic.php?t=276207. It's interesting that info-beamer, which is the inspirational Raspberry Pi application that rolled it's own hardware accelerated API to get fast performance on the Raspberry Pi only runs full-screen (maybe bypassing the compositor, though I'm not even sure if I'm putting reasonable words together)?

superlou commented 1 year ago

I tried disabling the compositor, and now when I expand the 640x480 window to full screen, it only goes down to 22 FPS rather than 8 or 9, which is a big improvement. That said, the expanded window isn't drawing a lot:

image

Edit: Forcing multisampling to 1 seems to get 60 FPS at full screen (windowed)! Is there an easy way to scale up the contents of the window rather than expanding the number of pixels?

QuantumBadger commented 1 year ago

Awesome, glad to hear it's running at 60fps now! Regarding scaling -- all of Speedy2D's drawing operations use physical pixels, for maximum control and performance, so there's no built in "scale" function. To scale everything up it's necessary to multiply the sizes/coordinates of the things you're drawing.

superlou commented 1 year ago

Ah, I wasn't sure if WindowSize::ScaledPixels (https://docs.rs/speedy2d/latest/speedy2d/window/enum.WindowSize.html) was more about scaling the viewport or maybe its for HiDPI scaling?

It might be more of a "game UI" vs. "application UI," thing, but I wonder if there's a cheap OpenGL viewport way to have some set resolution, but stretch everything to fit. It makes sense to multiply the sizes/coordinates of everything for most objects, but the scale for text doesn't seem to have a way to scale x and y independently. I've seen other OpenGL backend applications just stretch things (Godot, info-beamer) with objects like text and images getting blurrier, so I'll have to do some digging. Either way, probably a separate issue.