Skip to content

glcanon: rewrite the G-code preview on OpenGL 3.3 core - #4293

Merged
snowgoer540 merged 1 commit into
LinuxCNC:masterfrom
alex-pres:pr-gremlin-opengl-rewrite
Aug 12, 2026
Merged

glcanon: rewrite the G-code preview on OpenGL 3.3 core#4293
snowgoer540 merged 1 commit into
LinuxCNC:masterfrom
alex-pres:pr-gremlin-opengl-rewrite

Conversation

@alex-pres

Copy link
Copy Markdown
Contributor

Replaces the fixed-function preview shared by AXIS, the GTK screens and QtVCP with a shader/VBO renderer: a baked trajectory buffer, an offscreen ID-buffer pass for picking, and a glyph atlas for overlay text. The GL matrix stack, display lists, immediate mode and GL_SELECT are gone.

@alex-pres

alex-pres commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

Why rewrite?

  • OpenGL immediate mode has been deprecated for 18 years (since OpenGL 3.0 in 2008).
  • This unblocks many UI decisions — for example, it now works with XWayland.
  • There is a solid performance win, although it's only visible for large ngc files (engraving or 3D reliefs).

Performance

  • The new code does not make many OpenGL function calls per trajectory point. Instead, it builds a numpy array
    of trajectory points, transmits it directly from system memory to GPU memory, and submits (once) a small
    program to the GPU with instructions on how to convert it from 3D to 2D (the "shader" program). The same for backplot points.
  • Additionally, operations on trajectory points are optimized with numpy batch handling.
  • Selection of g-code line by clicking point must be also faster and GPU powered with new code.

Code Refactoring

Code is also reviewed and refactored for eaiser maintenance .

  • Previous code handled scene rotation from many places by directly calling OpenGL methods. Now there is a dedicated matrix that handle this.
  • Program siumlation reported points and Backlog points are separated to objects to easily see logic.
  • Also added new concept of Scene that contains Part(s) like Axes, Backplot, DRO, Program, and so on. Each part is self-contained and can be disabled, replaced or extended from code.
  • Previous version of code maintained arrays of moves, feeds and so on right in Python. These lists may take significant memory. For example look at comparsion below: | gcode.parse | old: +575 MB vs new:+28 MB | for 18M ngc file. New code does not need these lists and makes all necessary calculations while collecting points.

Hardware support

This rewrite targets the OpenGL 3.3 standard, released in 2010 and widely supported.

In case of hardware problems, or if drivers don't support the necessary features, the env var
LIBGL_ALWAYS_SOFTWARE=1 can be set to enable software OpenGL handling via llvmpipe.

Verification

  • During development, I tried to get pixel-to-pixel comparisons as much as possible and fix any differences.

Performance testing results

Benchmarked against stock master on fractal-1M.ngc (18.9 MB, 1,000,149 moves). Mac M4 ARM64, Docker + Xvfb + llvmpipe.

AXIS end-to-end (4 reps, real GUI, open_file_guts)

master rewrite
peak RSS 1674 MB 748 MB 2.24× lower
⤷ minus idle baseline (194 MB both) 1480 MB 554 MB 2.67× lower
steady redraw frame 0.32 s 0.12 s 2.7× faster
open_file_guts (open→drawn) 7.6 s (6.8–8.5) 7.1 s (7.1–7.4) a wash
load_preview alone 3.00 s 2.96 s a wash

Both screenshots confirm the file actually drew — this isn't one branch skipping work.

Phase harness (3 reps, EGL, isolates parse / extents / GPU build)

phase master rewrite
gcode.parse 1.66 s, +575 MB 2.76 s, +28 MB
calc_extents 0.86 s, +432 MB 0.00002 s, +0
GPU build 0.28 s (glNewList), +31 MB bake 0.027 s + upload 0.002 s
GL payload not queryable 24,003,600 B VBO (counted at glBufferData)
load total 2.82 s 2.80 s
peak RSS 1122 MB 276 MB
first click in preview +0.75 s, +276 MB (selection lists) none

