When you want a beautiful GUI, but no gpu

Typically, working utilities do not require a sane UI, with buttons, lists, windows, mouse support and other small things, most of the working Wishlist can be packaged in scripts and sometimes run them with the --help parameter, and this will even be more correct from the point of view of configuration and scaling. Everything gets worse when not only the development team, but also third-party people begin to use the tools. And they are not always ready to delve into the harmonious thoughts laid down in the lines of code. And then you have to make a fuss of the UI, and the developers usually get it simple, square, functional and completely boring. Some time ago, I was working on a small ventilation / heating / camera control system and also “what the uncle in a yellow helmet will come up with” for an underground car park.











(Here was a picture from the UI system, but the developer asked to remove it. If you do not want to read about walks on the rake field, then links to the github at the end of the article)



The system was built on the Chinese non-name SoC, for which the manufacturer decided to port the SDL framework of the first version. The internal tools and scripts were modified to such an extent that they turned into a weighty and “beautiful” layout with tabs, lists, popups, shadows, gradient, transparency and other goodies.



To realize all the beauties, nanogui was chosen, simple and unpretentious, and at the same time “powerful” all that was needed. It was exactly on paper, but the ravines forgot about OpenGL. Almost completely implemented UI control systems began to run on hardware, and there a black screen, all OpenGL3 initializations go without errors, buffers are set, and shaders are compiled, but no ... black screen, at what angle do not look.



At first they sinned on my crooked hands, then on the hands of the Antokha developer responsible for the driver and hardware, then they launched a test example of a triangle rendering from the SoC SDK, and again the black screen, documentation and examples are usually read last.



My colleague and I thought something wrong and went first to the Chinese forum, and not having already found clear answers for the developer, the answer was disappointing, there was no opengl implementation, and most likely it would not, because the line was being discontinued.

- But what about the SDL framework? - we asked

- We draw pixel by pixel into the video memory. - Our Chinese friends answered us.



That day, I saw the sad eyes of a programmer who calculates how much LoC he will send to / dev / null. But throwing a ready-made solution was very disappointing, (on the Internet there is everything) it turns out you can live without OpenGL in nanogui on a software render.



Only life turns out very slowly, on a large PC a couple of seconds per frame, on the Chinese miracle of engineering, it is already about 20-25 seconds to draw. Then they decided not to render the entire UI at once, but only the necessary (changed) parts of the widgets, but even in this mode, with all the hacks and optimizations, it took more than 10 seconds for one frame to become unviable ...



Having smoked some SDK examples, we found out that copying finished textures to video memory is “instant” (compared to 10 seconds of course), and it takes about 1ms to 512x512 without transparency and 2ms for the same with transparency, if you copy several of these textures one after another, then time grows nonlinearly catastrophically, this turned out to be due to the limited amount of video memory buffer, overflow of which led to flushing the buffer and rendering what was on the screen (not mine, it was already there), i.e. for a not quite dead interface, we can copy no more than 50-100 textures per frame and not immediately, but only after waiting for the video driver to collect data from the buffer.



The next iteration was the rendering of the widget into its own texture in the stream, and at the time the texture was created, the widget was drawn approximately similar to the final result, only in a square way, to draw all sorts of lines, shapes could be immediately in the video memory for free.



Almost defeating the miracle of Chinese thought “without” a GPU, you still can’t call the 20 FPS a decent result, and almost handing over the project, I asked the customer for permission to pick up some of the experience in open source. The first SDL is not very fashionable now, so it was decided to use the nanogui render in software mode on SDL2 and put it on a github. Maybe someone will need :)



Having read the article to the end,% habruiser% has the right to ask why it was necessary to block this bunch of code

for rounded corners and shadows? Firstly, it’s beautiful (s), secondly, “that uncle in a yellow helmet” already paid for the development of the system and the rounded corners there, unfortunately (or fortunately) ended up in the task list, it remains to make them with a gradient and add some shadows.



This was the original summer of 2017 in sunny Sochi.



This is how OpenGL renders











This is how software renders on a PC











References :



Original wjakob / nanogui

NanoVG software render

NanoGUI + SDL + software render



PS Do not believe the Chinese developers talking about the presence of OpenGL in the system, check the performance of all components, to know how :)



All Articles