More qt5 port notes
Arjen Hiemstra
ahiemstra at heimr.nl
Tue Jun 9 00:04:46 BST 2015
On Monday 08 June 2015 17:43:24 Boudewijn Rempt wrote:
> I also talked about the opengl canvas problems with kwin maintainer Martin
> Graesslin. He was pretty clear that Qt's undocumented qglfunctions thing
> is rather badly designed, and he said to use libepoxy instead of either
> that or our glew + qlibrary thing, but that doesn't work on osx, and is
> another dependency.
>
> I guess we could try to drop qlibrary and use dlopen directly, or figure
> out how to fix our code to use QFunctionPointer. I have no idea about that
> atm, I need more leisure than I have to look into it.
>
While Martin is for the most part right in it being badly designed, I
personally do think it is a better solution than using a dependency you cannot
use on OSX or trying to do something manually - unless there is no other
choice. We actually use QOpenGLFunctions at work and with some side notes and
caveats it can be used. To be fair, work code is python[1] so this might be a
little different from C++ as the python code has some additional contraints.
To get a QOpenGLFunctions object you can use
QOpenGLContext::versionFunctions(). This will return a functions object based
on the version of the current context. Since PyQt is a bit limited, in our
case this is a QOpenGLFunctions_GL_2_0 or similar object, at least the object
corresponding to OpenGL 2.0 . This also introduces another limitation: When
using this object, you will be able to access OpenGL 2.0 functions and *only*
OpenGL 2.0 functions. No extensions, no functions from higher versions,
nothing. So you will need to be fairly explicit with your function usage,
since for example glFenceSync is only available in the OpenGL 3.2 function
objects[2], though I cannot recall whether or not it is even available as
extension.
On the other hand, it does introduce a more reliable form of feature
detection: If you cannot get a proper version object for a certain version,
you can fall back to a rendering path that does not rely on features in that
version. QOpenGLFunctions::versionFunctions() will return a null pointer if it
cannot provide the right version of the functions, so you can fairly easily
check that and fall back if it fails. One thing it fails at though is falling
back to extensions if a certain mainline item is not available, which also
happens to be one of the reasons many people would discourage using
QOpenGLFunctions iirc. For example the buffer functions like glGenBuffers() will
not properly fallback to the ARB version glGenBuffersARB() but instead fail to
create a proper functions object.
All that said, for us it was a fairly easy choice as we do not require more
than OpenGL 2.0 with Framebuffers and we also wanted to keep support for the
ANGLE fallback on Windows. In the case of Krita, you probably need to add some
more proper version detection and fallback paths, but I think for most things
it covers the use cases.
- Arjen
[1]: See
https://github.com/Ultimaker/Uranium/blob/master/UM/Qt/QtGL2Renderer.py#L317
for the code that uses it.
[2]: See http://doc.qt.io/qt-5/qopenglfunctions-3-1.html vs.
http://doc.qt.io/qt-5/qopenglfunctions-3-2-compatibility.html for example.
More information about the calligra-devel
mailing list