What the numbers say

  • Memory is the headline. 2.2× lower peak in the real GUI, and the gap widens on first click: master compiles a second, per-line-named copy of the program into selection display lists (+276 MB); the rewrite's picker reads the buffers already uploaded.
  • Load time is unchanged, but for a non-obvious reason. The rewrite's raw parse is ~1.1 s slower — it transforms and fills arrays on the move path. That's fully paid back by calc_extents/unrotate_preview dropping from 0.86 s to zero, since the rewrite accumulates extents during the fill. If you want load time to actually drop, the parse hot path is where the remaining 1.1 s lives.
  • Frame time is 2.7× better and the GPU build is 10× cheaper (0.03 s vs 0.28 s).

Two caveats worth stating: llvmpipe puts display lists and VBOs in process RSS, so the RSS deltas are the only cross-branch-comparable "GPU memory" figure — a display list has no queryable size, so master gets no exact byte count. And I noticed that at the same view master's preview saturates to white where the rewrite renders mid-grey; that's a blend difference on densely overlapping geometry which I did not investigate.

@BsAtHome

Copy link
Copy Markdown
Contributor

Good work.

Functional touch screen support is rather important to keep working. Breaking a touch interface would probably make quite a few users pulling hairs and may even require baldness treatments when it persists.

Some cases that should function: running on RPi4, Rpi5 and running with remote X (also ssh tunneled)?

@alex-pres

alex-pres commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

Good work.

Functional touch screen support is rather important to keep working. Breaking a touch interface would probably make quite a few users pulling hairs and may even require baldness treatments when it persists.

Some cases that should function: running on RPi4, Rpi5 and running with remote X (also ssh tunneled)?

I've just verified and touchscreen works exactly as in master branch, so no problems with it.

Unfortunately I have no RPi to test on it but I'd not expect any problems, this OpenGL API is not exotic. I'd say previous immediate mode API is less compatible.

Regarding remote X11 via SSH, my googling shows it may be a problem, but it is easy to solve by switching to software GL rendering with LIBGL_ALWAYS_SOFTWARE=1.

@c-morley

Copy link
Copy Markdown
Collaborator

Tried on my laptop, seems to work great - colors seem a bit darker. Very nice job!

@alex-pres
alex-pres marked this pull request as draft July 31, 2026 09:51
@alex-pres

alex-pres commented Jul 31, 2026

Copy link
Copy Markdown
Contributor Author

Seems some changes are necessary to make it RPi4B compatible. it seems to be easy. And even more important, it seems we can do much further with this and loading 1M+ points program can be handled well even on weak hardware. I'll work it out and submit here.

@snowgoer540

Copy link
Copy Markdown
Contributor

Gave this a go with the QtPlasmaC screen. All looks well except two things:

  1. I notice that the line width is thinner for the code preview, the position tracker, etc.
  2. QtPlasmaC uses glTranslatef to calculate a "table view". I made the following changes that seemed to work (being 100% honest, this is outside of my paygrade, so I used Claude to get here). I have no idea if this is the right way to do it or not. Completely welcome your experties!

Deleted:
from OpenGL.GL import glTranslatef

Added
from glnav import multiply, translation_matrix

Deleted:
glTranslatef(-xTableCenter, -yTableCenter, 0)

Added
widget.modelview = multiply(widget.modelview, translation_matrix(-xTableCenter, -yTableCenter, 0))

Otherwise it seems to work as expected!

@alex-pres

alex-pres commented Aug 1, 2026

Copy link
Copy Markdown
Contributor Author

Hi!

  1. I notice that the line width is thinner for the code preview, the position tracker, etc.

That is already fixed and I will submit this with updated PR. There was alpha blending set different. Now it pixel-to-pixel matches previous results.

  1. QtPlasmaC uses glTranslatef to calculate a "table view". I made the following changes that seemed to work (being 100% honest, this is outside of my paygrade, so I used Claude to get here). I have no idea if this is the right way to do it or not. Completely welcome your experties!

Thank you, I will include this for sure.

@alex-pres
alex-pres force-pushed the pr-gremlin-opengl-rewrite branch from cfb284d to f78ed6f Compare August 3, 2026 12:31
@alex-pres
alex-pres marked this pull request as ready for review August 3, 2026 12:33
@alex-pres

alex-pres commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

