Raspberry OS based on Debian bullseye was recently published. The compiler provided with this new version was updated to 10.2.1. As usual, I need to cross build many large projects for the platform, and I had problems in the past with cross toolchains not precisely matching the versions in the target sysroot. I therefore typically prefer to build my own toolchains based on the precise versions of the packages provided with the OS. These are the toolchains I’m using for the past Raspberry Pi systems:
For Bullseye, these are the new toolchains I’m currently using:
Cross toolchain GCC 10.2.1 for Linux hosts for Bullseye: here.
Cross toolchain GCC 10.2.1 for Mac OS hosts for Bullseye: here.
As usual, place the toolchain in /opt/rpi, and the sysroot in /opt/rpi/sysroot. I tested these toolchains to build Qt 6.2.1 and everything seems to be fine so far.
Getting hardware acceleration into Qt eglfs is tricky. Doing so on a Raspberry Pi is, unfortunately, still tricky after many years. Qt claimed to have reimplemented the Qt Multimedia module entirely, and one of their target was getting hardware acceleration where possibile. So, I thought I could start with a quick look.
Qt 5
Since Raspberry Pi was born, I had to solve the problem of hardware accelerated video in Qt. At the beginning, I wrote POT (PiOmxTextures) to solve this problem: https://github.com/carlonluca/pot. It used OpenMAX to stream decoded video into an OpenGL texture, which was then showed through a custom backend of Qt Multimedia in Qt 5. This approach worked fine, but won’t work on Pi 4/Qt 6. On the other hand, there is another component in the same repo, that includes a custom Qt Quick item to render video through omxplayer. This is the most performant approach, but has its limitations.
Qt Multimedia
I quickly tested Qt Multimedia in Qt 6 on the rpi. My build from this article should support gstreamer. All I got was a a warning on the console. I didn’t investigate further. Maybe I’ll spend more time on this in the future.
POTVL
As the classical POT is no more usable on Raspberry Pi 4, I started to have a look at POTVL, which is very simple to port to Qt 6. With a small patch, it is possible to build it. You’ll find updates on the repo.
Demo
The video is a 1080p video. As you can see, the framerate is acceptable up to a certain weight of the graphics. It seems that Qt 6 OpenGL backend still is a bit less performant than Qt 5 in this specific demo, as you can see from this test from a previous article:
so the result may even improve in the future. The benchmark app can be found here: https://github.com/carlonluca/Fall. Unfortunately POTVL is still not future proof, but it is the simplest and most efficient element to port to Qt 6. I may try something better in the near future. Have fun! Bye 😉
In the classical Finite Element Method (FEM) the domain of the problem is approximated by defining a mesh and basis functions over its elements. More elements for the mesh means more basis functions and therefore larger space where approximated solutions can be found. The procedure of increasing the number of elements in the mesh is known as h-refinement. In Isogeometric Analysis (IGA), no mesh is required as the basis functions used to define the domain are the same basis functions used to define the approximate solution. Nevertheless, in IGA, the solution is still a combination of basis functions, so increasing the number of basis functions is still needed to implement some kind of h-refinement. A good way to do this is through knot insertion into the NURBS. This post also presents demo written in Octave and TypeScript.
You can find the full source code for the algorithms and all the examples in this GitHub repo.
Problem of Knot Insertion
Given the general form of a NURBS curve as described here:
knot insertion is the problem of adding the knot $\bar{\xi}\in\left[\xi_k,\xi_{k+1}\right)$ in the knot vector $\Xi$, so that the following still stands:
This is the technique used in all the implementations in the repo.
Octave Implementation
The Octave implementation includes the computeKnotInsertion script that takes a NURBS as input, together with the knot value to add and returns a new knot vector and control points. This is an example of insertion into a circle:
The computeSurfKnotInsertion script computes knot insertion for NURBS surfaces instead. With the script, knots can be added to both dimensions. An example is shown below:
TypeScript Implementation
The TypeScript implementation includes a method named insertKnot in the NurbsCurve class. That method allows to insert multiple knots into the vector, returning a new NurbsCurve, identical to the first, but with a different knot vector and different control points.
The NurbsSurf class includes the methods insertKnotXi and insertKnotEta to insert knots in the two dimensions of the parametric space and returns the new object NurbsSurf. This is the result of the algorithm applied to a plate:
and this is the result on a toroid (in this case knots were not inserted in the entire vector uniformly, but only in a section):
As expected, after each insertion, the NURBS is unaltered. This can also be seen by running the unit tests provided in the repo. For example, one unit test includes this code:
function testNurbs(n1: NurbsSurf, n2: NurbsSurf) {
for (let xi = 0; xi <= 1; xi += 0.01)
for (let eta = 0; eta <= 1; eta += 0.01)
assert(approxEqualPoints(n1.evaluate(xi, eta), n2.evaluate(xi, eta)))
}
[...]
measure("surf_knot_insertion_xi", () => {
let n1 = new NurbsPlateHole()
let n2 = new NurbsPlateHole()
for (let i = 0.1; i <= 1; i += 0.9) {
if (n2.Xi[i] != i) {
let k = BsplineCurve.findSpan(n2.Xi, i, n2.p, n2.controlPoints.length - 1)
testNurbs(n1, n2.insertKnotsXi(i, k, 0, 1))
}
}
})
It has been some time since Qt 6 was released. Now that Qt 6.2 is almost out, I guess it is time to have a look at it.
Building Qt 6
Qt 6 moved from qmake to cmake. This makes a difference when trying to build it and cross-build it. Instructions on how to build are already available online from many sources, so I won’t repeat the theory here. I just want to note a few key points.
Configuration
I configured this build in the simplest form. To start, I want to use eglfs on OpenGL ES.
Toolchain
Building Qt requires a toolchain for building on the host and a toolchain to build for the target (the Raspberry Pi in this case). The toolchain from the host is typically provided by your distro (I used Manjaro in this case), while the toolchain to cross-build for the Raspberry Pi is officially provided here. In the past years I had a lot of weird problems building with those toolchains, so I started to create my own. Never had any problem anymore. Here you can find the toolchains:
Please note that those toolchains are not always able to target every arch. The one for Buster is the one I used in my build, and the target arch is armv8-a.
Dependencies
Dependencies are already listed elsewhere. I would only like to note one thing here: I had problems linking because of a missing symbol: qt_resourceFeatureZstd. According to the sources, it seems that resources are compiled by the rcc tool. My guess is that the host tools use zstd by default to compress when available, but this is a problem when zstd is available on the host and not available on the target. Therefore, I suspect you have to decide if you want zstd support or not before building Qt 6 for the host, and be coherent with the build for the target. I decided to add zstd.
Build Errors
I had a few build errors building Qt 6.2 beta3. Nothing particularly relevant, but I had to apply a few changes. I did not keep track of those changes, they were all trivial.
Build Qt Test App
Once the Qt builds are ready, it is time to run. For the moment, I only want to do a quick test of QML. In my build, I forgot to set eglfs as the default platform, but it can be set it in the environment. I wrote a simple app to test Qt Quick here. The animations are very simple, but I wrote it like this to see how well many items are handled and how well the uniform movement on the y axis is rendered.
NOTE: Unlike Qt5, Qt6 includes host tools and tools built for the target. This means you can build the test app on the target directly or cross-build it from your host. For the package below anyway, you'd need to have a system compatible with those binaries.
First App
This video shows a comparison of this Qt 6 build against Qt 5. It also shows the same benchmark app on Intel UHD and nVidia.
Download
If you want to test the build of Qt 6 on your rpi, you can download it from here:
Download Qt 6.2.0-rc1 for Raspberry OS Buster armv8-a
The package does not include the toolchain, that you can download from the other links, but includes the host build. I don’t think it will be of help, as it is built for my Manjaro context, but I placed it there anyway.
The positions of the directories are relevant:
/opt/rpi/rpi-8.6.3: toolchain;
/opt/Qt-x64-6.2.0-beta3: host build;
/usr/local/Qt-rasp-6.2.0-beta3: position in the target;
I recently started to add many useful open source services to my Raspberry Pi, like Jenkins, GitLab etc… I wrote some articles about running some services on a arm64 device here:
After these, I also wanted to try WordPress: it is already available as a comfortable docker image for arm64. How could I put it to work? I thought I could reimplement the Bugfree Blog in WordPress!
Unfortunately it was a bit harder than I thought: first of all this bug was making the system completely unstable. I fortunately found a workaround soon by bisecting the kernel, and now there is also an official fix. The fix is not published yet on Ubuntu, but with this docker image I can apply the patches and cross-build the Ubuntu kernel quickly.
A second problem was related to disconnections of USB devices when USB hubs are connected. This is still unresolved.
A third problem is related to the SD card: I never had problems with the SD card, but I recently broke a few. The Raspberry Pi 4 is hotter that I thought, even when load is minimum. The SD cards are guaranteed to work properly up to 85°C, and the Raspberry Pi is set to that max temp, but I tried to reduce it by using a proper case and adding a little (and very professional) Lego castle to encourage heat dissipation. Let’s hope SD cards can live longer.
New URL
The new URL for the experimental Bugfree Blog on Raspberry Pi 64 bit is:
I really like this excellent piece of software. I found some docker images for it for the arm64 architecture, but they seemed not to be very up to date, so I created my own. Here you can find my version of a dockerized MLDonkey service, built for many archs: armv7, arm64, x86 and x64. The arm versions are perfect for Raspberry Pi variants.
The latest version of the image is taken from this commit, which is the latest at the time of writing. It also includes a couple of patches that I sent to add a dark theme.
The image is built on top of debian:buster. For the moment, it is difficult to use something newer because of this known issue.