[SailfishDevel] Serious request: please let us use C++!

Thomas Perl th.perl at gmail.com
Thu Dec 5 08:56:20 UTC 2013


Hi,

On 04 Dec 2013, at 23:21, Wim de Vries <wsvries at xs4all.nl> wrote:
> I mean this in positive sense: please don not enforce QML at the cost of C++ on the developers community.
> First, C(++) is THE language for openGL.

Actually the OpenGL API is specified in C. Of course, as you can call C API functions from C++, you can also write C++ applications using the OpenGL API. I’d argue that “THE” language for OpenGL is GLSL, i.e. the C-lookalike language that you use to write shaders that get compiled by the drivers and uploaded to the GPU to be run there. Of course, you need another language to actually call OpenGL API functions. But C++ is not in any way “more” the language than e.g. Java[1] or JavaScript[2] is.

[1] http://developer.android.com/reference/android/opengl/GLES20.html
[2] http://www.khronos.org/webgl/

> We want to program shaders and heavy calculations (C++).

No problem, you can even write and use shaders directly from QML:

http://qt-project.org/doc/qt-5.0/qtquick/qml-qtquick2-shadereffect.html

Of course, this is mostly for doing fragment shaders on top of some QML 2D content, but my point is: Shaders have as such nothing to do with C++.

> Qt used to be well suited for this, offering a Q(GL)Widget set that enabled a nice 'stage' for OpenGL and also a nice GUI for the rest of app.

A QWindow is basically the same as a QGLWidget without the actual overhead of the QWidgets library. In fact, it even gives you more control of the rendering than the QGLWidget does. Again, here’s the link to an example: http://qt-project.org/doc/qt-5.0/qtgui/openglwindow.html

We do even have an example with RPM packaging and everything ready to go:
https://github.com/mer-qa/qt5-opengles2-test

The only confusing thing might be that you don’t have convenience callbacks like initializeGL(), resizeGL() and paintGL(), however, if you really depend on those, these are quickly and easily to write on top of the QWindow API.

> Now we have go through Qpainters, QQuickitems (oh no, that's black listed also).
> Our QWidgets are useless now.

The reason for this is that the drawing model used by QWidgets and QPainter come from a time when rendering was done using the CPU, and they are optimized in this way. On mobile devices, both CPU and GPU are limited (compared to Desktop machines), so for rendering, it’s important to use the GPU as much as possible for rendering. Combined with Z-buffering and sorting, this might allow the engine (such as the Qt Scene Graph renderer) to avoid overdraw and cull as much as possible - the most efficient code is everything that you actually don’t run (or something like that..).

> We are enforced to do this in declarative QML.

Nobody forces you to. You can also do pure OpenGL rendering on a QWindow and skip QML completely. Or combine QML with custom OpenGL rendering.

> So, how do I simply calculate 1+1 in QML?

It’s JavaScript, so the expression “1+1” (without the quotes) will calculate it in QML.

> Large floating point arrays for my vertices?

Put them into VBOs on the C++ side.

> Malloc for images?

Ideally allocate a texture on the GPU and render to it using OpenGL FBOs instead of allocating main memory, rendering in software and then uploading to the GPU (it will end up in GPU memory at some point, anyway, and even if it’s just for final composition in Wayland).

> Reading buffers from serial devices?

Again, just use normal C/C++ APIs for that and expose it to the QML world (if you need to have that data available) via context properties[1].

[1] http://qt-project.org/doc/qt-5.0/qtqml/qtqml-cppintegration-contextproperties.html

> So please, make the Sailfish GUI accessible via C++ (like QWidgets).
> As it is now, I myself, will not be able to submit my (open source) aircraft navigation app for Sailfish.
> I am sure that a lot of Meego/maemo/Symbian developers will have the same problem.
> Google has been arrogant with their JAVA enforcement, now they are repairing it by enabling C++ via the NDK.
> Please do not make the same mistake.

You are free to use C++-only OpenGL rendering, and it will be fine, you just will not be able to use the Sailfish Silica UI components (for native look’n’feel). You are free to use QML-only UIs and make full use of the Sailfish Silica UI components. You are also free to combine both the QML Sailfish Silica UI components and native OpenGL rendering to do custom drawing.

And if you really, really want to, you can render all your stuff with any library you want in software (=on the CPU) to a RGB/RGBA buffer in memory and provide that to QML in the form of an image provider. Don’t expect high frame rates this way, but it /does/ work and provides full access to every pixel that gets drawn with the advantage that you can still use all the goodies of QML (yes, it takes some time to get used to, but once you got it, it’s great).

Here’s an example where we render the mandelbrot set (!) on the CPU (!!) in Python (!!!) and still get quite acceptable performance (nothing 60 FPS-ish, obviously) and integrate that with QML using a simple image provider (with some magic done behind the doors by PyOtherSide):

https://github.com/thp/pyotherside/tree/master/examples/mandelbrot

Are we missing code examples of how to integrate C++-based OpenGL rendering like QGLWidget (initializeGL, resizeGL and paintGL) with Sailfish Silica QML UIs? Would it help you if such examples were available (a simple hello world with Silica buttons and a rectangular area where things are rendered with OpenGL)?


HTH :)
Thomas


More information about the Devel mailing list