I've updated the code, I think that is now works as it should. I've added the following:

  • Added [optional] BatchProtocol between C++ Gcode parser and Python Canon. That way, instead of multiple Python method calls and type conversions, C++ code creates array of floats in memory and sometimes pass pointer of it to Python code. That speeds up big file parsing a lot!
  • Added compatibility with OpenGL version used by RPI4 (OpenGL ES 3.2) . In fact, almost nothing changed besides OpenGL shader program headers (it must contain version as first comment).
  • FIxed alpha opacity bug that made picture different compared to previous code. Currently it is almost 100% pixel-to-pixel equal.
  • Made another optimization [ for simple usual case of NGC engraving or 3d relieph file ] if array of moves does not have toolchages inside or coordinate system rotation, it is handled more efficiently.

Final result: 5M move file is loading much faster.

P.S. During development I found surprising results - regardless of all my optimizations, big ngc file load was still slow and memory eager. I found the reason - AXIS code is not well optimised, and while parsing it eats ~500 bytes per every source code line, it is all with dynamic memory allocation. So if want to directly compare the gremlin/glcanon speed, use qtaxis it seems to be better optimized around this.

If you, like me, do not have big .ngc files to try it out, I put some to Dropbox: https://www.dropbox.com/scl/fo/sp3njw8t2hlujo65ql4ma/AMGK-jRiwfUF3G1QJ-4aY8U?rlkey=ewxjww93bbobqd0sb5nxbk289&st=3lribdca&dl=0

@alex-pres

alex-pres commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

Some Benchmark results

Tested in AXIS with small patch that disables source code parsing [ by AXIS code ].
Used .ngc files from https://www.dropbox.com/scl/fo/sp3njw8t2hlujo65ql4ma/AMGK-jRiwfUF3G1QJ-4aY8U?rlkey=ewxjww93bbobqd0sb5nxbk289&st=3lribdca&dl=0

case moves open_file_guts (s) preview build (s) peak RSS (MB) 1st click (s) 2nd click (s) lines selected
master-1M 1,000,149 3.95 3.44 1533 1.239 0.375 none (8 attempts)
rewrite-1M 1,000,149 3.20 2.91 454 0.146 0.133 53518, 2083
master-5M 5,000,149 25.43 22.51 6643 12.396 1.921 none (6 attempts)
rewrite-5M 5,000,149 17.47 14.79 1079 0.370 0.318 8346, 8377

Load: 1.23x faster at 1M, 1.46x at 5M. Click-to-line: 8.5x faster at 1M, 33x at 5M — and only the rewrite actually selects anything. Master's first click is dominated by building the selection display lists (0.849 s at 1M, 10.35 s at 5M), then it discards the result: its 100-entry GL_SELECT hit buffer overflows on this geometry, so all 8 (1M) and 6 (5M) attempts highlighted nothing. Memory, 3.4x and 6.2x lower.

@alex-pres
alex-pres force-pushed the pr-gremlin-opengl-rewrite branch from be39bbe to 00bedfd Compare August 3, 2026 15:15
@snowgoer540

Copy link
Copy Markdown
Contributor

This is great work! I have a few comments...

The line weight is still not 1:1 from before the rewrite. I am not sure if that's intended, but it seems for feed, rapid, and manually controlled moves (in green, blue, and orange respectively in my preview), the line weight is different.

Before rewrite:
normal

After rewrite:
update

Also, I know many of these are not your doing, but here are many generic print statements all over these files. I feel like a lot of this should be moved to the logs for debugging, and do not need to be displayed in the terminal.

Specifically I noticed the addition of:
preview renderer: OpenGL 4.5 (Core Profile) Mesa 22.3.6 (renderer: llvmpipe (LLVM 15.0.6, 256 bits), max line width 255.0) which ends up cluttering the terminal.

For at least glcanon.py, I think we should make effort to move some of this to logging. I think the exception would be when a dependency is missing, etc. Those are helpful to have in the terminal (and really should also be in a log file somewhere).

Otherwise, let me know when you are happy with this and I am happy to commit it for you!

-Greg

@alex-pres

Copy link
Copy Markdown
Contributor Author

Greg, thanks for checking this!

The line weight is still not 1:1 from before the rewrite. I am not sure if that's intended, but it seems for feed, rapid, and manually controlled moves (in green, blue, and orange respectively in my preview), the line weight is different.

I will additionally check it!

Also, I know many of these are not your doing, but here are many generic print statements all over these files. I feel like a lot of this should be moved to the logs for debugging, and do not need to be displayed in the terminal.

I reworked logging, hope that is better now.

Otherwise, let me know when you are happy with this and I am happy to commit it for you!

Need to resolve line width and would be good to get at least one test on RPi and I think that is ready to go.

-Greg

@NTULINUX

NTULINUX commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

I absolutely love this, can't wait to see this merged!

FlexGUI looks a bit wonky with the GL3 port. Vanilla LinuxCNC:

Screenshot_20260805_143456

GL3:

Screenshot_20260805_143524

@snowgoer540

Copy link
Copy Markdown
Contributor

I will additionally check it!

Happy to help!

I thought you had a command you wanted me to run and post the output of, but I do not see it now?

@snowgoer540

Copy link
Copy Markdown
Contributor

In your rewrite, do you think there is case to increase #define MAX_POINTS (100000) in emcmodule.cc?

I've bumped this up 3 years ago (8264698), previous to my increase, it was set at 10000 since 2009. Honestly these days with memory sizes/graphics cards being what they are, I wonder if this is still applicable to limit it at all. Have you any thoughts on the matter?

@NTULINUX

NTULINUX commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

IMO LinuxCNC should still function on 32-bit processors with 4GB of RAM and plenty of room to spare. Aside from that, I have no opinion on MAX_POINTS.

@alex-pres

alex-pres commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

I will additionally check it!

Happy to help!

I thought you had a command you wanted me to run and post the output of, but I do not see it now?

It'd be helpful if you send output of "glxinfo -B" , "cat /etc/debian_version" and also the .ngc file you used for testing. So I can repeat it exactly.

@alex-pres

alex-pres commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

In your rewrite, do you think there is case to increase #define MAX_POINTS (100000) in emcmodule.cc?

I've bumped this up 3 years ago (8264698), previous to my increase, it was set at 10000 since 2009. Honestly these days with memory sizes/graphics cards being what they are, I wonder if this is still applicable to limit it at all. Have you any thoughts on the matter?

It is much better optimized now, now it incrementally converts vector[9] to xyz only for new values arriving and following work is done inside OpenGL on array with that raw xyz data that builds backplot line strip.

however that downside is in existing emcmodule.cc:3128 — Logger_get_points does PyBytes_FromStringAndSize(s->p, npts * 32): a copy of the entire buffer, under the sampler mutex, on every frame, even though glcanon_scene.py:1593 then throws away everything before first_point and typically uses one point. At 100 k that's 3.2 MB/frame (~190 MB/s at 60 fps) plus lock contention with the sampler thread.

So we can increase this buffer probably 10x or even 100x but only after implementing something like I did for program moves [ gcodemodule.cc:class MoveBatch ] - CC code and Python code will share pointer to static buffer of floats - native to CC, and easy to access in Python via numpy. it can be made optional [ CC code will be checking calling Python side if it understands new protocol ].

I could implement it too [ or someone else if have time ] but may be in another PR - that one is really too big already.

@BsAtHome

BsAtHome commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

IMO LinuxCNC should still function on 32-bit processors with 4GB of RAM and plenty of room to spare. Aside from that, I have no opinion on MAX_POINTS.

The last 32-bit PC processors were made decades ago. Distros have been purging 32-bit processor support for years now. There is no point in supporting it as we can't even compile it on newer distros.

The 4GB point should be no problem. It can run on a RPi with 1GB RAM. The real problem will be the graphics memory. That limit is usually the graphics card. However, a system with 4GB graphics shared RAM may be very adequate for reasonably large display lists. If I may make a guess... In 1GB graphics, if each line segment takes 256 bytes, then you can have 4 million lines. I don't think the problem is memory, but probably the bandwidth needed if the processor gets involved.

But, this still needs to be tested on both RPi4 and RPi5. They do have limits and we should get an idea where that limit is.

@alex-pres

alex-pres commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

In 1GB graphics, if each line segment takes 256 bytes, then you can have 4 million lines. I don't think the problem is memory, but probably the bandwidth needed if the processor gets involved.

To be exact: for backplot, VBO [ GPU ] memory usage is as follows:

  • 16 or 32bytes per point [ 32 if GPU max line width is limited to 1.0, 16 if line width is supported by driver ]
  • 100000 line segments will use 100001 points.
    With current limit it is 3MB.
    This array is mirrored from CPU to GPU so lets count twice.

on the CC code side, it is ~ n points * sizeof(double) * 9 [xyzabcuvw]

I think max capacity here will be limited not by memory but by CPU usage because rendering still need to be calculated and that is good if GPU doing it without taking CPU resources but no warranty here.

Better to check it on real hardware...

@snowgoer540

snowgoer540 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

I could implement it too [ or someone else if have time ] but may be in another PR - that one is really too big already.

Yes, I completely agree, I didn't intend for it to be part of this PR, just wanted to bring it up since it's definitely related. I was doing some testing on some large preview files, which reminded me of the backplot "going away", and I wanted to bring it up before it left my brain. Also, I can confirm that the new preview is definitely much faster than the old one!

Also, I do intend to dig out a RPi4 and give this a check. It aligns with another project I have cooking as well, so it's double motivation to move it along.

Thank you again for taking this on.

Edit: I will get you the output of "glxinfo -B" , "cat /etc/debian_version", and will get you the .ngc file I showed above after work today.

@NTULINUX

NTULINUX commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

What about this breaking FlexGUI's plotter? The screenshots I posted above?

@c-morley

c-morley commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Flexgui will need to fix the code on their end that causes the trouble.

@NTULINUX

NTULINUX commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Flexgui will need to fix the code on their end that causes the trouble.

OK, just wondering. Thanks!

@alex-pres

Copy link
Copy Markdown
Contributor Author

Flexgui will need to fix the code on their end that causes the trouble.

Exactly. That is because they are calling OpenGL directly with old API.

However, to make possible for 3rd party authors to write code that works with both 2.9 and 2.10 it is possible to add new variable somewhere to glcanon like self._GLCANON_VERSION = 2 . Please advise if that is good idea.

@snowgoer540

Copy link
Copy Markdown
Contributor

glxinfo -B

display: :0  screen: 0
direct rendering: Yes
Extended renderer info (GLX_MESA_query_renderer):
    Vendor: Mesa/X.org (0xffffffff)
    Device: llvmpipe (LLVM 15.0.6, 256 bits) (0xffffffff)
    Version: 22.3.6
    Accelerated: no
    Video memory: 15991MB
    Unified memory: yes
    Preferred profile: core (0x1)
    Max core profile version: 4.5
    Max compat profile version: 4.5
    Max GLES1 profile version: 1.1
    Max GLES[23] profile version: 3.2
OpenGL vendor string: Mesa/X.org
OpenGL renderer string: llvmpipe (LLVM 15.0.6, 256 bits)
OpenGL core profile version string: 4.5 (Core Profile) Mesa 22.3.6
OpenGL core profile shading language version string: 4.50
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile

OpenGL version string: 4.5 (Compatibility Profile) Mesa 22.3.6
OpenGL shading language version string: 4.50
OpenGL context flags: (none)
OpenGL profile mask: compatibility profile

OpenGL ES profile version string: OpenGL ES 3.2 Mesa 22.3.6
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.20

cat /etc/debian_version

12.15

I do have a BM running Debian 13 I could try it on as well.

However, to make possible for 3rd party authors to write code that works with both 2.9 and 2.10 it is possible to add new variable somewhere to glcanon like self._GLCANON_VERSION = 2 . Please advise if that is good idea

I would vote no on this. I think we've clung onto the old ways for long enough and if we are moving forward, it's time to move forward.

@snowgoer540

Copy link
Copy Markdown
Contributor

For the record, this is the same on MX Linux 25 (Based on Debian 13):

Screenshot_2026-08-06_18-53-34

Results of stanzas below:

name of display: :0.0
display: :0 screen: 0
direct rendering: Yes
Memory info (GL_NVX_gpu_memory_info):
Dedicated video memory: 8192 MB
Total available memory: 8192 MB
Currently available dedicated video memory: 7422 MB
OpenGL vendor string: NVIDIA Corporation
OpenGL renderer string: NVIDIA GeForce RTX 3060 Ti/PCIe/SSE2
OpenGL core profile version string: 4.6.0 NVIDIA 580.173.02
OpenGL core profile shading language version string: 4.60 NVIDIA
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile

OpenGL version string: 4.6.0 NVIDIA 580.173.02
OpenGL shading language version string: 4.60 NVIDIA
OpenGL context flags: (none)
OpenGL profile mask: (none)

OpenGL ES profile version string: OpenGL ES 3.2 NVIDIA 580.173.02
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.20

13.6

@alex-pres

Copy link
Copy Markdown
Contributor Author

I found reason for that problem - QT OpenGL set different flags for GL Context during creation, so it is one line fix to get backplot back 3px width.

However, I have a question I cannot make decision myself. Docs say v3d on RPi really set limit to line width to 1. So to draw 3px wide line you have to calculate and draw a square [ and pass 4 instead of 2 vertex to GPU for each line]. Of course it comes at cost when rendered.

My question is - is it really imporant to keep 3px line width for backplot on RPi and pay performance costs for it? I know it is not most powerful machine to run LinuxCNC on, so may be we can simply set more bright colors for backplot instead ?

For reference - program lines are 1px wide, and backplot lines are 3px.

@alex-pres

Copy link
Copy Markdown
Contributor Author

I pushed fixes now, only Q for now is live testing on RPi with their native OpenGL driver.

With software rendering [libvmpipe] I'd not expect results other than anywhere else.

@BsAtHome

BsAtHome commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

A remote X-session over ssh into a RPi5 runs axis without a problem (using bookworm).
Unfortunately, can't test with a local screen/session because I have no spare monitor in reach at the moment.

@snowgoer540

Copy link
Copy Markdown
Contributor

My question is - is it really imporant to keep 3px line width for backplot on RPi and pay performance costs for it? I know it is not most powerful machine to run LinuxCNC on, so may be we can simply set more bright colors for backplot instead ?

For reference - program lines are 1px wide, and backplot lines are 3px.

I would say no.

I pulled out a pi4 and loaded the linuxcnc iso (Trixie) and built master for it. Overall I would say the Pi4 experience is a bit lack-luster (for all screens). So anything done to gain here is probably a good thing. Perhaps the Pi5 is a different experience.

I also applied your patch, everything seemed to work for the screens I tested (QtPlasmaC and Axis). I will note that the backplot was 3px wide in both cases. Perhaps to be expected.

If we think this is tested enough between what I did this weekend for the Pi4, and what Bertho did for the Pi5, I will commit this as soon as I get your concurrence.

@BsAtHome

BsAtHome commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

If we think this is tested enough between what I did this weekend for the Pi4, and what Bertho did for the Pi5, I will commit this as soon as I get your concurrence.

It still needs to be tested on a RPi5 with a local session and monitor attached. As I mentioned, I do not have a spare monitor available (that is, not one that takes HDMI). I will try to see if I can borrow something, but it may still take a while.

@snowgoer540

Copy link
Copy Markdown
Contributor

It still needs to be tested on a RPi5 with a local session and monitor attached. As I mentioned, I do not have a spare monitor available (that is, not one that takes HDMI). I will try to see if I can borrow something, but it may still take a while.

I apologize, I took the monitor testing as “nice to have”. We can wait. Although I might argue it as a “nice to have” when compared to the value of getting this into the wild for testing on the master branch. I suspect that the number of RPi5’s running Master is probably minimal/non-existent.

@BsAtHome

Copy link
Copy Markdown
Contributor

The RPi5 works with local monitor (1920x1080). It is quite slow when you load the 1M file and have the preview on. It runs, but cannot keep up with the frame updates. There may be optimizations possible which are not being used that are better for the platform. That could be investigated separately. RT runs normal, but the screen lags/skips lines in the updates, but that is still fine.

Without the preview it is all working as expected and does keep up. The touched path indication is of limited size and is fine too (don't know how many; gets pruned in batches). The CPU usage for the axis process is apparently proportional with the number of lines handled and is about 100% (split over two cores) at just over tracing two and a half levels of the Hilbert curve and axis is holding just over 100% for the rest. The system is still interactive without problems and the screen pans/zooms without a hitch.
Running not full-screen does reduce the load by ~15%, The X server goes from 12% to 4% when not in full-screen, which indicates there is some dependency there too.

There may be some code or algorithmic tweaks to make this faster so the CPU has less to do. This should be investigated by someone at home in the the RPi CPU/GPU world (could also benefit other architectures). FWIW, Python may not scale well for all architectures.

Otherwise, RPi5 is a go.

@alex-pres

alex-pres commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

The RPi5 works with local monitor (1920x1080). It is quite slow when you load the 1M file and have the preview on. It runs, but cannot keep up with the frame updates. There may be optimizations possible which are not being used that are better for the platform. That could be investigated separately. RT runs normal, but the screen lags/skips lines in the updates, but that is still fine.

Thank you very much for detailed test! A few questions if you allow:
1 - how does it compare to "master"? In load and in frame updates?

2 - most important is what OpenGL driver used and if GPU is used at all. Can you please check
grep -n "preview renderer" ~/linuxcnc_debug.txt
there must be line like that

preview renderer: OpenGL ES 3.1 Mesa 23.2.1-1 (renderer: llvmpipe (LLVM 15.0.6, 256 bits), max line width 1.0)

and output of glxinfo -B may be also helpful.

@BsAtHome

Copy link
Copy Markdown
Contributor

No data/info in linuxcnc_debug.txt.

Other info:
rpi5-glxinfo.txt
rpi5-lsb_release.txt
rpi5-uname.txt

@andypugh

Copy link
Copy Markdown
Collaborator

Does this duplicate / replace #3547 ?

@alex-pres

Copy link
Copy Markdown
Contributor Author

No data/info in linuxcnc_debug.txt.

Other info: rpi5-glxinfo.txt rpi5-lsb_release.txt rpi5-uname.txt

glxinfo -B shows software rendering enabled (libvmpipe). Probably V3D GPU drivers are not installed or disabled.

I just got another report from customer using RPI 5B.
He got V3D 7.1.10.2 installed.
133MB ngc file loading time is the same compared to master (58 -> 56 seconds), but memory usage dropped from 5.7GB -> 1.17 GB with new code.

From video he sent me I cannot see any performance problems. It looks very responsive.

@alex-pres

Copy link
Copy Markdown
Contributor Author

Does this duplicate / replace #3547 ?

I did not see 3547 before, but that is definitely a replacement.

@BsAtHome

Copy link
Copy Markdown
Contributor

glxinfo -B shows software rendering enabled (libvmpipe). Probably V3D GPU drivers are not installed or disabled.

/me embarrassed. Goes down the room facing down a corner to contemplate the existence of the universe...

Interesting, my image doesn't even have /boot/firmware yet. The v3d driver was masked under the [pi4] section, so yes, it wont load. I think this is a (very) old LCNC image that I adapted a long time ago for testing purposes. I guess I need to build a clean (trixie) image from scratch to fix all installation problems.

And, yes, it works a lot better with the 3D driver actually enabled... Reading the 1M file works without a problem after some time and it is interactively very responsive indeed. Now the load running axis is just 10% and follows cleanly. Much better.

@alex-pres

Copy link
Copy Markdown
Contributor Author

Now I think it is ready to go and merge [ if accepted ] .

May be it is better to merge all commits into one to keep linuxcnc git history clean? I can do it from my side - just tell me a word.

@BsAtHome

Copy link
Copy Markdown
Contributor

Now I think it is ready to go and merge [ if accepted ] .

I see no further objections.

May be it is better to merge all commits into one to keep linuxcnc git history clean? I can do it from my side - just tell me a word.

Yes, that would be very nice if you did that.

Replaces the fixed-function preview shared by AXIS, the GTK screens and
QtVCP with a shader/VBO renderer: a baked trajectory buffer, an offscreen
ID-buffer pass for picking, and a glyph atlas for overlay text. The GL
matrix stack, display lists, immediate mode and GL_SELECT are gone. Added
optional optimised MoveBatch protocol to g-code parser. Rendering code
decomposed to a Scene object containing Parts (each can be replaced or
disabled).
@alex-pres
alex-pres force-pushed the pr-gremlin-opengl-rewrite branch from b0a473c to 6aa48da Compare August 12, 2026 15:53
@alex-pres

Copy link
Copy Markdown
Contributor Author

May be it is better to merge all commits into one to keep linuxcnc git history clean? I can do it from my side - just tell me a word.

Yes, that would be very nice if you did that.

Done

@snowgoer540
snowgoer540 merged commit 0a4be84 into LinuxCNC:master Aug 12, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants